添加功能
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user