Files
gzth/yuthon_salary/models/inherit_hr_payroll_structure.py
T
2025-05-30 20:55:53 +08:00

192 lines
8.5 KiB
Python

from odoo import api, fields, models, _
import re
from pypinyin import pinyin, Style
class HrPayrollStructure(models.Model):
_inherit = 'hr.payroll.structure'
_order = 'sequence asc'
company_id = fields.Many2one('res.company', string="公司", default=lambda self: self.env.company)
yuthon_company = fields.Selection([('thtz', 'thtz')], default="thtz")
type_id = fields.Many2one('hr.payroll.structure.type', string="职级类型")
level_id = fields.Many2one('yuthon.payroll.type.setting', string="级别")
lv_name = fields.Char(related='level_id.name', string='级别名称', store=True)
name = fields.Char(string="职级名称")
sequence = fields.Char(string='级别序号', store=True)
create_time = fields.Date(string="生效日期", default=fields.Date.today())
end_time = fields.Date(string="失效日期")
is_enable = fields.Boolean(string="启用", default=True)
currency_id = fields.Many2one("res.currency", string="货币", required=True, default=lambda self: self.env.company.currency_id)
base_salary = fields.Monetary(string="基本工资", currency_field="currency_id")
rank_salary = fields.Monetary(string="职级工资", currency_field="currency_id")
communication_subsidy = fields.Monetary(string="通讯补贴", currency_field="currency_id")
position_salary = fields.Monetary(string="岗位工资", currency_field="currency_id")
position_subsidy = fields.Monetary(string="岗位补贴", currency_field="currency_id")
integrated_subsidy = fields.Monetary(string="综合补贴", currency_field="currency_id")
advance_performance_bonuses = fields.Monetary(string="预发绩效奖金", currency_field="currency_id")
@api.model
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
res = super(HrPayrollStructure, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby,
lazy=lazy)
if 'lv' in groupby:
def sort_by_sequence_number(item):
lv = item.get('lv')
if lv:
rec = self.search([('lv', '=', lv)], limit=1)
if rec and rec.sequence:
match = re.findall(r'\d+', rec.sequence)
if match:
number_str = "".join(match)
try:
number = int(number_str)
return (not number_str.startswith('0'), number)
except ValueError:
return (False, 0)
return (False, 0) # 首位非0的放前面
res.sort(key=sort_by_sequence_number)
return res
def _handle_salary_rule(self, field_name, amount):
category_id = self.env['hr.salary.rule.category'].search([('name', '=', '职级')], limit=1)
if amount:
name_pinyin = pinyin(field_name, style=Style.FIRST_LETTER)
code = "".join([p[0][0] for p in name_pinyin]).upper()
salary_id = self.env['hr.salary.rule'].search(
[('name', '=', field_name), ('struct_id', '=', self.id.origin)], limit=1)
if not salary_id:
self.env['hr.salary.rule'].create({
'name': field_name,
'category_id': category_id.id,
'code': code,
'amount_fix': amount,
'struct_id': self.id.origin
})
else:
salary_id.write({
'amount_fix': amount
})
@api.onchange('base_salary')
def _onchange_base_salary(self):
self._handle_salary_rule('基本工资', self.base_salary)
@api.onchange('rank_salary')
def _onchange_rank_salary(self):
self._handle_salary_rule('职级工资', self.rank_salary)
@api.onchange('communication_subsidy')
def _onchange_communication_subsidy(self):
self._handle_salary_rule('通讯补贴', self.communication_subsidy)
@api.onchange('position_salary')
def _onchange_position_salary(self):
self._handle_salary_rule('岗位工资', self.position_salary)
@api.onchange('position_subsidy')
def _onchange_position_subsidy(self):
self._handle_salary_rule('岗位补贴', self.position_subsidy)
@api.onchange('integrated_subsidy')
def _onchange_integrated_subsidy(self):
self._handle_salary_rule('综合补贴', self.integrated_subsidy)
@api.onchange('advance_performance_bonuses')
def _onchange_advance_performance_bonuses(self):
self._handle_salary_rule('预发绩效奖金', self.advance_performance_bonuses)
def open_record(self):
return {
"type": "ir.actions.act_window",
"res_model": 'hr.payroll.structure',
"res_id": self.id,
"name": "职级详情",
"view_mode": "form",
}
def action_yuthon_payroll_wizard(self):
return {
"type": "ir.actions.act_window",
"name": "导入薪资",
"res_model": "yuthon.payroll.wizard",
"view_mode": "form",
"target": "new",
}
def generate_salary_rules(self, company_code, field_mapping):
# 搜索符合条件的薪资结构
company_id = self.env['res.company'].search([('name', '=', company_code)], limit=1)
structure_ids = self.env['hr.payroll.structure'].search([('company_id', '=', company_id.id)])
for structure in structure_ids:
# # 清空当前结构的规则
# structure.rule_ids.unlink()
# 初始化规则列表
rule_list = []
for rule_name, field_attr in field_mapping.items():
field_amount = getattr(structure, field_attr)
if field_amount is not None:
name_pinyin = pinyin(rule_name, style=Style.FIRST_LETTER)
code = "".join([p[0][0] for p in name_pinyin]).upper()
category_id = self.env['hr.salary.rule.category'].search([('name', '=', '职级')], limit=1)
rule_list.append([0, 0, {
'name': rule_name,
'category_id': category_id.id,
'code': code,
'amount_fix': field_amount,
'struct_id': structure.id,
'company_id': structure.company_id.id
}])
if rule_list:
structure.write({'rule_ids': rule_list})
def salary_rule_data(self):
# 定义不同公司的字段映射
company_mappings = {
'天河物管': { # 天河物管
'基本工资': 'base_salary',
'岗位工资': 'position_salary',
'综合补贴': 'integrated_subsidy',
'通讯补贴': 'communication_subsidy'
},
'天河粮储': { # 天河梁储
'基本工资': 'base_salary',
'岗位工资': 'position_salary',
'岗位补贴': 'position_subsidy',
'预发绩效奖金': 'advance_performance_bonuses'
}
}
for company_code, field_mapping in company_mappings.items():
self.generate_salary_rules(company_code, field_mapping)
def action_select_delete_wizard(self):
return {
"type": "ir.actions.act_window",
"name": "选择删除",
"res_model": "select.delete.wizard",
"view_mode": "form",
"target": "new",
}
def delete_structure(self):
payroll_ids = self.env["hr.payroll.structure"].browse(
self._context.get('active_ids', self._context.get('active_id')))
for payroll in payroll_ids:
for rule in payroll.rule_ids:
rule.sudo().unlink()
def update_payroll_items(self):
payroll_ids = self.env["hr.payroll.structure"].browse(
self._context.get('active_ids', self._context.get('active_id')))
category_id = self.env['hr.salary.rule.category'].search([('name', '=', '常用项')], limit=1)
for payroll in payroll_ids:
self.env['hr.salary.rule'].create({
'name': '质检员津贴',
'code': 'ZJYJT',
'category_id': category_id.id,
'struct_id': payroll.id,
'sequence': 1,
'amount_select': 'fix',
})