@@ -3,6 +3,7 @@ import datetime
|
||||
import calendar
|
||||
from odoo import api, fields, models, tools, _
|
||||
from odoo.tools.float_utils import float_round
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
|
||||
class HrAttendanceYear(models.Model):
|
||||
@@ -95,7 +96,6 @@ class HrAttendanceMonthDetail(models.Model):
|
||||
actual_attendance_days = fields.Integer(string="实际出勤天数")
|
||||
compensatory_leave = fields.Integer(string="调休")
|
||||
leave_of_absence = fields.Integer(string="事假")
|
||||
leave_of_sick = fields.Integer(string="病假")
|
||||
statutory_leave = fields.Integer(string="法定假")
|
||||
work_overtime = fields.Integer(string="加班")
|
||||
entry_date = fields.Date(related='employee_id.open_start_time', string="入职日期")
|
||||
@@ -106,6 +106,7 @@ class HrAttendanceMonthDetail(models.Model):
|
||||
marriage_leave = fields.Float(string='婚假')
|
||||
general_off_leave = fields.Float(string='调休')
|
||||
maternity_leave = fields.Float(string='产假')
|
||||
paternity_leave = fields.Float(string='陪产假')
|
||||
family_planning_leave = fields.Float(string='计生假')
|
||||
bereavement_leave = fields.Float(string='丧假')
|
||||
home_visit_leave = fields.Float(string='探亲假')
|
||||
@@ -412,8 +413,99 @@ class HrAttendanceMonthDetail(models.Model):
|
||||
}
|
||||
|
||||
def button_confirm(self):
|
||||
current_employee = self.env['hr.employee'].search([('user_id', '=', self.env.user.id)], limit=1)
|
||||
for record in self:
|
||||
record.state = 'confirmed'
|
||||
current_year = record.current_year
|
||||
current_month = int(record.current_month)
|
||||
|
||||
# 计算该月的天数
|
||||
if current_month in [1, 3, 5, 7, 8, 10, 12]:
|
||||
month_days = 31
|
||||
elif current_month in [4, 6, 9, 11]:
|
||||
month_days = 30
|
||||
elif current_month == 2:
|
||||
if (int(current_year) % 4 == 0 and int(current_year) % 100 != 0) or (int(current_year) % 400 == 0):
|
||||
month_days = 29
|
||||
else:
|
||||
month_days = 28
|
||||
# 日期拼接
|
||||
payslip_start_date = datetime.date(int(current_year), current_month, 1)
|
||||
payslip_end_date = datetime.date(int(current_year), current_month, month_days)
|
||||
|
||||
payslip_record = self.env['hr.payslip'].search([
|
||||
('employee_id', '=', current_employee.id),
|
||||
('date_from', '>=', payslip_start_date),
|
||||
('date_to', '<=', payslip_end_date)
|
||||
])
|
||||
if payslip_record:
|
||||
# 初始值
|
||||
base_deduction = 0
|
||||
performance_deduction = 0
|
||||
commuting_deduction = 0
|
||||
# 获取当前人员的 对应的月份的基本薪资 绩效奖金 和 通信补贴
|
||||
base_salary = payslip_record.base_salary
|
||||
performance_bonuses = payslip_record.performance_bonuses
|
||||
commuting_allowance = payslip_record.commuting_allowance
|
||||
|
||||
# 普通病假
|
||||
common_sick_leave = record.general_sick_leave
|
||||
base_deduction += common_sick_leave * base_salary * 0.01
|
||||
performance_deduction += (performance_bonuses / 21.75) * common_sick_leave
|
||||
|
||||
# 住院恢复期
|
||||
hospital_recovery_leave = record.recovery_sick_leave
|
||||
base_deduction += hospital_recovery_leave * base_salary * 0.01
|
||||
performance_deduction += (performance_bonuses / 21.75) * hospital_recovery_leave
|
||||
|
||||
# 住院假
|
||||
hospital_leave = record.hospital_sick_leave
|
||||
performance_deduction += (performance_bonuses / 21.75) * hospital_leave
|
||||
|
||||
# 事假
|
||||
personal_leave = record.leave_of_absence
|
||||
base_deduction += personal_leave * base_salary * 0.025
|
||||
performance_deduction += (performance_bonuses / 21.75) * personal_leave
|
||||
|
||||
# 产假
|
||||
maternity_leave = record.maternity_leave
|
||||
commuting_deduction += (commuting_allowance / month_days) * maternity_leave
|
||||
performance_deduction += (performance_bonuses / month_days) * maternity_leave
|
||||
|
||||
# 陪产假
|
||||
paternity_leave = record.paternity_leave
|
||||
commuting_deduction += (commuting_allowance / month_days) * paternity_leave
|
||||
performance_deduction += (performance_bonuses / month_days) * paternity_leave
|
||||
|
||||
# 计生假
|
||||
family_planning_leave = record.family_planning_leave
|
||||
commuting_deduction += (commuting_allowance / month_days) * family_planning_leave
|
||||
performance_deduction += (performance_bonuses / month_days) * family_planning_leave
|
||||
|
||||
# 丧假
|
||||
bereavement_leave = record.bereavement_leave
|
||||
performance_deduction += (performance_bonuses / 21.75) * bereavement_leave
|
||||
|
||||
# 探亲假
|
||||
home_visit_leave = record.home_visit_leave
|
||||
performance_deduction += (performance_bonuses / 21.75) * home_visit_leave
|
||||
|
||||
# 婚假
|
||||
marriage_leave = record.marriage_leave
|
||||
performance_deduction += (performance_bonuses / 21.75) * marriage_leave
|
||||
|
||||
# 考试假
|
||||
exam_leave = record.exam_leave
|
||||
performance_deduction += (performance_bonuses / 21.75) * exam_leave
|
||||
|
||||
# 家长会假
|
||||
parents_meeting_leave = record.parents_meeting_leave
|
||||
performance_deduction += (performance_bonuses / 21.75) * parents_meeting_leave
|
||||
|
||||
current_employee.write({
|
||||
'last_month_base_salary_deduction': base_deduction,
|
||||
'last_month_performance_deduction': performance_deduction,
|
||||
'last_month_commuting_deduction': commuting_deduction
|
||||
})
|
||||
|
||||
def _get_attendance_month_obj(self):
|
||||
"""
|
||||
|
||||
@@ -7,7 +7,6 @@ class YuthonHrEmployee(models.Model):
|
||||
_inherit = "hr.employee"
|
||||
|
||||
user_role_ids_changed = fields.Boolean(compute='_compute_user_roles')
|
||||
last_attendance = fields.Boolean(string="上月全勤", compute='_compute_last_attendance', store=True)
|
||||
|
||||
@api.depends('user_role_ids')
|
||||
def _compute_user_roles(self):
|
||||
@@ -33,30 +32,4 @@ class YuthonHrEmployee(models.Model):
|
||||
# 未知因素屏蔽选择值
|
||||
group.write({'users': [(4, employee.user_id.id)]})
|
||||
self.user_role_ids = old_users_ids
|
||||
self.user_role_ids_changed = True
|
||||
|
||||
@api.depends('name')
|
||||
def _compute_last_attendance(self):
|
||||
for record in self:
|
||||
today = datetime.today()
|
||||
first_day_of_last_month = today.replace(day=1) - relativedelta(months=1)
|
||||
last_day_of_last_month = first_day_of_last_month.replace(day=28) + relativedelta(days=4)
|
||||
last_day_of_last_month = last_day_of_last_month - relativedelta(days=last_day_of_last_month.day)
|
||||
attendance_records = self.env['hr.attendance'].search([
|
||||
('employee_id', '=', record.id),
|
||||
('check_in', '>=', first_day_of_last_month),
|
||||
('check_in', '<=', last_day_of_last_month)
|
||||
])
|
||||
has_abnormal = True
|
||||
if attendance_records:
|
||||
for attendance in attendance_records:
|
||||
if (
|
||||
attendance.is_no_card or
|
||||
attendance.is_early_card or
|
||||
attendance.is_late_card or
|
||||
attendance.is_abnormal or
|
||||
attendance.absenteeism_card
|
||||
):
|
||||
has_abnormal = False
|
||||
break
|
||||
record.last_attendance = has_abnormal
|
||||
self.user_role_ids_changed = True
|
||||
@@ -85,6 +85,7 @@
|
||||
<field name="marriage_leave"/>
|
||||
<field name="general_off_leave"/>
|
||||
<field name="maternity_leave"/>
|
||||
<field name="paternity_leave"/>
|
||||
<field name="family_planning_leave"/>
|
||||
<field name="bereavement_leave"/>
|
||||
<field name="home_visit_leave"/>
|
||||
@@ -218,7 +219,6 @@
|
||||
<group>
|
||||
<field name="compensatory_leave"/>
|
||||
<field name="leave_of_absence"/>
|
||||
<field name="leave_of_sick"/>
|
||||
<field name="come_late"/>
|
||||
<field name="work_overtime"/>
|
||||
<field name="statutory_leave"/>
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_inherit_hr_employee_form" model="ir.ui.view">
|
||||
<field name="name">hr.employee.form</field>
|
||||
<field name="model">hr.employee</field>
|
||||
<field name="inherit_id" ref="hr.view_employee_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='is_salary']" position="after">
|
||||
<field name="last_attendance" readonly="0"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -167,6 +167,16 @@ class HrAttendanceMonthWizard(models.TransientModel):
|
||||
'事假': 'unpaid_leave',
|
||||
'补休': 'cop_leave',
|
||||
'产假': 'maternity_leave',
|
||||
'病假(普通)': 'general_sick_leave',
|
||||
'病假(住院期)': 'hospital_sick_leave',
|
||||
'病假(出院恢复期)': 'recovery_sick_leave',
|
||||
'陪产假': 'paternity_leave',
|
||||
'计生假': 'family_planning_leave',
|
||||
'丧假': 'bereavement_leave',
|
||||
'探亲假' : 'home_visit_leave',
|
||||
'婚假': 'marriage_leave',
|
||||
'考试假': 'exam_leave',
|
||||
'家长会假': 'parents_meeting_leave',
|
||||
}
|
||||
leave_days = {}
|
||||
year = int(self.current_year)
|
||||
@@ -204,5 +214,3 @@ class HrAttendanceMonthWizard(models.TransientModel):
|
||||
for field_name, days in leave_days.items():
|
||||
setattr(attendance_detail, leave_types[field_name], days)
|
||||
setattr(attendance_detail, 'work_overtime', all_overtime_hours)
|
||||
|
||||
# return result
|
||||
@@ -166,64 +166,14 @@ class YuthonHrEmployee(models.Model):
|
||||
social_base_on = fields.Float(string="1-6月社保薪资基数")
|
||||
social_base_off = fields.Float(string="7-12月社保薪资基数")
|
||||
is_salary = fields.Boolean(string="是否薪资计算", default=True)
|
||||
last_month_attendance_deduction = fields.Float(string="上月考勤扣款")
|
||||
last_month_base_salary_deduction = fields.Float(string="上月基本薪资扣款")
|
||||
last_month_performance_deduction = fields.Float(string="上月绩效扣款", compute='_compute_last_month_deductions')
|
||||
last_month_commuting_deduction = fields.Float(string='上月通信扣款', compute='_compute_last_month_deductions')
|
||||
commuting = fields.Float(string='通信补贴', compute='_compute_employee_salary')
|
||||
performance = fields.Float(string='绩效奖金', compute='_compute_employee_salary')
|
||||
last_month_performance_deduction = fields.Float(string="上月绩效扣款")
|
||||
last_month_commuting_deduction = fields.Float(string='上月通信扣款')
|
||||
medical_insurance_base = fields.Float(string='基本医疗费基数', compute='_compute_insurance_bases')
|
||||
pension_insurance_base = fields.Float(string='基本养老费基数', compute='_compute_insurance_bases')
|
||||
work_injury_insurance_base = fields.Float(string='工伤保险费基数', compute='_compute_insurance_bases')
|
||||
housing_fund_base = fields.Float(string='住房公积金基数', compute='_compute_insurance_bases')
|
||||
|
||||
def _compute_employee_salary(self):
|
||||
for record in self:
|
||||
# 获取上个月的时间范围
|
||||
now = datetime.now()
|
||||
last_month_start = (now.replace(day=1) - relativedelta(months=1))
|
||||
last_month_end = last_month_start + relativedelta(day=31)
|
||||
payslip_record = self.env['hr.payslip'].search([
|
||||
('employee_id', '=', record.id),
|
||||
('date_from', '>=', last_month_start),
|
||||
('date_to', '<=', last_month_end)
|
||||
])
|
||||
if payslip_record:
|
||||
record.commuting = payslip_record.commuting_allowance
|
||||
record.performance = payslip_record.performance_bonuses
|
||||
else:
|
||||
record.commuting = 0
|
||||
record.performance = 0
|
||||
|
||||
@api.depends('commuting', 'performance')
|
||||
def _compute_last_month_deductions(self):
|
||||
today = datetime.today()
|
||||
last_month = today - relativedelta(months=1)
|
||||
last_month_year = str(last_month.year)
|
||||
last_month_month = str(last_month.month)
|
||||
for record in self:
|
||||
# 查找上个月的考勤月度明细记录
|
||||
attendance_record = self.env['hr.attendance.month.detail'].search([
|
||||
('employee_id', '=', record.id),
|
||||
('current_year', '=', last_month_year),
|
||||
('current_month', '=', last_month_month)
|
||||
])
|
||||
if attendance_record:
|
||||
# 计算总产假天数
|
||||
maternity_leave = attendance_record.maternity_leave
|
||||
# 计算月天数
|
||||
if last_month.month in [1, 3, 5, 7, 8, 10, 12]:
|
||||
end_day = 31
|
||||
elif last_month.month in [4, 6, 9, 11]:
|
||||
end_day = 30
|
||||
elif (last_month.month % 4 == 0 and last_month.year % 100 != 0) or (last_month.year % 400 == 0):
|
||||
end_day = 29
|
||||
else:
|
||||
end_day = 28
|
||||
|
||||
# 计算扣款
|
||||
record.last_month_commuting_deduction = record.commuting / end_day * maternity_leave
|
||||
record.last_month_performance_deduction = record.performance / end_day * maternity_leave
|
||||
last_attendance = fields.Boolean(string="上月全勤", store=True)
|
||||
|
||||
@api.depends('social_base_on', 'social_base_off')
|
||||
def _compute_insurance_bases(self):
|
||||
@@ -250,6 +200,7 @@ class YuthonHrEmployee(models.Model):
|
||||
else:
|
||||
setattr(record, field_name, base)
|
||||
|
||||
|
||||
@api.onchange('job_id')
|
||||
def _onchange_job_id(self):
|
||||
if self.job_id:
|
||||
|
||||
@@ -143,13 +143,11 @@
|
||||
<field name="pension_insurance_base"/>
|
||||
<field name="work_injury_insurance_base"/>
|
||||
<field name="housing_fund_base"/>
|
||||
<field name="last_month_attendance_deduction"/>
|
||||
<field name="last_month_base_salary_deduction"/>
|
||||
<field name="last_month_performance_deduction"/>
|
||||
<field name="last_month_commuting_deduction"/>
|
||||
<field name="commuting" invisible="1"/>
|
||||
<field name="performance" invisible="1"/>
|
||||
<field name="is_salary"/>
|
||||
<field name="last_attendance"/>
|
||||
</group>
|
||||
<group name="overtime" string="加班" col="2">
|
||||
<group>
|
||||
|
||||
Reference in New Issue
Block a user