Files
gzth/yuthon_hr_attendance/models/yuthon_run_planning.py
T
2025-04-30 15:26:23 +08:00

350 lines
20 KiB
Python

from odoo import api, fields, models, tools, _
from datetime import datetime, time, timedelta
from odoo.exceptions import UserError
from datetime import date, timedelta
class YuthonRunPlanning(models.Model):
_name = 'yuthon.run.planning'
_description = '工程部排班计划'
name = fields.Char(string='排班计划名称', required=True)
illustrate = fields.Char(string='排班说明', default='默认轮排到下个月')
engineering_run_ids = fields.One2many('yuthon.engineering.run.line', 'engineering_planning_id', string='关联运行班排班明细')
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='关联其他明细')
department_id = fields.Many2one("hr.department", string="部门", required=True)
start_date = fields.Date(string='生效日期', default=fields.Datetime.today())
end_date = fields.Date(string='失效日期')
def action_planning_wizard_run(self):
return {
"type": "ir.actions.act_window",
"name": "删除运行班计划弹窗",
"res_model": "yuthon.run.wizard",
"view_mode": "form",
"target": "new",
}
def action_planning_wizard_high(self):
return {
"type": "ir.actions.act_window",
"name": "删除高压班计划弹窗",
"res_model": "yuthon.high.wizard",
"view_mode": "form",
"target": "new",
}
def action_planning_wizard_integrated(self):
return {
"type": "ir.actions.act_window",
"name": "删除综合班计划弹窗",
"res_model": "yuthon.integrated.wizard",
"view_mode": "form",
"target": "new",
}
# 运行班
def run_confirm(self):
selected_month = self.start_date.month
year = datetime.now().year
first_day_of_month = datetime(year, selected_month, 1)
# 计算结束日期(当月的最后一天)
next_month = (selected_month % 12) + 1
next_year = year + (1 if next_month == 1 else 0)
last_day_of_month = datetime(next_year, next_month, 1) - timedelta(days=1)
existing_slots = self.env['planning.slot'].search([
('department_id.name', '=', '运行班'),
('start_datetime', '>=', first_day_of_month),
('start_datetime', '<=', last_day_of_month),
])
if len(existing_slots) > 0:
raise UserError(f"该月已经有排程,请选择其他时间。")
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.sorted('sequence'):
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) - timedelta(days=1),
'end_datetime': datetime(current_date.year, current_date.month, current_date.day, end_time) + timedelta(hours=16) - timedelta(days=1),
'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)
current_date = first_day_of_month
all_slot = self.env['planning.slot'].search([('department_id.name', '=', '运行班'), ('start_datetime', '>=', first_day_of_month), ('start_datetime', '<=', last_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),('start_datetime', '>=', first_day_of_month),('start_datetime', '<=', last_day_of_month)]).sorted('start_datetime')
if i < 31:
slot_id[i].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) - timedelta(days=1),
'end_datetime': datetime(current_date.year, current_date.month, current_date.day,end_time2) + timedelta(hours=16) - timedelta(days=1),
'role_id': role_a.id,
'allocated_hours': 8,
})
if i + 1 < len(slot_id):
slot_id[i + 1].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_time) + timedelta(days=1, hours=16) - timedelta(days=1),
'end_datetime': datetime(current_date.year, current_date.month, current_date.day,end_time) + timedelta(days=1, hours=16) - timedelta(days=1),
'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:
if other.employee_id:
other_resource_id = other.employee_id.resource_id
regular_holiday = other.regular_holidays
weekday_mapping = {
'one': 7, 'two': 1, 'three':2, 'four': 3, 'five': 4, 'six': 5, 'seven': 6
}
weekday_number = weekday_mapping.get(regular_holiday)
other_data[other_resource_id.id] = weekday_number
for employee in self.other_run_ids:
current_date = first_day_of_month
while current_date <= last_day_of_month:
resource_id = employee.employee_id.resource_id
if not other_data[resource_id.id] == datetime(current_date.year, current_date.month,current_date.day).weekday():
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)- timedelta(days=1),
'end_datetime': datetime(current_date.year, current_date.month, current_date.day,end_time) + timedelta(hours=16)- timedelta(days=1),
'display_sequence': employee.sequence,
'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 high_confirm(self):
selected_month = self.start_date.month
year = datetime.now().year
first_day_of_month = datetime(year, selected_month, 1)
# 计算结束日期(下个月的第一天)
next_month = (selected_month % 12) + 1
next_year = year + (1 if next_month == 1 else 0) # 如果是12月,年份加1
last_day_of_month = datetime(next_year, next_month, 1) - timedelta(days=1)
existing_slots = self.env['planning.slot'].search([
('department_id.name', '=', '高压班'),
('start_datetime', '>=', first_day_of_month),
('start_datetime', '<=', last_day_of_month),
])
if len(existing_slots) > 0:
raise UserError(f"该月已经有排程,请选择其他时间。")
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)- timedelta(days=1),
'end_datetime': datetime(current_date.year, current_date.month, current_date.day,end_time) + timedelta(hours=16)- timedelta(days=1),
'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)
current_date = first_day_of_month
all_slot = self.env['planning.slot'].search([('department_id.name', '=', '高压班'), ('start_datetime', '>=', first_day_of_month),('start_datetime', '<=', last_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), ('start_datetime', '>=', first_day_of_month), ('start_datetime', '<=', last_day_of_month)]).sorted('start_datetime')
if i < 31:
slot_id[i].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) - timedelta(days=1),
'end_datetime': datetime(current_date.year, current_date.month, current_date.day,end_time2) + timedelta(hours=16) - timedelta(days=1),
'role_id': role_a.id,
'allocated_hours': 8,
})
if i + 1 < len(slot_id):
slot_id[i + 1].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_time) + timedelta(days=1, hours=16) - timedelta(days=1),
'end_datetime': datetime(current_date.year, current_date.month, current_date.day,end_time) + timedelta(days=1, hours=16) - timedelta(days=1),
'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):
selected_month = self.start_date.month
year = datetime.now().year
first_day_of_month = datetime(year, selected_month, 1)
# 计算结束日期(下个月的第一天)
next_month = (selected_month % 12) + 1
next_year = year + (1 if next_month == 1 else 0) # 如果是12月,年份加1
last_day_of_month = datetime(next_year, next_month, 1)- timedelta(days=1)
existing_slots = self.env['planning.slot'].search([
('department_id.name', '=', '综合班'),
('start_datetime', '>=', first_day_of_month),
('start_datetime', '<=', last_day_of_month),
])
if len(existing_slots) > 0:
raise UserError(f"该月已经有排程,请选择其他时间。")
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) - timedelta(days=1),
'end_datetime': datetime(current_date.year, current_date.month, current_date.day,end_time) + timedelta(hours=16)- timedelta(days=1),
'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)
current_date = first_day_of_month
all_slot = self.env['planning.slot'].search(
[('department_id.name', '=', '综合班'), ('start_datetime', '>=', first_day_of_month),
('start_datetime', '<=', last_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), ('start_datetime', '>=', first_day_of_month), ('start_datetime', '<=', last_day_of_month)]).sorted('start_datetime')
if i < 31:
slot_id[i].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) - timedelta(days=1),
'end_datetime': datetime(current_date.year, current_date.month, current_date.day,end_time2) + timedelta(hours=16) - timedelta(days=1),
'role_id': role_a.id,
'allocated_hours': 8,
})
if i + 1 < len(slot_id):
slot_id[i + 1].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_time) + timedelta(days=1, hours=16) - timedelta(days=1),
'end_datetime': datetime(current_date.year, current_date.month, current_date.day,
end_time) + timedelta(days=1, hours=16) - timedelta(days=1),
'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 _get_default_month(self):
current_month = datetime.now().month
return str(current_month)
class YuthonEngineeringRunLine(models.Model):
_name = 'yuthon.engineering.run.line'
_description = '运行班计划明细'
employee_id = fields.Many2one('hr.employee', string='人员',domain=lambda self: [('department_id.name', '=', '运行班')])
sequence = fields.Integer(string='序号')
engineering_planning_id = fields.Many2one('yuthon.run.planning', string='关联工程部排班计划')
class YuthonHighRunLine(models.Model):
_name = 'yuthon.high.run.line'
_description = '高压班计划明细'
employee_id = fields.Many2one('hr.employee', string='人员', domain=lambda self: [('department_id.name', '=', '高压班')])
sequence = fields.Integer(string='序号')
engineering_planning_id = fields.Many2one('yuthon.run.planning', string='关联工程部排班计划')
class YuthonAllRunLine(models.Model):
_name = 'yuthon.all.run.line'
_description = '综合班计划明细'
employee_id = fields.Many2one('hr.employee', string='人员', domain=lambda self: [('department_id.name', '=', '综合班')])
sequence = fields.Integer(string='序号')
engineering_planning_id = fields.Many2one('yuthon.run.planning', string='关联工程部排班计划')
class YuthonOtherLine(models.Model):
_name = 'yuthon.other.line'
_description = '其他'
regular_holidays = fields.Selection([('one', '星期一'), ('two', '星期二'), ('three', '星期三'),
('four', '星期四'), ('five', '星期五'), ('six', '星期六'),
('seven', '星期日')], string='固定休息日')
employee_id = fields.Many2one('hr.employee', string='人员',
domain=lambda self: [('department_id.name', 'in', ['运行班'])])
sequence = fields.Integer(string='序号')
engineering_planning_id = fields.Many2one('yuthon.run.planning', string='关联工程部排班计划')