!6782 添加功能

Merge pull request !6782 from 李鹏宇/dev_zhou
This commit is contained in:
李鹏宇
2025-12-02 02:45:03 +00:00
committed by Gitee
7 changed files with 154 additions and 62 deletions
@@ -298,6 +298,34 @@
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
</record>
<record forcecreate="True" id="executive_day_remind_in" model="ir.cron">
<field name="name">定时任务:行政班次上班打卡提醒</field>
<field name="model_id" ref="model_hr_attendance"/>
<field name="state">code</field>
<field name="code">model.executive_day_remind_in()</field>
<field eval="True" name="active"/>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="nextcall" eval="(DateTime.now() + timedelta(days=1)).strftime('%Y-%m-%d 17:00:00')"/>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
</record>
<record forcecreate="True" id="executive_day_remind_out" model="ir.cron">
<field name="name">定时任务:行政班次下班打卡提醒</field>
<field name="model_id" ref="model_hr_attendance"/>
<field name="state">code</field>
<field name="code">model.executive_day_remind_out()</field>
<field eval="True" name="active"/>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="nextcall" eval="(DateTime.now() + timedelta(days=1)).strftime('%Y-%m-%d 17:00:00')"/>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
</record>
</data>
</odoo>
+2 -2
View File
@@ -2,7 +2,7 @@
<odoo>
<data>
<record forcecreate="True" id="card_lc_shift_remind_time_on_administrative" model="ir.cron">
<field name="name">定时任务:计划行政上班提醒</field>
<field name="name">定时任务:保安部计划行政上班提醒</field>
<field name="model_id" ref="model_hr_attendance"/>
<field name="state">code</field>
<field name="code">model.card_lc_shift_remind_on_administrative()</field>
@@ -16,7 +16,7 @@
</record>
<record forcecreate="True" id="card_lc_shift_remind_time_out_administrative" model="ir.cron">
<field name="name">定时任务:计划行政下班提醒</field>
<field name="name">定时任务:保安部计划行政下班提醒</field>
<field name="model_id" ref="model_hr_attendance"/>
<field name="state">code</field>
<field name="code">model.card_lc_shift_remind_out_administrative()</field>
+42 -19
View File
@@ -791,7 +791,7 @@ class HrAttendance(models.Model):
else:
record.week = False
def _common_card_remind(self, dept_name=None, planning_name=None, is_check_in=True, method_name=None):
def _common_card_remind(self, dept_name=None, planning_name=None, is_check_in=True, method_name=None, is_executive=False):
"""通用打卡提醒函数"""
if not method_name:
return
@@ -803,24 +803,38 @@ class HrAttendance(models.Model):
end_window = next_call + timedelta(minutes=5)
if not (start_window <= fields.Datetime.now() + timedelta(hours=8) <= end_window):
return
slot_start = datetime.combine(current_date, datetime.min.time())
slot_end = datetime.combine(current_date + timedelta(days=1), datetime.min.time())
domain = [
('template_id.planning_name', '=', planning_name),
('start_datetime', '>=', slot_start),
('start_datetime', '<', slot_end),
('role_id.name', '=', dept_name),
]
planning_slots = self.env['planning.slot'].search(domain)
for slot in planning_slots:
if is_check_in:
is_card = self.env['hr.attendance'].search([('employee_id', '=', slot.employee_id.id), ('check_in', '!=', False), ('current_data', '=', current_date)], limit=1)
if not is_card:
self.card_in_comment(slot.employee_id, planning_name)
else:
is_card = self.env['hr.attendance'].search([('employee_id', '=', slot.employee_id.id), ('check_out', '!=', False), ('current_data', '=', current_date)], limit=1)
if not is_card:
self.card_out_comment(slot.employee_id, planning_name)
if is_executive:
domain = [('current_data', '=', current_date)]
attendances = self.env['hr.attendance'].search(domain)
attended_employee_ids = attendances.mapped('employee_id')
for employee in attended_employee_ids:
if is_check_in:
is_card = self.env['hr.attendance'].search([('employee_id', '=', employee.id), ('check_in', '!=', False), ('current_data', '=', current_date)], limit=1)
if not is_card:
self.card_in_comment(employee, '行政班次')
else:
is_card = self.env['hr.attendance'].search([('employee_id', '=', employee.id), ('check_out', '!=', False), ('current_data', '=', current_date)], limit=1)
if not is_card:
self.card_out_comment(employee, '行政班次')
else:
slot_start = datetime.combine(current_date, datetime.min.time())
slot_end = datetime.combine(current_date + timedelta(days=1), datetime.min.time())
domain = [
('template_id.planning_name', '=', planning_name),
('start_datetime', '>=', slot_start),
('start_datetime', '<', slot_end),
('role_id.name', '=', dept_name),
]
planning_slots = self.env['planning.slot'].search(domain)
for slot in planning_slots:
if is_check_in:
is_card = self.env['hr.attendance'].search([('employee_id', '=', slot.employee_id.id), ('check_in', '!=', False), ('current_data', '=', current_date)], limit=1)
if not is_card:
self.card_in_comment(slot.employee_id, planning_name)
else:
is_card = self.env['hr.attendance'].search([('employee_id', '=', slot.employee_id.id), ('check_out', '!=', False), ('current_data', '=', current_date)], limit=1)
if not is_card:
self.card_out_comment(slot.employee_id, planning_name)
# 保安部 - 早班
def ba_card_white_up(self):
@@ -939,6 +953,15 @@ class HrAttendance(models.Model):
self._common_card_remind(dept_name='保安部', planning_name='保安计划行政', is_check_in=False,
method_name='card_lc_shift_remind_out_administrative')
# 行政班次
def executive_day_remind_in(self):
self._common_card_remind(planning_name='行政班次', is_check_in=True,
method_name='executive_day_remind_in', is_executive=True)
def executive_day_remind_out(self):
self._common_card_remind(planning_name='行政班次', is_check_in=False,
method_name='executive_day_remind_out', is_executive=True)
def card_in_comment(self, employee_id, planning_name):
data = f"您的班次是{planning_name},还有5分钟上班,记得打卡"
url = '#小程序://天投云/XttsPpKg3MEpY7h'
@@ -17,7 +17,18 @@ class YuthonRunPlanning(models.Model):
department_id = fields.Many2one("hr.department", string="部门", required=True)
start_date = fields.Date(string='生效日期', default=fields.Datetime.today())
end_date = fields.Date(string='失效日期')
is_effect = fields.Boolean(string="是否生效", compute="_compute_is_effect")
@api.depends('start_date', 'end_date')
def _compute_is_effect(self):
today = fields.Date.today()
for record in self:
if not record.start_date:
record.is_effect = False
elif not record.end_date:
record.is_effect = record.start_date <= today
else:
record.is_effect = record.start_date <= today <= record.end_date
def action_planning_wizard_run(self):
return {
@@ -48,20 +59,25 @@ class YuthonRunPlanning(models.Model):
# 运行班
def run_confirm(self):
selected_month = self.start_date.month
year = datetime.now().year
first_day_of_month = datetime(year, selected_month, 1)
latest_slot = self.env['planning.slot'].search([
('department_id.name', '=', '运行班')
], order='start_datetime desc', limit=1)
# 从最新排班中提取年/月
latest_datetime = latest_slot.start_datetime
latest_year = latest_datetime.year
latest_month = latest_datetime.month
# 计算下个月的年/月
target_month = latest_month + 1
target_year = latest_year
if target_month > 12:
target_month = 1
target_year += 1
first_day_of_month = datetime(target_year, target_month, 1)
# 计算结束日期(当月的最后一天)
next_month = (selected_month % 12) + 1
next_year = year + (1 if next_month == 1 else 0)
next_month = target_month % 12 + 1
next_year = target_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)
@@ -147,20 +163,25 @@ class YuthonRunPlanning(models.Model):
}
# 高压班
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([
latest_slot = 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"该月已经有排程,请选择其他时间。")
], order='start_datetime desc', limit=1)
# 从最新排班中提取年/月
latest_datetime = latest_slot.start_datetime
latest_year = latest_datetime.year
latest_month = latest_datetime.month
# 计算下个月的年/月
target_month = latest_month + 1
target_year = latest_year
if target_month > 12:
target_month = 1
target_year += 1
first_day_of_month = datetime(target_year, target_month, 1)
# 计算结束日期(当月的最后一天)
next_month = target_month % 12 + 1
next_year = target_year + (1 if next_month == 1 else 0)
last_day_of_month = datetime(next_year, next_month, 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)
@@ -220,20 +241,25 @@ class YuthonRunPlanning(models.Model):
}
# 综合班
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([
latest_slot = 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"该月已经有排程,请选择其他时间。")
], order='start_datetime desc', limit=1)
# 从最新排班中提取年/月
latest_datetime = latest_slot.start_datetime
latest_year = latest_datetime.year
latest_month = latest_datetime.month
# 计算下个月的年/月
target_month = latest_month + 1
target_year = latest_year
if target_month > 12:
target_month = 1
target_year += 1
first_day_of_month = datetime(target_year, target_month, 1)
# 计算结束日期(当月的最后一天)
next_month = target_month % 12 + 1
next_year = target_year + (1 if next_month == 1 else 0)
last_day_of_month = datetime(next_year, next_month, 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)
@@ -20,7 +20,7 @@
<form string="排版规则" create="0">
<sheet>
<header>
<button name="run_confirm" type="object" string="排班" class="oe_highlight"/>
<button name="run_confirm" type="object" string="排班" class="oe_highlight" invisible="not is_effect"/>
<button name="action_planning_wizard_run" type="object" string="删除排班" class="oe_highlight"/>
</header>
<group>
@@ -73,7 +73,7 @@
<form string="排版规则">
<sheet>
<header>
<button name="integrated_confirm" type="object" string='排班' class="oe_highlight"/>
<button name="integrated_confirm" type="object" string='排班' class="oe_highlight" invisible="not is_effect"/>
<button name="action_planning_wizard_integrated" type="object" string="删除排班" class="oe_highlight"/>
</header>
<group>
@@ -115,7 +115,7 @@
<form string="排版规则">
<sheet>
<header>
<button name="high_confirm" type="object" string="排班" class="oe_highlight"/>
<button name="high_confirm" type="object" string="排班" class="oe_highlight" invisible="not is_effect"/>
<button name="action_planning_wizard_high" type="object" string="删除排班" class="oe_highlight"/>
</header>
<group>
@@ -185,6 +185,20 @@ class PropertyBankStatements(models.Model):
lessee_ids = fields.Many2many('property.tenant.information', string='承租方', compute="_compute_property_employee_id", store=True)
admin_id = fields.Many2one('res.users', string="片区管理员", compute="_compute_property_employee_id", store=True)
def write_off_details(self):
self.ensure_one()
modify_lines = self.env['receivable.modify.line'].search([
('bank_id', '=', self.id)
])
receivable_ids = modify_lines.mapped('receivable_id').filtered(lambda r: r.id)
return {
'type': 'ir.actions.act_window',
'res_model': 'property.accounts.receivable',
'view_mode': 'tree',
'view_id': self.env.ref('yuthon_property.view_property_accounts_receivable_tree').id,
'domain': [('id', 'in', receivable_ids.ids)],
}
@api.depends('name')
def _compute_property_employee_id(self):
for record in self:
@@ -668,6 +668,7 @@
<field name="arch" type="xml">
<xpath expr="//field[@name='bank_state']" position="after">
<button name="revocation" type="object" class="btn btn-primary" string="撤销" invisible="bank_state == 'not_reconciled'"/>
<button name="write_off_details" type="object" class="btn btn-primary" string="核销详情" invisible="bank_state == 'not_reconciled'"/>
</xpath>
</field>
</record>