224 lines
11 KiB
Python
224 lines
11 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([('', '')])
|
|
company_id = fields.Many2one('res.company', string="公司")
|
|
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)
|
|
attributes = fields.Selection([('increment', '增'), ('deduction', '减')], string="工资项属性", default='increment')
|
|
|
|
def create_salary_four(self):
|
|
all_records = self.env['yuthon.payroll.common'].sudo().search([])
|
|
company_id = self.env['res.company'].search([
|
|
('name', '=', '天河投资集团')
|
|
])
|
|
for record in all_records:
|
|
record.write({
|
|
'company_id': company_id,
|
|
})
|
|
|
|
@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([]):
|
|
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"
|
|
if ins.name == '扣发通信补贴':
|
|
formula_salary = "result = employee.last_month_commuting_deduction"
|
|
if ins.name == '扣发基本工资':
|
|
formula_salary = "result = employee.last_month_base_salary_deduction"
|
|
if ins.name == '工龄工资':
|
|
formula_salary = "result = (employee.company_old_year) * 10"
|
|
if ins.name == '误餐费':
|
|
formula_salary = "result = employee.meal_number * 40 + employee.meal_supplement"
|
|
if ins.name == '通讯补贴':
|
|
formula_salary = "result = 300"
|
|
if ins.name == '全勤奖':
|
|
formula_salary = "result = 200 if employee.last_attendance else 0"
|
|
if ins.name == '加班费':
|
|
formula_salary = "result = round(((employee.all_overtime_hours - 40) * (payslip.base_salary /21.75 / 8) * 1.5), 0) if employee.all_overtime_hours > 40 else 0"
|
|
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',
|
|
'amount_python_compute': formula_salary,
|
|
'struct_id': sal.id,
|
|
}])
|
|
sal.write({'rule_ids': rule_list})
|
|
else:
|
|
sal.rule_ids.search([('name', '=', ins.name)]).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="公司")
|
|
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([]):
|
|
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="公司")
|
|
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([])
|
|
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
|
|
code = 'None'
|
|
if ins.name == '基本医疗保险费':
|
|
code = 'JBYLIAO'
|
|
formula_salary = "result = employee.medical_insurance_base * " + str(number)
|
|
if ins.name == '基本养老保险费':
|
|
code = 'JBYLAO'
|
|
formula_salary = "result = employee.pension_insurance_base * " + str(number)
|
|
if ins.name == '失业保险费':
|
|
code = 'SYBX'
|
|
formula_salary = "result = employee.work_injury_insurance_base * " + str(number)
|
|
if ins.name == '工伤保险费':
|
|
code = 'GSBX'
|
|
formula_salary = "result = employee.social_base_on * " + str(number)
|
|
if ins.name == '住房公积金':
|
|
code = 'ZFGJJ'
|
|
formula_salary = "result = (round((employee.housing_fund_base * " + str(number) + "), 0)) if employee.is_accum_salary else 0"
|
|
if ins.name == '工会会费':
|
|
code = 'GHHF'
|
|
formula_salary = "result = round((payslip.base_salary * 0.005), 2)"
|
|
if ins.name == '企业(职业)年金':
|
|
code = 'QYNJ'
|
|
# formula_salary = "result = (employee.last_year_salary * 0.02) if employee.regularization_year != 0 else ((payslip.base_salary + payslip.rank_salary) * 0.02)"
|
|
formula_salary = "result = round((employee.last_year_salary * 0.02), 0)"
|
|
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,
|
|
'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)]).write({'amount_python_compute': formula_salary})
|
|
|
|
|