258 lines
15 KiB
Python
258 lines
15 KiB
Python
from email.policy import default
|
|
|
|
from odoo import api, fields, models, _
|
|
from pypinyin import pinyin, Style
|
|
|
|
|
|
class YuthonPayrollCommon(models.Model):
|
|
_name = 'yuthon.payroll.common'
|
|
_description = '薪资常用项'
|
|
_order = 'sequence asc'
|
|
|
|
yuthon_company = fields.Selection([('thtz', 'thtz')], default="thtz")
|
|
company_id = fields.Many2one('res.company', string="公司", default=lambda self: self.env.company)
|
|
name = fields.Char(string='工资项名称')
|
|
sequence = fields.Char(string='序号', store=True)
|
|
department_id = fields.Many2one('hr.department', string="部门")
|
|
payroll_structure_ids = fields.Many2many('hr.payroll.structure', string="排除职级范围", store=True)
|
|
payroll_type_ids = fields.Many2many('yuthon.payroll.type.setting', string="排除薪资类别")
|
|
conditional_formulas = fields.Text(string='条件公式')
|
|
start_date = fields.Date(string="生效日期", default=fields.Date.today())
|
|
end_date = fields.Date(string="失效日期")
|
|
before_tax = fields.Boolean(string="税前")
|
|
is_enable = fields.Boolean(string="启用", default=True)
|
|
create_time = fields.Date(string="创建日期", default=fields.Datetime.now)
|
|
attributes = fields.Selection([('increment', '增'), ('deduction', '减')], string="工资项属性", default='increment')
|
|
|
|
@api.onchange('payroll_type_ids')
|
|
def _onchange_payroll_type_ids(self):
|
|
if self.payroll_type_ids:
|
|
structures = self.env['hr.payroll.structure'].search([('level_id', 'in', self.payroll_type_ids.ids)])
|
|
self.payroll_structure_ids = [(6, 0, structures.ids)]
|
|
else:
|
|
self.payroll_structure_ids = [(6, 0, [])]
|
|
|
|
def create_salary_common(self):
|
|
"""
|
|
更新常用项职级
|
|
:return:
|
|
# Available variables:
|
|
#----------------------
|
|
# payslip: hr.payslip object
|
|
# employee: hr.employee object
|
|
# contract: hr.contract object
|
|
# rules: dict containing the rules code (previously computed)
|
|
# categories: dict containing the computed salary rule categories (sum of amount of all rules belonging to that category).
|
|
# worked_days: dict containing the computed worked days
|
|
# inputs: dict containing the computed inputs.
|
|
# Note: returned value have to be set in the variable 'result'
|
|
result = contract.wage * 0.10
|
|
"""
|
|
insurances_ids = self.env["yuthon.payroll.common"].browse(self._context.get('active_ids', self._context.get('active_id')))
|
|
for ins in insurances_ids:
|
|
for sal in self.env["hr.payroll.structure"].search([('company_id', '=', ins.company_id.id)]):
|
|
if sal.id in ins.payroll_structure_ids.ids:
|
|
continue
|
|
rule_list = []
|
|
formula_salary = ''
|
|
if ins.name == '扣发绩效奖金':
|
|
formula_salary = "result = (employee.last_month_performance_deduction) * -1"
|
|
if ins.name == '扣发通信补贴':
|
|
formula_salary = "result = (employee.last_month_commuting_deduction) * -1"
|
|
if ins.name == '扣发基本工资':
|
|
formula_salary = "result = (employee.last_month_base_salary_deduction) * -1"
|
|
if ins.name == '工龄工资' and ins.company_id.name == '天河物管':
|
|
formula_salary = "result = employee.company_old_year * 10 if employee.company_old_year >= 1 and employee.department_id.name != '领导班子' else 0"
|
|
if ins.name == '工龄工资' and ins.company_id.name == '集团本部':
|
|
formula_salary = "result = 0 if (employee.is_annual_salary or '劳务' in (employee.contract_id.structure_type_id.name or '') or '工勤返聘' in (employee.contract_id.structure_type_id.name or '')) else (employee.company_old_year * 10)"
|
|
if ins.name == '误餐费':
|
|
formula_salary = "result = employee.meal_number * 40 + employee.meal_supplement"
|
|
if ins.name == '通讯补贴':
|
|
formula_salary = "result = 0 if (employee.is_annual_salary or '劳务' in (employee.contract_id.structure_type_id.name or '') or '工勤返聘' in (employee.contract_id.structure_type_id.name or '')) else 300"
|
|
if ins.name == '全勤奖' and ins.company_id.name == '集团本部':
|
|
formula_salary = "result = 0 if (employee.is_annual_salary or '劳务' in (employee.contract_id.structure_type_id.name or '') or '工勤返聘' in (employee.contract_id.structure_type_id.name or '')) else (200 if employee.last_attendance else 0)"
|
|
if ins.name == '全勤奖' and ins.company_id.name == '天河物管':
|
|
formula_salary = "result = 100 if employee.last_attendance else 0"
|
|
if ins.name == '加班费':
|
|
formula_salary = "result = 0 if (employee.is_annual_salary or employee.contract_id.structure_type_id.name == '工勤返聘') else (round(((employee.last_month_overtime - 40) * (payslip.base_salary / 21.75 / 8) * 1.5), 0) if employee.last_month_overtime > 40 else 0)"
|
|
if ins.name == '岗位工资':
|
|
formula_salary = "result = 0"
|
|
if ins.name == '安全生产管理补贴':
|
|
formula_salary = "result = employee.security_amount "
|
|
if ins.name == '工龄补贴' and ins.company_id.name == '天河物管':
|
|
formula_salary = "result = min(400, max(0, ((employee.entry_date - employee.open_start_time).days // 30.4375 - employee.interrupt_work_month) // 12) * 10 + employee.salary_year * 20) if employee.department_id.name != '领导班子' else 0"
|
|
if ins.name == '岗位绩效':
|
|
formula_salary = "result = 0"
|
|
if ins.name == '高温补贴':
|
|
formula_salary = "result = 0"
|
|
if ins.name == '优秀部门经理/员工':
|
|
formula_salary = "result = 0"
|
|
if ins.name == '请假扣发':
|
|
formula_salary = "result = 0"
|
|
if ins.name == '值班(含节日加班)':
|
|
formula_salary = "result = 0"
|
|
if ins.name == '上月值班费':
|
|
formula_salary = "result = 0"
|
|
if ins.name == '环境作业津贴':
|
|
formula_salary = "result = 0"
|
|
if ins.name == '儿童节慰问金':
|
|
formula_salary = "result = 0"
|
|
if ins.name == '春节福利' and ins.company_id.name == '天河物管':
|
|
formula_salary = "result = 680 if employee.salary_month == '1' and employee.department_id.name != '领导班子' else 0"
|
|
if ins.name == '质检员津贴':
|
|
formula_salary = "result = employee.quality_inspector_amount"
|
|
if ins.name == '工会会费' and ins.company_id.name in ['集团本部', '天河物管']:
|
|
formula_salary = "result = round(abs(payslip.base_salary * 0.005) * -1, 2)"
|
|
if ins.name == '工会会费' and ins.company_id.name == '天河粮储':
|
|
formula_salary = "result = abs(20 if employee.user_role_id.name in ['总经理', '副总经理'] else \
|
|
15 if employee.user_role_id.name in ['部门经理', '部门副经理'] else \
|
|
5 if employee.job_id.name == '工勤' else \
|
|
10) * -1"
|
|
if ins.name == '岗位补贴':
|
|
formula_salary = "result = employee.subsidy_amount"
|
|
|
|
if ins.name not in sal.rule_ids.mapped('name'):
|
|
rule_list.append([0, 0, {
|
|
'name': ins.name,
|
|
'category_id': self.env['hr.salary.rule.category'].search([('name', '=', '常用项')], limit=1).id,
|
|
'code': "".join([p[0][0] for p in pinyin(ins.name, style=Style.FIRST_LETTER)]).upper(),
|
|
'amount_select': 'code',
|
|
'company_id': ins.company_id.id,
|
|
'amount_python_compute': formula_salary,
|
|
'struct_id': sal.id,
|
|
}])
|
|
sal.write({'rule_ids': rule_list})
|
|
else:
|
|
sal.rule_ids.search([('name', '=', ins.name), ('company_id', '=', ins.company_id.id)]).write({'amount_python_compute': formula_salary})
|
|
|
|
@api.depends('start_date', 'end_date')
|
|
def compute_is_enable(self):
|
|
for rec in self:
|
|
if rec.start_date and rec.end_date:
|
|
if rec.start_date <= fields.Date.today() < rec.end_date:
|
|
rec.is_enable = True
|
|
else:
|
|
rec.is_enable = False
|
|
|
|
|
|
class YuthonPayrollTemporary(models.Model):
|
|
_name = 'yuthon.payroll.temporary'
|
|
_description = '薪资临时项'
|
|
|
|
company_id = fields.Many2one('res.company', string="公司", default=lambda self: self.env.company)
|
|
name = fields.Char(string='工资项名称')
|
|
department_id = fields.Many2one('hr.department', string="部门")
|
|
attributes = fields.Selection([('increment', '增'), ('deduction', '减')], string="工资项属性", default='increment')
|
|
is_before_tax = fields.Boolean(string="税前")
|
|
start_date = fields.Date(string="生效日期", default=fields.Date.today())
|
|
end_date = fields.Date(string="失效日期")
|
|
|
|
def create_salary_temporary(self):
|
|
"""
|
|
更新薪资临时项
|
|
:return:
|
|
"""
|
|
insurances_ids = self.env["yuthon.payroll.temporary"].browse(self._context.get('active_ids', self._context.get('active_id')))
|
|
for ins in insurances_ids:
|
|
for sal in self.env["hr.payroll.structure"].search([('company_id', '=', ins.company_id.id)]):
|
|
rule_list = []
|
|
if ins.name not in sal.rule_ids.mapped('name'):
|
|
rule_list.append([0, 0, {
|
|
'name': ins.name,
|
|
'category_id': self.env['hr.salary.rule.category'].search([('name', '=', '临时项')], limit=1).id,
|
|
'code': "".join([p[0][0] for p in pinyin(ins.name, style=Style.FIRST_LETTER)]).upper(),
|
|
'amount_select': 'fix',
|
|
'amount_fix': 0,
|
|
'struct_id': sal.id,
|
|
}])
|
|
sal.write({'rule_ids': rule_list})
|
|
|
|
|
|
class YuthonPayrollInsurances (models.Model):
|
|
_name = 'yuthon.payroll.insurances'
|
|
_description = '五险一金'
|
|
|
|
company_id = fields.Many2one('res.company', string="公司", default=lambda self: self.env.company)
|
|
name = fields.Char(string='工资项名称')
|
|
is_base = fields.Boolean(string='独立基数')
|
|
basic_medical_insurance = fields.Float(string='基本医疗保险费', store=True)
|
|
basic_endowment_insurance = fields.Float(string='基本养老保险费', store=True)
|
|
unemployment_insurance = fields.Float(string='失业保险费', store=True)
|
|
housing_provident_fund = fields.Float(string='住房公积金', store=True)
|
|
proportion_company = fields.Float(string='公司缴纳比例')
|
|
proportion_employee = fields.Float(string='个人缴纳比例', digits=(16, 3))
|
|
proportion_company_ceiling = fields.Float(string='公司缴纳比例上限')
|
|
proportion_company_floor = fields.Float(string='公司缴纳比例下限')
|
|
company_base_ceiling = fields.Float(string='公司缴纳基数上限')
|
|
company_base_floor = fields.Float(string='公司缴纳基数下限')
|
|
employee_base_ceiling = fields.Float(string='个人缴纳基数上限')
|
|
employee_base_floor = fields.Float(string='个人缴纳基数下限')
|
|
documents_ids = fields.Many2many('ir.attachment', string="附件")
|
|
payroll_type_ids = fields.Many2many('yuthon.payroll.type.setting', string="排除薪资类别")
|
|
payroll_structure_ids = fields.Many2many('hr.payroll.structure', string="排除职级范围")
|
|
remarks = fields.Text(string="备注")
|
|
start_date = fields.Date(string="生效日期", default=fields.Date.today())
|
|
end_date = fields.Date(string="失效日期")
|
|
|
|
@api.onchange('payroll_type_ids')
|
|
def _onchange_payroll_type_ids(self):
|
|
if self.payroll_type_ids:
|
|
structures = self.env['hr.payroll.structure'].search([('level_id', 'in', self.payroll_type_ids.ids)])
|
|
self.payroll_structure_ids = [(6, 0, structures.ids)]
|
|
else:
|
|
self.payroll_structure_ids = [(6, 0, [])]
|
|
|
|
def create_salary_five(self):
|
|
"""
|
|
更新五险一金
|
|
:return:
|
|
"""
|
|
insurances_ids = self.env["yuthon.payroll.insurances"].browse(self._context.get('active_ids', self._context.get('active_id')))
|
|
for ins in insurances_ids:
|
|
salary_lv_ids = self.env["hr.payroll.structure"].search([('company_id', '=', ins.company_id.id)])
|
|
for sal in salary_lv_ids:
|
|
if sal.id in ins.payroll_structure_ids.ids:
|
|
continue
|
|
rule_list = []
|
|
formula_salary = ''
|
|
number = ins.proportion_employee * 0.01 * -1
|
|
code = 'None'
|
|
if ins.name == '基本医疗保险费':
|
|
code = 'JBYLIAO'
|
|
formula_salary = "result = 0"
|
|
if ins.name == '基本养老保险费':
|
|
code = 'JBYLAO'
|
|
formula_salary = "result = 0"
|
|
if ins.name == '失业保险费':
|
|
code = 'SYBX'
|
|
formula_salary = "result = 0"
|
|
if ins.name == '工伤保险费':
|
|
code = 'GSBX'
|
|
formula_salary = "result = employee.social_base_on * " + str(number)
|
|
if ins.name == '住房公积金':
|
|
code = 'ZFGJJ'
|
|
formula_salary = "result = (round((employee.salary_housing_fund * " + str(number) + "), 0)) if employee.is_accum_salary else 0"
|
|
if ins.name == '企业(职业)年金':
|
|
if ins.company_id.name == '天河物管':
|
|
code = 'WGQYNJ'
|
|
formula_salary = "result = 0.0 if employee.total_coefficients == 0 else round(abs((employee.converted/employee.total_coefficients * employee.calculation_totals * 0.08 * 0.5)/12) * -1, 2)"
|
|
elif ins.company_id.name == '集团本部':
|
|
code = 'QYNJ'
|
|
formula_salary = "result = round(abs(employee.last_year_salary * 0.02) * -1, 0)"
|
|
else:
|
|
code = 'LCQYNJ'
|
|
formula_salary = "result = round(abs(employee.last_year_salary * 0.02) * -1, 2)"
|
|
if ins.name not in sal.rule_ids.mapped('name'):
|
|
rule_list.append([0, 0, {
|
|
'name': ins.name,
|
|
'category_id': self.env['hr.salary.rule.category'].search([('name', '=', '五险一金')], limit=1).id,
|
|
'code': code,
|
|
'company_id': ins.company_id.id,
|
|
'amount_select': 'code',
|
|
'amount_python_compute': formula_salary,
|
|
'struct_id': sal.id,
|
|
}])
|
|
sal.write({'rule_ids': rule_list})
|
|
else:
|
|
sal.rule_ids.search([('name', '=', ins.name), ('company_id', '=', ins.company_id.id)]).write({'amount_python_compute': formula_salary, 'code':code,})
|