Files
gzth/yuthon_salary/models/yuthon_payroll_project.py
T
2025-04-03 10:29:59 +08:00

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})