From f2bb1f3eb8c43a5927547a43dc24eb1358c6727e Mon Sep 17 00:00:00 2001
From: zhouzhou <123@qq.com>
Date: Thu, 5 Dec 2024 20:30:01 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
yuthon_duty_plan/models/yuthon_duty_plan.py | 2 +-
.../models/planning_template_inherit.py | 21 ++
.../models/yuthon_run_planning.py | 231 ++++++++++++++----
.../models/yuthon_shift_planning.py | 31 +--
.../inherit_planning_slot_template_views.xml | 12 +-
.../views/inherit_planning_slot_views.xml | 3 +
.../views/yuthon_run_planning_views.xml | 124 ++++++++--
yuthon_work_brand/views/attendance_menu.xml | 17 +-
8 files changed, 348 insertions(+), 93 deletions(-)
diff --git a/yuthon_duty_plan/models/yuthon_duty_plan.py b/yuthon_duty_plan/models/yuthon_duty_plan.py
index 1f200fd28..905c86594 100644
--- a/yuthon_duty_plan/models/yuthon_duty_plan.py
+++ b/yuthon_duty_plan/models/yuthon_duty_plan.py
@@ -24,7 +24,7 @@ class YuthonDutyPlan(models.Model):
duty_lines = []
current_date = first_day_of_month
while current_date <= last_day_of_month:
- for line in self.plan_line_ids:
+ for line in self.plan_line_ids.sorted('sequence'):
for employee in line.employee_ids:
duty_lines.append({
'employee_id': employee.id,
diff --git a/yuthon_hr_attendance/models/planning_template_inherit.py b/yuthon_hr_attendance/models/planning_template_inherit.py
index 6054f1e18..09c5d43a1 100644
--- a/yuthon_hr_attendance/models/planning_template_inherit.py
+++ b/yuthon_hr_attendance/models/planning_template_inherit.py
@@ -6,11 +6,18 @@ from datetime import datetime, timedelta, time, date
from odoo import api, fields, models, _
from odoo.tools import format_time
+from random import randint, shuffle
class PlanningTemplate(models.Model):
_inherit = 'planning.slot.template'
+ def _get_default_color(self):
+ return randint(1, 11)
+
+ planning_name = fields.Char(string='名称')
+ color = fields.Integer("颜色", default=_get_default_color)
+
def _compute_name(self):
super()._compute_name()
user_tz = pytz.timezone(self.env['planning.slot']._get_tz())
@@ -38,10 +45,24 @@ class PlanningTemplate(models.Model):
duration_days = math.ceil((end_datetime - start_datetime).total_seconds() / (3600 * 24))
return duration_days, timedelta(hours=end_datetime.hour, minutes=end_datetime.minute).total_seconds() / 3600
+ @api.depends("planning_name")
+ def _compute_display_name(self):
+ super()._compute_display_name()
+ for record in self:
+ record.display_name = f"{record.name} {record.role_id.name}{record.planning_name}"
+
class Planning(models.Model):
_inherit = 'planning.slot'
+ department_id = fields.Many2one('hr.department', string='部门')
+ color = fields.Integer("Color", compute='_compute_color')
+
+ @api.depends('template_id.color')
+ def _compute_color(self):
+ for slot in self:
+ slot.color = slot.template_id.color
+
# 修改原生自动安排函数
@api.model
def auto_plan_ids(self, view_domain):
diff --git a/yuthon_hr_attendance/models/yuthon_run_planning.py b/yuthon_hr_attendance/models/yuthon_run_planning.py
index 286e3b5e0..a05e1ff12 100644
--- a/yuthon_hr_attendance/models/yuthon_run_planning.py
+++ b/yuthon_hr_attendance/models/yuthon_run_planning.py
@@ -13,65 +13,56 @@ class YuthonRunPlanning(models.Model):
high_run_ids = fields.One2many('yuthon.high.run.line', 'engineering_planning_id', string='关联高压班排班明细')
all_run_ids = fields.One2many('yuthon.all.run.line', 'engineering_planning_id', string='关联综合部排班明细')
other_run_ids = fields.One2many('yuthon.other.line', 'engineering_planning_id', string='关联其他明细')
-
- def confirm(self):
- run_lines_list = [self.engineering_run_ids, self.high_run_ids, self.all_run_ids]
+ department_run_id = fields.Many2one("hr.department", string="部门", required=True, default=lambda self: self.env['hr.department'].search([('name', '=', '运行班')]))
+ department_high_id = fields.Many2one("hr.department", string="部门", required=True, default=lambda self: self.env['hr.department'].search([('name', '=', '高压班')]))
+ department_integrated_id = fields.Many2one("hr.department", string="部门", required=True, default=lambda self: self.env['hr.department'].search([('name', '=', '综合班')]))
+ # 运行班
+ def run_confirm(self):
today = datetime.today().date()
first_day_of_month = today.replace(day=1)
if today.month < 12:
last_day_of_month = (today.replace(month=today.month + 1, day=1) - timedelta(days=1))
else:
last_day_of_month = (today.replace(year=today.year + 1, month=1, day=1) - timedelta(days=1))
- role_a = self.env['planning.role'].search([('name', '=', '工程部白班')], limit=1)
- start_time = int(self.env['planning.slot.template'].search([('role_id', '=', role_a.id)]).start_time)
- end_time = int(self.env['planning.slot.template'].search([('role_id', '=', role_a.id)]).end_time)
- run = 0
- for run_lines in run_lines_list:
- if not run_lines:
- continue
- run += 1
- for employee in run_lines:
- current_date = first_day_of_month
- while current_date <= last_day_of_month:
- resource_id = employee.employee_id.resource_id
- self.env['planning.slot'].create({
- 'resource_id': resource_id.id,
- 'start_datetime': datetime(current_date.year, current_date.month, current_date.day, start_time) + timedelta(hours=16),
- 'end_datetime': datetime(current_date.year, current_date.month, current_date.day, end_time) + timedelta(hours=16),
- 'role_id': role_a.id,
- 'allocated_hours': 8,
- })
- current_date += timedelta(days=1)
- if current_date > last_day_of_month:
- break
- role_b = self.env['planning.role'].search([('name', '=', '工程部中值夜班')], limit=1)
- start_time2 = int(self.env['planning.slot.template'].search([('role_id', '=', role_b.id)]).start_time)
- end_time2 = int(self.env['planning.slot.template'].search([('role_id', '=', role_b.id)]).end_time)
- if run == 1:
- all_slot = self.env['planning.slot'].search([('department_id.name', '=', '运行班')])
- elif run == 2:
- all_slot = self.env['planning.slot'].search([('department_id.name', '=', '高压班')])
- elif run == 3:
- all_slot = self.env['planning.slot'].search([('department_id.name', '=', '综合班')])
-
+ role_a = self.env['planning.role'].search([('name', '=', '工程部')], limit=1)
+ start_time = int(self.env['planning.slot.template'].search([('role_id', '=', role_a.id), ('planning_name', '=', '白班')]).start_time)
+ end_time = int(self.env['planning.slot.template'].search([('role_id', '=', role_a.id), ('planning_name', '=', '白班')]).end_time)
+ for employee in self.engineering_run_ids:
current_date = first_day_of_month
- i = -1
while current_date <= last_day_of_month:
- for employee in range(0, len(run_lines)):
- i = i + 1
- slot_id = all_slot.search([('resource_id', '=', run_lines[employee].employee_id.resource_id.id)]).sorted('start_datetime')[i]
- slot_id.sudo().write({
- 'template_id': self.env['planning.slot.template'].search([('role_id', '=', role_b.id)]).id,
- 'start_datetime': datetime(current_date.year, current_date.month, current_date.day,
- start_time2) + timedelta(hours=16),
- 'end_datetime': datetime(current_date.year, current_date.month, current_date.day,
- end_time2) + timedelta(days=1, hours=16),
- 'role_id': role_b.id,
- 'allocated_hours': 8,
- })
- current_date += timedelta(days=1)
- if current_date > last_day_of_month:
- break
+ resource_id = employee.employee_id.resource_id
+ self.env['planning.slot'].create({
+ 'template_id': self.env['planning.slot.template'].search([('role_id', '=', role_a.id), ('planning_name', '=', '白班')]).id,
+ 'resource_id': resource_id.id,
+ 'start_datetime': datetime(current_date.year, current_date.month, current_date.day, start_time) + timedelta(hours=16),
+ 'end_datetime': datetime(current_date.year, current_date.month, current_date.day, end_time) + timedelta(hours=16),
+ 'role_id': role_a.id,
+ 'allocated_hours': 8,
+ })
+ current_date += timedelta(days=1)
+ if current_date > last_day_of_month:
+ break
+ start_time2 = int(self.env['planning.slot.template'].search([('planning_name', '=', '中值夜班'), ('role_id', '=', role_a.id)]).start_time)
+ end_time2 = int(self.env['planning.slot.template'].search([('planning_name', '=', '中值夜班'), ('role_id', '=', role_a.id)]).end_time)
+ all_slot = self.env['planning.slot'].search([('department_id.name', '=', '运行班')])
+ current_date = first_day_of_month
+ i = -1
+ while current_date <= last_day_of_month:
+ for employee in range(0, len(self.engineering_run_ids)):
+ i = i + 1
+ slot_id = all_slot.search([('resource_id', '=', self.engineering_run_ids[employee].employee_id.resource_id.id)]).sorted('start_datetime')[i]
+ slot_id.sudo().write({
+ 'template_id': self.env['planning.slot.template'].search([('role_id', '=', role_a.id), ('planning_name', '=', '中值夜班')]).id,
+ 'start_datetime': datetime(current_date.year, current_date.month, current_date.day,
+ start_time2) + timedelta(hours=16),
+ 'end_datetime': datetime(current_date.year, current_date.month, current_date.day,
+ end_time2) + timedelta(days=1, hours=16),
+ 'role_id': role_a.id,
+ 'allocated_hours': 8,
+ })
+ current_date += timedelta(days=1)
+ if current_date > last_day_of_month:
+ break
other_data = {}
for other in self.other_run_ids:
@@ -92,18 +83,19 @@ class YuthonRunPlanning(models.Model):
pass
else:
self.env['planning.slot'].create({
+ 'template_id': self.env['planning.slot.template'].search([('role_id', '=', role_a.id), ('planning_name', '=', '白班')]).id,
'resource_id': resource_id.id,
'start_datetime': datetime(current_date.year, current_date.month, current_date.day,
start_time) + timedelta(hours=16),
'end_datetime': datetime(current_date.year, current_date.month, current_date.day,
end_time) + timedelta(hours=16),
'role_id': role_a.id,
+ ''
'allocated_hours': 8,
})
current_date += timedelta(days=1)
if current_date > last_day_of_month:
break
-
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
@@ -113,7 +105,140 @@ class YuthonRunPlanning(models.Model):
'sticky': False,
}
}
+ # 高压班
+ def high_confirm(self):
+ today = datetime.today().date()
+ first_day_of_month = today.replace(day=1)
+ if today.month < 12:
+ last_day_of_month = (today.replace(month=today.month + 1, day=1) - timedelta(days=1))
+ else:
+ last_day_of_month = (today.replace(year=today.year + 1, month=1, day=1) - timedelta(days=1))
+ role_a = self.env['planning.role'].search([('name', '=', '工程部')], limit=1)
+ start_time = int(self.env['planning.slot.template'].search(
+ [('role_id', '=', role_a.id), ('planning_name', '=', '白班')]).start_time)
+ end_time = int(self.env['planning.slot.template'].search(
+ [('role_id', '=', role_a.id), ('planning_name', '=', '白夜班')]).end_time)
+ for employee in self.high_run_ids:
+ current_date = first_day_of_month
+ while current_date <= last_day_of_month:
+ resource_id = employee.employee_id.resource_id
+ self.env['planning.slot'].create({
+ 'template_id': self.env['planning.slot.template'].search(
+ [('role_id', '=', role_a.id), ('planning_name', '=', '白班')]).id,
+ 'resource_id': resource_id.id,
+ 'start_datetime': datetime(current_date.year, current_date.month, current_date.day,
+ start_time) + timedelta(hours=16),
+ 'end_datetime': datetime(current_date.year, current_date.month, current_date.day,
+ end_time) + timedelta(hours=16),
+ 'role_id': role_a.id,
+ 'allocated_hours': 8,
+ })
+ current_date += timedelta(days=1)
+ if current_date > last_day_of_month:
+ break
+ start_time2 = int(self.env['planning.slot.template'].search(
+ [('planning_name', '=', '中值夜班'), ('role_id', '=', role_a.id)]).start_time)
+ end_time2 = int(self.env['planning.slot.template'].search(
+ [('planning_name', '=', '中值夜班'), ('role_id', '=', role_a.id)]).end_time)
+ all_slot = self.env['planning.slot'].search([('department_id.name', '=', '高压班')])
+ current_date = first_day_of_month
+ i = -1
+ while current_date <= last_day_of_month:
+ for employee in range(0, len(self.high_run_ids)):
+ i = i + 1
+ slot_id = all_slot.search(
+ [('resource_id', '=', self.high_run_ids[employee].employee_id.resource_id.id)]).sorted(
+ 'start_datetime')[i]
+ slot_id.sudo().write({
+ 'template_id': self.env['planning.slot.template'].search(
+ [('role_id', '=', role_a.id), ('planning_name', '=', '中值夜班')]).id,
+ 'start_datetime': datetime(current_date.year, current_date.month, current_date.day,
+ start_time2) + timedelta(hours=16),
+ 'end_datetime': datetime(current_date.year, current_date.month, current_date.day,
+ end_time2) + timedelta(days=1, hours=16),
+ 'role_id': role_a.id,
+ 'allocated_hours': 8,
+ })
+ current_date += timedelta(days=1)
+ if current_date > last_day_of_month:
+ break
+ return {
+ 'type': 'ir.actions.client',
+ 'tag': 'display_notification',
+ 'params': {
+ 'type': 'success',
+ 'message': '排班安排已完成',
+ 'sticky': False,
+ }
+ }
+ # 综合班
+ def integrated_confirm(self):
+ today = datetime.today().date()
+ first_day_of_month = today.replace(day=1)
+ if today.month < 12:
+ last_day_of_month = (today.replace(month=today.month + 1, day=1) - timedelta(days=1))
+ else:
+ last_day_of_month = (today.replace(year=today.year + 1, month=1, day=1) - timedelta(days=1))
+ role_a = self.env['planning.role'].search([('name', '=', '工程部')], limit=1)
+ start_time = int(self.env['planning.slot.template'].search(
+ [('role_id', '=', role_a.id), ('planning_name', '=', '白班')]).start_time)
+ end_time = int(self.env['planning.slot.template'].search(
+ [('role_id', '=', role_a.id), ('planning_name', '=', '白夜班')]).end_time)
+ for employee in self.all_run_ids:
+ current_date = first_day_of_month
+ while current_date <= last_day_of_month:
+ resource_id = employee.employee_id.resource_id
+ self.env['planning.slot'].create({
+ 'template_id': self.env['planning.slot.template'].search(
+ [('role_id', '=', role_a.id), ('planning_name', '=', '白班')]).id,
+ 'resource_id': resource_id.id,
+ 'start_datetime': datetime(current_date.year, current_date.month, current_date.day,
+ start_time) + timedelta(hours=16),
+ 'end_datetime': datetime(current_date.year, current_date.month, current_date.day,
+ end_time) + timedelta(hours=16),
+ 'role_id': role_a.id,
+ 'allocated_hours': 8,
+ })
+ current_date += timedelta(days=1)
+ if current_date > last_day_of_month:
+ break
+ start_time2 = int(self.env['planning.slot.template'].search(
+ [('planning_name', '=', '中值夜班'), ('role_id', '=', role_a.id)]).start_time)
+ end_time2 = int(self.env['planning.slot.template'].search(
+ [('planning_name', '=', '中值夜班'), ('role_id', '=', role_a.id)]).end_time)
+
+ all_slot = self.env['planning.slot'].search([('department_id.name', '=', '综合班')])
+ current_date = first_day_of_month
+ i = -1
+ while current_date <= last_day_of_month:
+ for employee in range(0, len(self.all_run_ids)):
+ i = i + 1
+ slot_id = all_slot.search(
+ [('resource_id', '=', self.all_run_ids[employee].employee_id.resource_id.id)]).sorted(
+ 'start_datetime')[i]
+ slot_id.sudo().write({
+ 'template_id': self.env['planning.slot.template'].search(
+ [('role_id', '=', role_a.id), ('planning_name', '=', '中值夜班')]).id,
+ 'start_datetime': datetime(current_date.year, current_date.month, current_date.day,
+ start_time2) + timedelta(hours=16),
+ 'end_datetime': datetime(current_date.year, current_date.month, current_date.day,
+ end_time2) + timedelta(days=1, hours=16),
+ 'role_id': role_a.id,
+ 'allocated_hours': 8,
+ })
+ current_date += timedelta(days=1)
+ if current_date > last_day_of_month:
+ break
+ return {
+ 'type': 'ir.actions.client',
+ 'tag': 'display_notification',
+ 'params': {
+ 'type': 'success',
+ 'message': '排班安排已完成',
+ 'sticky': False,
+ }
+ }
class YuthonEngineeringRunLine(models.Model):
_name = 'yuthon.engineering.run.line'
@@ -150,7 +275,7 @@ class YuthonOtherLine(models.Model):
('four', '星期四'), ('five', '星期五'), ('six', '星期六'),
('seven', '星期日')], string='固定休息日')
employee_id = fields.Many2one('hr.employee', string='人员',
- domain=lambda self: [('department_id.name', 'in', ['综合班', '高压班', '运行班'])])
+ domain=lambda self: [('department_id.name', 'in', ['运行班'])])
sequence = fields.Integer(string='序号')
engineering_planning_id = fields.Many2one('yuthon.run.planning', string='关联工程部排班计划')
diff --git a/yuthon_hr_attendance/models/yuthon_shift_planning.py b/yuthon_hr_attendance/models/yuthon_shift_planning.py
index b88612d5c..f4d0a1ed0 100644
--- a/yuthon_hr_attendance/models/yuthon_shift_planning.py
+++ b/yuthon_hr_attendance/models/yuthon_shift_planning.py
@@ -16,12 +16,13 @@ class YuthonShiftPlanning(models.Model):
planning_ever_noon_ids = fields.One2many('yuthon.shift.ever.noon.line', 'shift_planning_id', string='关联常中班')
def confirm(self):
- start_date = datetime.now().replace(day=1) # 获取本月第一天零点
- end_date = (start_date + timedelta(days=32)).replace(day=1) # 获取下个月第一天零点
- role_a = self.env['planning.role'].search([('name', '=', '保安部白班')], limit=1)
- role_b = self.env['planning.role'].search([('name', '=', '保安部中班')], limit=1)
- role_c = self.env['planning.role'].search([('name', '=', '保安部夜班')], limit=1)
- role = [role_a, role_b, role_c]
+ start_date = datetime.today().replace(day=1) # 获取本月日期
+ end_date = (start_date + timedelta(days=32)).replace(day=1) # 获取下个月第一天日期
+ role_a = self.env['planning.role'].search([('name', '=', '保安部')], limit=1)
+ role_template_a = self.env['planning.slot.template'].search([('planning_name', '=', '白班'), ('role_id', '=', role_a.id)])
+ role_template_b = self.env['planning.slot.template'].search([('planning_name', '=', '中班'), ('role_id', '=', role_a.id)])
+ role_template_c = self.env['planning.slot.template'].search([('planning_name', '=', '夜班'), ('role_id', '=', role_a.id)])
+ role = [role_template_a, role_template_b, role_template_c]
planning_groups = {
'planning_a_ids': range(len(role)), # 默认顺序: 早 -> 中 -> 夜
'planning_b_ids': [1, 2, 0], # 中 -> 夜 -> 早
@@ -59,9 +60,9 @@ class YuthonShiftPlanning(models.Model):
if resource_id in ever_holidays and current_weekday in ever_holidays[resource_id]:
pass # 跳过休息日
else:
- role_template = self.env['planning.slot.template'].search(
- [('role_id', '=', role[role_index].id)], limit=1)
- self.create_planning_slot(record, role[role_index], role_template, current_date)
+ # role_template = self.env['planning.slot.template'].search(
+ # [('role_id', '=', role[role_index].id)], limit=1)
+ self.create_planning_slot(record, role_a, role[role_index], current_date)
current_date += timedelta(days=1)
if current_date >= end_date:
break
@@ -99,9 +100,7 @@ class YuthonShiftPlanning(models.Model):
if resource_id in ever_holidays and current_weekday in ever_holidays[resource_id]:
pass # 跳过休息日
else:
- role_template = self.env['planning.slot.template'].search(
- [('role_id', '=', role_item.id)], limit=1)
- self.create_planning_slot(record, role_item, role_template, current_date) # 确保这个方法存在
+ self.create_planning_slot(record, role_a,role_item, current_date) # 确保这个方法存在
current_date += timedelta(days=1)
# 为白班员工创建排班
create_shifts_for_group(self.planning_ever_white_ids, role[0])
@@ -112,13 +111,15 @@ class YuthonShiftPlanning(models.Model):
def create_planning_slot(self, record,role,role_template,current_date):
start_hour = int(role_template.start_time)
end_hour = int(role_template.end_time)
- start_time = current_date.replace(hour=start_hour)+ timedelta(hours=16)
+ current_datetime = datetime.combine(current_date, time(0, 0, 0))
+ start_time = current_datetime.replace(hour=start_hour)+ timedelta(hours=16)
if role_template.end_time < role_template.start_time:
- end_time = current_date.replace(hour=end_hour)+ timedelta(days=1, hours=16)
+ end_time = current_datetime.replace(hour=end_hour)+ timedelta(days=1, hours=16)
else:
- end_time = current_date.replace(hour=end_hour)+ timedelta(hours=16)
+ end_time = current_datetime.replace(hour=end_hour)+ timedelta(hours=16)
self.env['planning.slot'].create({
'resource_id': record.employee_id.resource_id.id,
+ 'template_id':role_template.id,
'role_id':role.id,
'start_datetime': start_time,
'end_datetime': end_time,
diff --git a/yuthon_hr_attendance/views/inherit_planning_slot_template_views.xml b/yuthon_hr_attendance/views/inherit_planning_slot_template_views.xml
index 0f8c42c10..51f9c1fd2 100644
--- a/yuthon_hr_attendance/views/inherit_planning_slot_template_views.xml
+++ b/yuthon_hr_attendance/views/inherit_planning_slot_template_views.xml
@@ -2,20 +2,28 @@
planning.slot.template.tree.inherit
planning.slot.template
-
+
+
+
+
+
planning.slot.template.form.inherit
planning.slot.template
-
+
+
+
+
+
diff --git a/yuthon_hr_attendance/views/inherit_planning_slot_views.xml b/yuthon_hr_attendance/views/inherit_planning_slot_views.xml
index a67561425..b9c0ea139 100644
--- a/yuthon_hr_attendance/views/inherit_planning_slot_views.xml
+++ b/yuthon_hr_attendance/views/inherit_planning_slot_views.xml
@@ -26,6 +26,9 @@
+
+
+
diff --git a/yuthon_hr_attendance/views/yuthon_run_planning_views.xml b/yuthon_hr_attendance/views/yuthon_run_planning_views.xml
index 7f43825d1..8b900f1a7 100644
--- a/yuthon_hr_attendance/views/yuthon_run_planning_views.xml
+++ b/yuthon_hr_attendance/views/yuthon_run_planning_views.xml
@@ -10,6 +10,7 @@
+
yuthon.run.planning.form
yuthon.run.planning
@@ -17,11 +18,12 @@
+
+
+ yuthon.integrated.planning.tree
+ yuthon.run.planning
+
+
+
+
+
+
+
+
+ yuthon.integrated.planning.form
+ yuthon.run.planning
+
+
+
+
+
+
+ yuthon.high.planning.tree
+ yuthon.run.planning
+
+
+
+
+
+
+
+
+ yuthon.high.planning.form
+ yuthon.run.planning
+
+
+
+
- 排班安排
+ 运行班安排
yuthon.run.planning
tree,form
+ [('department_run_id.name', '=', '运行班')]
+
+
+
+ 综合部安排
+ yuthon.run.planning
+ tree,form
+ [('department_high_id.name', '=', '综合班')]
+
+
+
+ 高压部安排
+ yuthon.run.planning
+ tree,form
+ [('department_integrated_id.name', '=', '高压班')]
+
diff --git a/yuthon_work_brand/views/attendance_menu.xml b/yuthon_work_brand/views/attendance_menu.xml
index f72609deb..435aee322 100644
--- a/yuthon_work_brand/views/attendance_menu.xml
+++ b/yuthon_work_brand/views/attendance_menu.xml
@@ -75,11 +75,26 @@
name="工程部计划"
parent="hr_attendance_root_board"
sequence="7"/>
-
+
+
+
+