添加功能

This commit is contained in:
zhou
2025-05-06 20:29:08 +08:00
parent 29d64ad042
commit a253b75725
9 changed files with 106 additions and 85 deletions
+3 -2
View File
@@ -491,7 +491,7 @@ class ReportExcel(models.Model):
actual_header_length = len(visible_cols)
# 写入大表头,根据实际显示列数确定合并范围
company_year_month_text = f'员工{data["current_year"]}年{data["current_month"]}工资表({company_name})'
company_year_month_text = f'员工{data["current_year"]}年{data["current_month"]}月工资表({company_name})'
sheet.merge_range(0, 0, 0, actual_header_length - 1, company_year_month_text, title_format)
# 添加单位和日期
@@ -777,6 +777,7 @@ class ReportExcel(models.Model):
chinese_month = month_mapping.get(current_month)
target_name = f"{current_year}年-{chinese_month}"
return [
('is_push', '=', False),
('is_salary_push', '=', True),
('is_salary_release', '=', True),
('payslip_run_id.name', '=', target_name)
]
@@ -37,7 +37,7 @@ class SoongWorkflowRecord(models.Model):
approvals_group_id = fields.Many2one(related='workflow_id.approvals_group_id', string="审批分组", store=True)
department_id = fields.Many2one("hr.department", string="部门", required=True)
done_by = fields.Many2one(comodel_name="res.users", string="发起人")
# is_department_record = fields.Boolean(string="是否是本部门及以下的数据", store=False, search="_search_is_department_record")
is_department_record = fields.Boolean(string="是否是本部门数据", index=True)
active = fields.Boolean(string="归档", default=True)
# def get_department_employees(self, department_id):
+1 -1
View File
@@ -32,7 +32,7 @@
action="soong_workflow_record_action_admin"
sequence="11"/>
<menuitem id="menu_soong_workflow_hr_employee"
name="人力相关流程"
name="人力资源流程"
parent="menu_soong_workflow_root"
action="soong_workflow_hr_employee_action"
sequence="11"/>
@@ -34,6 +34,7 @@
<field name="create_uid"/>
<field name="write_date2"/>
<field name="reclaim_state" column_invisible="1"/>
<field name="is_department_record" optional="hide"/>
<button name="delete_record" type="object" string="删除" class="btn-primary" confirm="你确定要删除吗?"/>
<button name="reminders_record" type="object" string="催办" class="btn-primary"
groups="soong_workflow.group_soong_workflow_manager"/>
@@ -9,8 +9,8 @@
editable="bottom" banner_route="/attendance/banner/route">
<field name="employee_id" class="list_current_data"/>
<field name="current_data" optional="show" class="list_current_data"/>
<field name="check_in" optional="show" widget="time"/>
<field name="check_out" optional="show" widget="time"/>
<field name="check_in" optional="show" widget="time" class="list_current_data"/>
<field name="check_out" optional="show" widget="time" class="list_current_data"/>
<field name="shift_id" optional="hidden"/>
<field name="shift_name" optional="show" class="list_current_data"/>
<field name="create_date" optional="hidden"/>
+14 -2
View File
@@ -76,6 +76,7 @@ class InheritHrPayslip(models.Model):
paid_tax = fields.Float(string='已缴税额')
based_pay = fields.Float(string='临时绩效工资')
life_salary = fields.Float(string='生活补贴')
january_performance = fields.Float(string='1月份绩效奖金补发')
performance_deduction = fields.Float(string='扣发绩效奖金', compute='_compute_deduction', store=True)
commuting_deduction = fields.Float(string='扣发通信补贴', compute='_compute_deduction', store=True)
@@ -205,13 +206,15 @@ class InheritHrPayslip(models.Model):
@api.depends('year_compute', 'year_jie', 'year_gong', 'jing_te', 'study_on', 'post_salary',
'seniority_salary','commuting_allowance', 'base_salary' , 'performance_bonuses',
'full_attendance_award', 'overtime_pay',
'full_attendance_award', 'overtime_pay', 'based_pay', 'january_performance',
'high_temperature_allowance', 'performance_deduction', 'commuting_deduction', 'base_salary_deduction')
def _compute_total_before_tax(self):
for record in self:
record.total_before_tax = (
record.performance_bonuses +
record.commuting_allowance +
record.january_performance +
record.based_pay +
record.base_salary +
record.seniority_salary +
record.post_salary +
@@ -344,8 +347,17 @@ class InheritHrPayslip(models.Model):
def button_salary_print(self):
return {
"type": "ir.actions.act_window",
"name": "导入薪资",
"name": "打印薪资",
"res_model": "salary.print.wizard",
"view_mode": "form",
"target": "new",
}
def open_record(self):
return {
"type": "ir.actions.act_window",
"res_model": 'hr.payslip',
"res_id": self.id,
"name": "薪资详情",
"view_mode": "form",
}
@@ -87,6 +87,9 @@
<field name="model">hr.payslip</field>
<field name="arch" type="xml">
<tree string="薪资发放" default_order="employee_id">
<header>
<button name="button_salary_print" string="打印" type="object" class="oe_highlight"/>
</header>
<field name="employee_id" string="姓名" widget="ztree_select"/>
<field name="date_of_entry"/>
<field name="company_id" string="公司" optional="hide"/>
@@ -250,6 +253,7 @@
<field name="commuting_allowance"/>
<field name="seniority_salary"/>
<field name="full_attendance_award"/>
<field name="january_performance"/>
<field name="overtime_pay" decoration-danger="1"/>
<field name="high_temperature_allowance" decoration-danger="1"/>
<field name="based_pay" decoration-danger="1"/>
@@ -272,6 +276,7 @@
<field name="meal_misunderstanding_fee"/>
<field name="is_push" column_invisible="1"/>
<button name="put_button" string="推送" type="object" class="oe_highlight"/>
<button name="open_record" string="详情" type="object" class="oe_highlight"/>
</tree>
</field>
</record>
+78 -76
View File
@@ -6,7 +6,7 @@ from pypinyin import pinyin, Style
import xlrd
import base64
import datetime
from datetime import datetime
from datetime import datetime, timedelta
class SalaryComputeWizard(models.Model):
@@ -93,92 +93,94 @@ class SalaryComputeWizard(models.Model):
})
payslip.compute_sheet()
internship_ids = self.env['hr.payslip'].search([
('employee_id.name', '=', '王鸿怡'),
('employee_id.contract_id.is_probation', '=', True),
('date_from', '<=', end_date),
('date_to', '>=', start_date)
('date_to', '>=', start_date),
])
if internship_ids:
for internship_id in internship_ids:
start_date = internship_id.date_from
end_date = internship_id.date_to
original_start_date = internship_id.date_from
original_end_date = internship_id.date_to
contract_start_date = internship_id.employee_id.contract_id.start_date
contract_end_date = internship_id.employee_id.contract_id.end_date
if (contract_end_date <= start_date and contract_start_date >= end_date) or (start_date < contract_start_date <= end_date):
if internship_id.line_ids:
target_names = {
'基本工资': 'base_salary',
'职级工资': 'rank_salary',
'岗位工资': 'post_salary',
'预发绩效奖金': 'performance_bonuses',
'通讯补贴': 'commuting_allowance',
'工龄工资': 'seniority_salary'
}
for line in internship_id.line_ids:
if line.name in target_names:
result = line.total * 0.8
field_name = target_names[line.name]
setattr(internship_id, field_name, result)
line.write({'total': result})
elif contract_end_date.year == end_date.year and contract_end_date.month == end_date.month:
leave_days = self._create_leave_record(start_date, end_date)
days = leave_days.number_of_days
leave_days.unlink()
days = self._process_shift_days(days, start_date, end_date) # 总工作日
leave_internship = self._create_leave_record(start_date, contract_end_date)
internship_days = leave_internship.number_of_days
leave_internship.unlink()
internship_days = self._process_shift_days(internship_days, start_date, contract_end_date) # 实习期工作日
leave_work = self._create_leave_record(contract_end_date, end_date)
work_days = leave_work.number_of_days
leave_work.unlink()
work_days = self._process_shift_days(work_days, contract_end_date, end_date) # 转正工作日
if internship_id.line_ids:
target_names = {
'基本工资': 'base_salary',
'职级工资': 'rank_salary',
'岗位工资': 'post_salary',
'预发绩效奖金': 'performance_bonuses',
'通讯补贴': 'commuting_allowance',
'工龄工资': 'seniority_salary'
}
for line in internship_id.line_ids:
if line.name in target_names:
result = line.total * 0.8 * internship_days / days + line.total * 0.8 * work_days / days
field_name = target_names[line.name]
setattr(internship_id, field_name, result)
line.write({'total': result})
days = self._process_shift_days(original_start_date, original_end_date) # 总工作日
# 复制原始日期用于修改
start_date = original_start_date
end_date = original_end_date
# 检查 start_date 是否早于 contract_start_date
if start_date < contract_start_date:
start_date = contract_start_date
internship_days = self._process_shift_days(start_date, end_date) # 实习期工作日
# 重置为原始日期
start_date = original_start_date
end_date = original_end_date
# 检查 end_date 是否晚于 contract_end_date
if end_date > contract_end_date:
end_date = contract_end_date
work_days = self._process_shift_days(start_date, end_date) # 转正工作日
if internship_id.line_ids:
target_names = {
'基本工资': 'base_salary',
'职级工资': 'rank_salary',
'岗位工资': 'post_salary',
'预发绩效奖金': 'performance_bonuses',
'通讯补贴': 'commuting_allowance',
'工龄工资': 'seniority_salary'
}
for line in internship_id.line_ids:
if line.name in target_names:
field_name = target_names[line.name]
if field_name == 'performance_bonuses':
result = 0
elif field_name in ['commuting_allowance', 'seniority_salary']:
if work_days != days:
result = line.total * internship_days / days + line.total * work_days / days
else:
result = line.total * internship_days / days
else:
if work_days != days:
result = line.total * 0.8 * internship_days / days + line.total * work_days / days
else:
result = line.total * 0.8 * internship_days / days
setattr(internship_id, field_name, result)
line.write({'total': result})
def _get_chinese_month(self, month):
chinese_months = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
return chinese_months[month - 1]
# 创建用户记录传入日期来获取天数(自然日中工作日的逻辑)
def _create_leave_record(self, start_date, end_date):
holiday_status_id = self.env['hr.leave.type'].search([('name', '=', '年假')])
admin_id = self.env['hr.employee'].search([("name", "=", 'Administrator')])
return self.env['hr.leave'].sudo().create({
'employee_id': admin_id.id,
'holiday_status_id': holiday_status_id.id,
'request_date_from': start_date,
'request_date_to': end_date,
'state': 'confirm',
})
def _process_shift_days(self, start_date, end_date):
calendar_leaves = self.env['resource.calendar.leaves'].search([("calendar_id", "=", "行政考勤工作日")])
holidays_list = []
shift_days_list = []
for leaves in calendar_leaves:
if leaves.holidays:
holidays_list.extend(leaves.holidays.split(','))
if leaves.alternate_rest_day:
holidays_list.extend(leaves.alternate_rest_day.split(','))
if leaves.shift_replacement_day:
shift_days_list.extend(leaves.shift_replacement_day.split(','))
days = (end_date - start_date).days + 1
current_date = start_date
while current_date <= end_date:
current_date_str = current_date.strftime('%m月%d日')
current_date_str = self.remove_leading_zero(current_date_str)
is_weekend = current_date.weekday() in [5, 6]
if current_date_str in holidays_list:
days -= 1
elif current_date_str in shift_days_list:
if not is_weekend:
days += 1
elif is_weekend:
days -= 1
current_date += timedelta(days=1)
return days
# 行政考勤 调休日期
def _process_shift_days(self, days, start_date, end_date):
calendar_leaves = self.env['resource.calendar.leaves'].search([])
all_days = []
for calendar in calendar_leaves:
shift_days = calendar.shift_replacement_day.split(',') if calendar.shift_replacement_day else []
for day_str in shift_days:
day = datetime.strptime(day_str, '%m月%d日')
day = day.replace(year=start_date.year).date()
all_days.append(day)
unique_days = list(set(all_days))
total_days = days
for day in unique_days:
if start_date <= day <= end_date:
total_days += 1
return total_days
def remove_leading_zero(self, date_str):
month, day = date_str.split('月')
month = month.lstrip('0')
day = day.rstrip('日')
day = day.lstrip('0')
return f'{month}月{day}日'
@@ -5,7 +5,7 @@
<button type="button" class="btn btn-primary" style="margin-left: 10px;" t-on-click="openTaskForm">
新建日程
</button>
<button type="button" class="btn btn-primary" style="margin-left: 10px;" t-on-click="openMeetingArrangementForm">
<button type="button" class="btn btn-primary" style="margin-left: 10px;" t-on-click="openMeetForm">
新建会议
</button>
</xpath>