添加功能
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
'data/hr_attendance_time.xml',
|
||||
'data/attendance_code_data.xml',
|
||||
'data/attendance_time_data.xml',
|
||||
'data/attendance_month_date.xml',
|
||||
'data/mail_template.xml',
|
||||
'views/hr_attendance_views.xml',
|
||||
'views/resource_calendar_leaves_views.xml',
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record forcecreate="True" id="attendance_month_data" model="ir.cron">
|
||||
<field name="name">定时任务:考勤统计</field>
|
||||
<field name="model_id" ref="model_hr_attendance_month_wizard"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model.button_attendance_month()</field>
|
||||
<field eval="True" name="active"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="interval_type">months</field>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="nextcall" eval="(DateTime.now()).strftime('%Y-%m-%d 12:00:00')"/>
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall"/>
|
||||
</record>
|
||||
<record forcecreate="True" id="attendance_month_data" model="ir.cron">
|
||||
<field name="name">定时任务:触发考勤统计然后发送</field>
|
||||
<field name="model_id" ref="model_hr_attendance_month_detail"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model.button_all_attendance_month()</field>
|
||||
<field eval="True" name="active"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="interval_type">months</field>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="nextcall" eval="(DateTime.now()).strftime('%Y-%m-%d 12:00:00')"/>
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall"/>
|
||||
</record>
|
||||
<record forcecreate="True" id="attendance_month_detail" model="ir.cron">
|
||||
<field name="name">定时任务:确认字段</field>
|
||||
<field name="model_id" ref="model_hr_attendance_month_detail"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model.attendance_month_detail()</field>
|
||||
<field eval="True" name="active"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="interval_type">months</field>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="nextcall" eval="(DateTime.now()).strftime('%Y-%m-%d 12:30:00')"/>
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -41,7 +41,7 @@ class HrAttendanceMonth(models.Model):
|
||||
is_statistics = fields.Boolean(string="是否已统计", store=True, default=False)
|
||||
statistics_time = fields.Datetime(string="统计时间")
|
||||
attendance_month_detail_ids = fields.One2many(string="出勤月度汇总明细", comodel_name='hr.attendance.month.detail', inverse_name='hr_attendance_month_id')
|
||||
company_id = fields.Many2one('res.company', string="公司名称", default=lambda self: self.env.company)
|
||||
yuthon_company = fields.Selection([('thtz', '天河投资集团'), ('thwg', '天河物管'), ('thlc', '天河粮储')],string='公司')
|
||||
|
||||
def _compute_name(self):
|
||||
for record in self:
|
||||
@@ -128,7 +128,8 @@ class HrAttendanceMonthDetail(models.Model):
|
||||
|
||||
note = fields.Char(string='备注')
|
||||
hr_attendance_month_id = fields.Many2one('hr.attendance.month', string="出勤月度汇总", ondelete="cascade", readonly=True)
|
||||
company_id = fields.Many2one(related="hr_attendance_month_id.company_id")
|
||||
yuthon_company = fields.Selection([('thtz', '天河投资集团'), ('thwg', '天河物管'), ('thlc', '天河粮储')],
|
||||
string='公司')
|
||||
signature = fields.Image(string="签名", copy=False, attachment=True, max_width=1024, max_height=1024)
|
||||
signed_by = fields.Char(string="签名者", copy=False)
|
||||
signed_on = fields.Datetime(string="签名时间", copy=False)
|
||||
@@ -373,11 +374,131 @@ class HrAttendanceMonthDetail(models.Model):
|
||||
record.analysis_attendance_month_detail()
|
||||
|
||||
def button_put(self):
|
||||
pass
|
||||
menu_id = self.env['ir.ui.menu'].search([('name', '=', '我的确认'), ('parent_id', '!=', False)])
|
||||
str = 'https://oa.thtzjt.com/web#id={}&cids=1&menu_id={}&action={}&model=hr.attendance.month.detail&view_type=list'.format(
|
||||
self.id, menu_id.id, menu_id.action.id)
|
||||
we_id = self.env['hr.employee'].search([('id', '=', self.employee_id)]).wecom_userid
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='attendance', user_id=we_id, title="考勤确认",
|
||||
description=self.employee_id.name + '请确认你的考勤:',
|
||||
url=str, btntxt="详细信息")
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'type': 'success',
|
||||
'message': '确认通知已发送',
|
||||
'sticky': False,
|
||||
}
|
||||
}
|
||||
|
||||
def button_all_put(self):
|
||||
pass
|
||||
detail_ids = self.env["hr.attendance.month.detail"].browse(self._context.get('active_ids', self._context.get('active_id')))
|
||||
for detail in detail_ids:
|
||||
menu_id = self.env['ir.ui.menu'].search([('name', '=', '我的确认'), ('parent_id', '!=', False)])
|
||||
str = 'https://oa.thtzjt.com/web#id={}&cids=1&menu_id={}&action={}&model=hr.attendance.month.detail&view_type=list'.format(
|
||||
self.id, menu_id.id, menu_id.action.id)
|
||||
we_id = self.env['hr.employee'].search([('id', '=', detail.employee_id)]).wecom_userid
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='attendance', user_id=we_id, title="考勤确认",
|
||||
description=detail.employee_id.name + '请确认你的考勤:',
|
||||
url=str, btntxt="详细信息")
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'type': 'success',
|
||||
'message': '确认通知已发送',
|
||||
'sticky': False,
|
||||
}
|
||||
}
|
||||
|
||||
def button_confirm(self):
|
||||
for record in self:
|
||||
record.state = 'confirmed'
|
||||
record.state = 'confirmed'
|
||||
|
||||
def _get_attendance_month_obj(self):
|
||||
"""
|
||||
获取出勤月度汇总记录结果表
|
||||
:return: obj
|
||||
"""
|
||||
self.ensure_one()
|
||||
yuthon_company = self.yuthon_company
|
||||
attendance_month_obj = self.env["hr.attendance.month"].search([
|
||||
('current_year', '=', self.current_year),
|
||||
('current_month', '=', self.current_month),
|
||||
('yuthon_company', '=', yuthon_company),
|
||||
], limit=1)
|
||||
if not attendance_month_obj:
|
||||
attendance_month_obj = self.env["hr.attendance.month"].sudo().create({
|
||||
"attendance_year_id": self.attendance_year_id.id,
|
||||
"current_year": self.current_year,
|
||||
"current_month": self.current_month,
|
||||
"is_statistics": True,
|
||||
"statistics_time": fields.Datetime.now(),
|
||||
"yuthon_company": yuthon_company,
|
||||
})
|
||||
return attendance_month_obj
|
||||
|
||||
def _get_attendance_month_detail(self, employee):
|
||||
"""
|
||||
判断当前是否已经创建了考勤明细
|
||||
:param employee: 员工
|
||||
:return: 考情明细
|
||||
"""
|
||||
self.ensure_one()
|
||||
yuthon_company = self.yuthon_company
|
||||
attendance_month_detail_obj = self.env["hr.attendance.month.detail"].search(
|
||||
[('employee_id', '=', employee.id),
|
||||
('current_year', '=', self.current_year),
|
||||
('current_month', '=', self.current_month),
|
||||
('yuthon_company', '=', yuthon_company)
|
||||
], limit=1)
|
||||
if not attendance_month_detail_obj:
|
||||
attendance_month_detail_obj = self.env["hr.attendance.month.detail"].sudo().create({
|
||||
"employee_id": employee.id,
|
||||
"attendance_year_id": self.attendance_year_id.id,
|
||||
"current_year": self.current_year,
|
||||
"current_month": self.current_month,
|
||||
"yuthon_company": yuthon_company
|
||||
})
|
||||
return attendance_month_detail_obj
|
||||
|
||||
def button_compute_all(self):
|
||||
self.ensure_one()
|
||||
attendance_month_obj = self._get_attendance_month_obj()
|
||||
# 查询所有的当前员工? 是否需要判断当前员工是否关联企业微信??预留
|
||||
calendars = self.env['resource.calendar'].search([])
|
||||
all_employee_ids = set()
|
||||
for calendar in calendars:
|
||||
all_employee_ids.update(calendar.resource_user_ids.ids)
|
||||
all_employee_ids = list(all_employee_ids)
|
||||
detail_ids = self.env["hr.attendance.month.detail"].browse(self._context.get('active_ids', self._context.get('active_id')))
|
||||
for detail_id in detail_ids:
|
||||
if detail_id.employee_id not in all_employee_ids:
|
||||
# 判断当前是否已经创建了考勤明细
|
||||
attendance_month_detail_obj = self._get_attendance_month_detail(detail_id.employee_id)
|
||||
attendance_month_detail_obj.hr_attendance_month_id = attendance_month_obj.id
|
||||
# 判断当前用户是否已经确认签字,签字后不再更新
|
||||
if attendance_month_detail_obj.state == 'confirmed' and attendance_month_detail_obj.signature:
|
||||
continue
|
||||
# 更新用户的考勤明细
|
||||
attendance_month_detail_obj.analysis_attendance_month_detail()
|
||||
# 返回action动作
|
||||
action = self._hr_attendance_month_detail_action()
|
||||
return action
|
||||
|
||||
def attendance_month_detail(self):
|
||||
attendance_details = self.env['hr.attendance.month.detail'].search([])
|
||||
for detail in attendance_details:
|
||||
detail.write({'state': 'confirmed'})
|
||||
|
||||
|
||||
def button_all_attendance_month(self):
|
||||
attendance_details = self.env['hr.attendance.month.detail'].search([])
|
||||
for detail in attendance_details:
|
||||
menu_id = self.env['ir.ui.menu'].search([('name', '=', '我的确认'), ('parent_id', '!=', False)])
|
||||
str = 'https://oa.thtzjt.com/web#id={}&cids=1&menu_id={}&action={}&model=hr.attendance.month.detail&view_type=list'.format(
|
||||
self.id, menu_id.id, menu_id.action.id)
|
||||
we_id = self.env['hr.employee'].search([('id', '=', detail.employee_id)]).wecom_userid
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='attendance', user_id=we_id, title="考勤确认",
|
||||
description=detail .employee_id.name + '请确认你的考勤:',
|
||||
url=str, btntxt="详细信息")
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
parent="hr_attendance_root_board"
|
||||
groups="group_he_attendance_manager"
|
||||
sequence="4"/>
|
||||
<!-- <menuitem id="menu_hr_attendance_month_wizard" name="考勤统计" parent="menu_hr_attendance_month_board"-->
|
||||
<!-- action="action_hr_attendance_month_wizard"/>-->
|
||||
<menuitem id="menu_hr_attendance_month_wizard" name="考勤统计" parent="menu_hr_attendance_month_board"
|
||||
action="action_hr_attendance_month_wizard"/>
|
||||
<menuitem id="menu_hr_attendance_month_view_attendances" name="报表" parent="menu_hr_attendance_month_board"
|
||||
sequence="30" action="hr_attendance_month_action"/>
|
||||
<menuitem id="menu_hr_attendance_year_view_attendances" name="出勤年份维护" parent="menu_hr_attendance_month_board"
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<field name="current_month" />
|
||||
<field name="is_statistics"/>
|
||||
<field name="statistics_time"/>
|
||||
<field name="company_id" />
|
||||
<field name="yuthon_company" />
|
||||
<button name="action_show_details" string="汇总明细" type="object" title="Show Details" icon="fa-list"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -34,7 +34,7 @@
|
||||
<field name="name">hr.attendance.month.form</field>
|
||||
<field name="model">hr.attendance.month</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="hr attendance month" create="0">
|
||||
<form string="hr attendance month">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="current_year" />
|
||||
@@ -94,7 +94,7 @@
|
||||
<!-- 其他-->
|
||||
<field name="holiday_id"/>
|
||||
<field name="note"/>
|
||||
<field name="company_id"/>
|
||||
<field name="yuthon_company"/>
|
||||
<field name="state" widget="badge" decoration-info="state == 'unconfirmed'" decoration-success="state == 'confirmed'"/>
|
||||
<button name="button_put" string="发送" type="object" class="oe_highlight"/>
|
||||
</tree>
|
||||
@@ -137,7 +137,7 @@
|
||||
<!-- 其他-->
|
||||
<field name="holiday_id"/>
|
||||
<field name="note"/>
|
||||
<field name="company_id"/>
|
||||
<field name="yuthon_company"/>
|
||||
<field name="state" widget="badge" decoration-info="state == 'unconfirmed'" decoration-success="state == 'confirmed'"/>
|
||||
<button name="button_confirm" string="确认" type="object" class="oe_highlight"/>
|
||||
</tree>
|
||||
@@ -168,7 +168,7 @@
|
||||
<field name="work_overtime"/>
|
||||
<field name="statutory_leave"/>
|
||||
<field name="note"/>
|
||||
<field name="company_id"/>
|
||||
<field name="yuthon_company"/>
|
||||
<field name="state" />
|
||||
</group>
|
||||
</group>
|
||||
@@ -237,4 +237,11 @@
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.button_all_put()</field>
|
||||
</record>
|
||||
<record id="all_data_attendance_month_compute" model="ir.actions.server">
|
||||
<field name="name">批量计算</field>
|
||||
<field name="model_id" ref="yuthon_hr_attendance.model_hr_attendance_month_detail"/>
|
||||
<field name="binding_model_id" ref="yuthon_hr_attendance.model_hr_attendance_month_detail"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = model.button_compute_all()</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -25,7 +25,15 @@ class HrAttendanceMonthWizard(models.TransientModel):
|
||||
('11', '11月份'),
|
||||
('12', '12月份')
|
||||
], string="考勤月份")
|
||||
company_id = fields.Many2one('res.company', default=lambda self: self.env.company)
|
||||
yuthon_company = fields.Selection([('thtz', '天河投资集团'), ('thwg', '天河物管'), ('thlc', '天河粮储')],
|
||||
string='公司', default=lambda self: self._get_default_yuthon_company())
|
||||
|
||||
def _get_default_yuthon_company(self):
|
||||
current_user = self.env.user
|
||||
employee = self.env['hr.employee'].search([('user_id', '=', current_user.id)], limit=1)
|
||||
if employee and employee.yuthon_company:
|
||||
return employee.yuthon_company
|
||||
return False
|
||||
|
||||
def _get_attendance_month_obj(self):
|
||||
"""
|
||||
@@ -33,11 +41,11 @@ class HrAttendanceMonthWizard(models.TransientModel):
|
||||
:return: obj
|
||||
"""
|
||||
self.ensure_one()
|
||||
company_id = self.company_id.id or self.env.company.id
|
||||
yuthon_company = self.yuthon_company
|
||||
attendance_month_obj = self.env["hr.attendance.month"].search([
|
||||
('current_year', '=', self.current_year),
|
||||
('current_month', '=', self.current_month),
|
||||
('company_id', '=', company_id),
|
||||
('yuthon_company', '=', yuthon_company),
|
||||
], limit=1)
|
||||
if not attendance_month_obj:
|
||||
attendance_month_obj = self.env["hr.attendance.month"].sudo().create({
|
||||
@@ -46,8 +54,8 @@ class HrAttendanceMonthWizard(models.TransientModel):
|
||||
"current_month": self.current_month,
|
||||
"is_statistics": True,
|
||||
"statistics_time": fields.Datetime.now(),
|
||||
"company_id": company_id,
|
||||
})
|
||||
"yuthon_company": yuthon_company,
|
||||
})
|
||||
return attendance_month_obj
|
||||
|
||||
def _get_attendance_month_detail(self, employee):
|
||||
@@ -57,17 +65,20 @@ class HrAttendanceMonthWizard(models.TransientModel):
|
||||
:return: 考情明细
|
||||
"""
|
||||
self.ensure_one()
|
||||
yuthon_company = self.yuthon_company
|
||||
attendance_month_detail_obj = self.env["hr.attendance.month.detail"].search(
|
||||
[('employee_id', '=', employee.id),
|
||||
('current_year', '=', self.current_year),
|
||||
('current_month', '=', self.current_month)
|
||||
('current_month', '=', self.current_month),
|
||||
('yuthon_company', '=', yuthon_company)
|
||||
], limit=1)
|
||||
if not attendance_month_detail_obj:
|
||||
attendance_month_detail_obj = self.env["hr.attendance.month.detail"].sudo().create({
|
||||
"employee_id": employee.id,
|
||||
"attendance_year_id": self.attendance_year_id.id,
|
||||
"current_year": self.current_year,
|
||||
"current_month": self.current_month
|
||||
"current_month": self.current_month,
|
||||
"yuthon_company": yuthon_company
|
||||
})
|
||||
return attendance_month_detail_obj
|
||||
|
||||
@@ -77,7 +88,7 @@ class HrAttendanceMonthWizard(models.TransientModel):
|
||||
:return: ir.actions.act_window 视图 view_hr_attendance_month_detail_tree
|
||||
"""
|
||||
self.ensure_one()
|
||||
company_id = self.company_id.id or self.env.company.id
|
||||
yuthon_company = self.yuthon_company
|
||||
action = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'hr.attendance.month.detail',
|
||||
@@ -87,12 +98,12 @@ class HrAttendanceMonthWizard(models.TransientModel):
|
||||
'context': {
|
||||
"current_year": self.current_year,
|
||||
"current_month": self.current_month,
|
||||
"company_id": company_id
|
||||
"yuthon_company": yuthon_company
|
||||
},
|
||||
'domain': [
|
||||
('current_year', '=', self.current_year),
|
||||
('current_month', '=', self.current_month),
|
||||
('company_id', '=', company_id),
|
||||
('yuthon_company', '=', yuthon_company),
|
||||
],
|
||||
'target': 'main',
|
||||
'views': [[self.env.ref('yuthon_hr_attendance.view_hr_attendance_month_detail_tree').id, 'list'],
|
||||
@@ -109,13 +120,13 @@ class HrAttendanceMonthWizard(models.TransientModel):
|
||||
attendance_month_obj = self._get_attendance_month_obj()
|
||||
# 查询所有的当前员工? 是否需要判断当前员工是否关联企业微信??预留
|
||||
user_obj = self.env['res.users'].sudo().search([])
|
||||
company_id = self.company_id.id or self.env.company.id
|
||||
yuthon_company = self.yuthon_company
|
||||
calendars = self.env['resource.calendar'].search([])
|
||||
all_employee_ids = set()
|
||||
for calendar in calendars:
|
||||
all_employee_ids.update(calendar.resource_user_ids.ids)
|
||||
all_employee_ids = list(all_employee_ids)
|
||||
hr_employee_obj = self.env['hr.employee'].sudo().search([("user_id", "in", user_obj.ids), ("company_id", "=", company_id)])
|
||||
hr_employee_obj = self.env['hr.employee'].sudo().search([("user_id", "in", user_obj.ids), ("yuthon_company", "=", yuthon_company)])
|
||||
# 循环所有员工对每个人进行统计
|
||||
for employee in hr_employee_obj:
|
||||
if employee.id not in all_employee_ids:
|
||||
@@ -130,3 +141,20 @@ class HrAttendanceMonthWizard(models.TransientModel):
|
||||
# 返回action动作
|
||||
action = self._hr_attendance_month_detail_action()
|
||||
return action
|
||||
|
||||
# 考勤定时任务
|
||||
def button_attendance_month(self):
|
||||
now = datetime.datetime.now()
|
||||
year = now.year
|
||||
month = str(now.month)
|
||||
company_options = ['thtz', 'thwg', 'thlc']
|
||||
attendance_year = self.env['hr.attendance.year'].search([('year', '=', str(year))], limit=1)
|
||||
if not attendance_year:
|
||||
attendance_year = self.env['hr.attendance.year'].create({'year': str(year)})
|
||||
for option in company_options:
|
||||
wizard = self.create({
|
||||
'attendance_year_id': attendance_year.id,
|
||||
'current_month': month,
|
||||
'yuthon_company':option
|
||||
})
|
||||
wizard.search_attendance_month()
|
||||
@@ -8,7 +8,7 @@
|
||||
<group>
|
||||
<field name="attendance_year_id"/>
|
||||
<field name="current_month" />
|
||||
<field name="company_id" string="公司名称" invisible="1"/>
|
||||
<field name="yuthon_company" string="公司名称"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="search_attendance_month" id="search_attendance_month" string="开始统计" type="object" class="btn-primary"/>
|
||||
|
||||
@@ -120,9 +120,9 @@ class YuthonNotice(models.Model):
|
||||
'state': 'no',
|
||||
})
|
||||
we_id = self.env['hr.employee'].search([('id', '=', employee_id)]).wecom_userid
|
||||
# self.sudo().env["wecom.apps"].sync_send_message_textcard(category='notice', user_id=we_id, title="通知公告",
|
||||
# description=self.name + '发布人:' + self.users_id.name,
|
||||
# url=str, btntxt="详细信息")
|
||||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='notice', user_id=we_id, title="通知公告",
|
||||
description=self.name + '发布人:' + self.users_id.name,
|
||||
url=str, btntxt="详细信息")
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
|
||||
Reference in New Issue
Block a user