@@ -10,7 +10,6 @@
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='employee_id']" position="after">
|
||||
<field name="contract_type_id" string="用工形式"/>
|
||||
<field name="simplified_name" column_invisible="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='name']" position="attributes">
|
||||
<attribute name="column_invisible">1</attribute>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
'wizard/yuthon_payroll_wizard_views.xml',
|
||||
'wizard/payroll_labor_wizard_views.xml',
|
||||
'wizard/payroll_retired_wizard_views.xml',
|
||||
'wizard/salary_year_wizard.xml',
|
||||
'wizard/salary_compute_wizard_views.xml',
|
||||
'wizard/salary_payslip_wizard_views.xml',
|
||||
'wizard/select_delete_wizard_viwes.xml',
|
||||
@@ -45,6 +46,7 @@
|
||||
'yuthon_salary/static/src/js/salary_return_button.js',
|
||||
'yuthon_salary/static/src/js/salary_retired_button.js',
|
||||
'yuthon_salary/static/src/js/salary_validation_button.js',
|
||||
'yuthon_salary/static/src/js/salary_year_button.js',
|
||||
'yuthon_salary/static/src/xml/salary_create_button.xml',
|
||||
'yuthon_salary/static/src/xml/salary_labor_button.xml',
|
||||
'yuthon_salary/static/src/xml/salary_retired_button.xml',
|
||||
@@ -52,6 +54,7 @@
|
||||
'yuthon_salary/static/src/xml/salary_documents_button.xml',
|
||||
'yuthon_salary/static/src/xml/salary_validation_button.xml',
|
||||
'yuthon_salary/static/src/xml/salary_return_button.xml',
|
||||
'yuthon_salary/static/src/xml/salary_year_button.xml',
|
||||
],
|
||||
},
|
||||
'installable': True,
|
||||
|
||||
@@ -22,13 +22,56 @@ class YuthonSalaryYear(models.Model):
|
||||
# 粮储
|
||||
performance_salary = fields.Float(string="绩效奖金")
|
||||
# 综合
|
||||
sum_salary = fields.Float(string="应发合计")
|
||||
buckle_salary = fields.Float(string="扣个税")
|
||||
solid_salary = fields.Float(string="实发年终奖")
|
||||
sum_salary = fields.Float("应发合计", compute='_compute_company_specific_sum', store=True)
|
||||
buckle_salary = fields.Float(string="扣个税", compute='_compute_buckle_salary', store=True)
|
||||
solid_salary = fields.Float(string="实发年终奖", compute='_compute_solid_salary', store=True)
|
||||
create_date = fields.Date(string="创建日期")
|
||||
company_id = fields.Many2one('res.company', related="employee_id.company_id", string="公司")
|
||||
personal_tax = fields.Many2one('yuthon.personal.rule', string="个人所得税规则")
|
||||
# 计算字段
|
||||
@api.depends('company_id', 'on_year_balance', 'former_year_balance', 'on_year_liquidation',
|
||||
'former_year_liquidation', 'one_three_salary', 'job_salary', 'test_salary',
|
||||
'software_salary', 'safe_salary', 'outstanding_salary', 'leadership_salary',
|
||||
'performance_salary')
|
||||
def _compute_company_specific_sum(self):
|
||||
# 定义各公司的计算字段映射
|
||||
company_rules = {
|
||||
'集团本部': [
|
||||
'on_year_balance', 'former_year_balance',
|
||||
'on_year_liquidation', 'former_year_liquidation'
|
||||
],
|
||||
'天河物管': [
|
||||
'one_three_salary', 'job_salary', 'test_salary',
|
||||
'software_salary', 'safe_salary', 'outstanding_salary',
|
||||
'leadership_salary'
|
||||
],
|
||||
'天河粮储': ['performance_salary']
|
||||
}
|
||||
|
||||
for record in self:
|
||||
company_name = record.company_id.name
|
||||
sum_value = 0.0
|
||||
fields_to_sum = company_rules.get(company_name, [])
|
||||
for field_name in fields_to_sum:
|
||||
sum_value += getattr(record, field_name, 0.0)
|
||||
record.sum_salary = sum_value
|
||||
|
||||
@api.depends('sum_salary')
|
||||
def _compute_buckle_salary(self):
|
||||
for record in self:
|
||||
rule = self.env['yuthon.personal.rule'].search([
|
||||
('start_number', '<', record.sum_salary),
|
||||
('end_number', '>', record.sum_salary),
|
||||
], limit=1)
|
||||
if rule:
|
||||
record.buckle_salary = record.sum_salary * rule.tax_rate
|
||||
else:
|
||||
record.buckle_salary = 0
|
||||
|
||||
@api.depends('sum_salary', 'buckle_salary')
|
||||
def _compute_solid_salary(self):
|
||||
for record in self:
|
||||
record.solid_salary = record.sum_salary - record.buckle_salary
|
||||
|
||||
|
||||
class YuthonPersonalRule(models.Model):
|
||||
@@ -39,6 +82,5 @@ class YuthonPersonalRule(models.Model):
|
||||
end_number = fields.Float(string="结束范围")
|
||||
tax_rate = fields.Float(string="税率")
|
||||
compute_number = fields.Float(string="速算扣除数")
|
||||
company_id = fields.Many2one('res.company', string="公司")
|
||||
start_date = fields.Date(string="生效日期")
|
||||
end_date = fields.Date(string="失效日期")
|
||||
@@ -24,4 +24,5 @@ access_yuthon_payroll_retired,access_yuthon_payroll_retired,model_yuthon_payroll
|
||||
access_payroll_labor_wizard,access_payroll_labor_wizard,model_payroll_labor_wizard,base.group_user,1,1,1,1
|
||||
access_payroll_retired_wizard,access_payroll_retired_wizard,model_payroll_retired_wizard,base.group_user,1,1,1,1
|
||||
access_yuthon_salary_documents,access_yuthon_salary_documents,model_yuthon_salary_documents,base.group_user,1,1,1,1
|
||||
access_salary_print_wizard, access_salary_print_wizard,model_salary_print_wizard,base.group_user,1,1,1,1
|
||||
access_salary_print_wizard, access_salary_print_wizard,model_salary_print_wizard,base.group_user,1,1,1,1
|
||||
access_salary_year_wizard,access_salary_year_wizard,model_salary_year_wizard,base.group_user,1,1,1,1
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,29 @@
|
||||
/** @odoo-module */
|
||||
import { ListController } from "@web/views/list/list_controller";
|
||||
import { registry } from '@web/core/registry';
|
||||
import { listView } from '@web/views/list/list_view';
|
||||
|
||||
export class CustomSalaryYearStatementsController extends ListController {
|
||||
setup() {
|
||||
super.setup();
|
||||
}
|
||||
|
||||
openSalaryYearWizard() {
|
||||
this.actionService.doAction({
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'salary.year.wizard',
|
||||
name: '年终奖导入弹窗',
|
||||
view_mode: 'form',
|
||||
view_type: 'form',
|
||||
views: [[false, 'form']],
|
||||
target: 'new', // 以弹窗形式打开
|
||||
context: {},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
registry.category("views").add("custom_salary_year_button", {
|
||||
...listView,
|
||||
Controller: CustomSalaryYearStatementsController,
|
||||
buttonTemplate: "salary_year_module.ListView.Buttons",
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<templates>
|
||||
<t t-name="salary_year_module.ListView.Buttons" t-inherit="web.ListView.Buttons">
|
||||
<xpath expr="//div[hasclass('o_list_buttons')]" position="after">
|
||||
<button type="button" class="btn btn-primary" style="margin-left: 10px;" t-on-click="openSalaryYearWizard">
|
||||
导入
|
||||
</button>
|
||||
</xpath>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -4,7 +4,7 @@
|
||||
<field name="name">yuthon.salary.year.tree</field>
|
||||
<field name="model">yuthon.salary.year</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="年终奖金计算" editable="bottom">
|
||||
<tree string="年终奖金计算" editable="bottom" js_class="custom_salary_year_button">
|
||||
<field name="employee_id"/>
|
||||
<field name="on_year_balance" groups="yuthon_salary.group_jtbb_user"/>
|
||||
<field name="former_year_balance" groups="yuthon_salary.group_jtbb_user"/>
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
<field name="performance_salary" groups="yuthon_salary.group_lc_user"/>
|
||||
|
||||
<field name="sum_salary"/>
|
||||
<field name="buckle_salary"/>
|
||||
<field name="solid_salary"/>
|
||||
<field name="sum_salary"/>
|
||||
@@ -47,7 +46,6 @@
|
||||
<field name="end_number"/>
|
||||
<field name="tax_rate"/>
|
||||
<field name="compute_number"/>
|
||||
<field name="company_id"/>
|
||||
<field name="start_date"/>
|
||||
<field name="end_date"/>
|
||||
</tree>
|
||||
|
||||
@@ -7,4 +7,5 @@ from . import put_return_wizard
|
||||
from . import temporary_payslip_wizard
|
||||
from . import payroll_labor_wizard
|
||||
from . import payroll_retired_wizard
|
||||
from . import salary_print_wizard
|
||||
from . import salary_print_wizard
|
||||
from . import salary_year_wizard
|
||||
@@ -0,0 +1,103 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api, _, SUPERUSER_ID
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
from pypinyin import pinyin, Style
|
||||
import xlrd
|
||||
import base64
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class SalaryYearWizard(models.Model):
|
||||
_name = 'salary.year.wizard'
|
||||
_description = '年终奖导入弹窗'
|
||||
|
||||
company_id = fields.Many2one('res.company', string='公司', default=lambda self: self.env.company, store=True)
|
||||
company_name = fields.Char(string='公司名称', related='company_id.name', store=True)
|
||||
|
||||
excel_file = fields.Binary(string="上传Excel表")
|
||||
excel_name = fields.Char(string="文件名")
|
||||
|
||||
def confirm(self):
|
||||
if not self.excel_file:
|
||||
raise ValidationError('请上传文件。')
|
||||
book = xlrd.open_workbook(file_contents=base64.decodebytes(self.excel_file))
|
||||
sh = book.sheet_by_index(0)
|
||||
for rx in range(1, sh.nrows):
|
||||
row = sh.row(rx)
|
||||
if self.company_id.name == '集团本部':
|
||||
self.salary_year_ttjt_data(row)
|
||||
elif self.company_id.name == '天河物管':
|
||||
self.salary_year_thwg_data(row)
|
||||
else:
|
||||
self.salary_year_thlc_data(row)
|
||||
|
||||
|
||||
def salary_year_ttjt_data(self,row):
|
||||
employee_id = self.env['hr.employee'].search([('name', '=', row[0].value)], limit=1)
|
||||
on_year_balance = row[1].value
|
||||
former_year_balance = row[2].value
|
||||
on_year_liquidation = row[3].value
|
||||
former_year_liquidation = row[4].value
|
||||
salary_year_id = self.env["yuthon.salary.year"].search([('employee_id', '=', employee_id.id)])
|
||||
if salary_year_id:
|
||||
salary_year_id.write({
|
||||
'on_year_balance': on_year_balance,
|
||||
'former_year_balance': former_year_balance,
|
||||
'on_year_liquidation': on_year_liquidation,
|
||||
'former_year_liquidation': former_year_liquidation,
|
||||
})
|
||||
else:
|
||||
self.env["yuthon.salary.year"].create({
|
||||
'employee_id': employee_id.id,
|
||||
'on_year_balance': on_year_balance,
|
||||
'former_year_balance': former_year_balance,
|
||||
'on_year_liquidation': on_year_liquidation,
|
||||
'former_year_liquidation': former_year_liquidation,
|
||||
})
|
||||
|
||||
def salary_year_thwg_data(self, row):
|
||||
employee_id = self.env['hr.employee'].search([('name', '=', row[0].value)], limit=1)
|
||||
one_three_salary = row[1].value
|
||||
job_salary = row[2].value
|
||||
test_salary = row[3].value
|
||||
software_salary = row[4].value
|
||||
safe_salary = row[5].value
|
||||
outstanding_salary = row[6].value
|
||||
leadership_salary = row[7].value
|
||||
salary_year_id = self.env["yuthon.salary.year"].search([('employee_id', '=', employee_id.id)])
|
||||
if not salary_year_id:
|
||||
self.env["yuthon.salary.year"].create({
|
||||
'employee_id': employee_id.id,
|
||||
'one_three_salary': one_three_salary,
|
||||
'job_salary': job_salary,
|
||||
'test_salary': test_salary,
|
||||
'software_salary': software_salary,
|
||||
'safe_salary': safe_salary,
|
||||
'outstanding_salary': outstanding_salary,
|
||||
'leadership_salary': leadership_salary,
|
||||
})
|
||||
else:
|
||||
salary_year_id.write({
|
||||
'one_three_salary': one_three_salary,
|
||||
'job_salary': job_salary,
|
||||
'test_salary': test_salary,
|
||||
'software_salary': software_salary,
|
||||
'safe_salary': safe_salary,
|
||||
'outstanding_salary': outstanding_salary,
|
||||
'leadership_salary': leadership_salary,
|
||||
})
|
||||
|
||||
def salary_year_thlc_data(self, row):
|
||||
employee_id = self.env['hr.employee'].search([('name', '=', row[0].value)], limit=1)
|
||||
performance_salary = row[1].value
|
||||
salary_year_id = self.env["yuthon.salary.year"].search([('employee_id', '=', employee_id.id)])
|
||||
if not salary_year_id:
|
||||
salary_year_id = self.env["yuthon.salary.year"].create({
|
||||
'employee_id': employee_id.id,
|
||||
'performance_salary': performance_salary,
|
||||
})
|
||||
else:
|
||||
salary_year_id.write({
|
||||
'performance_salary': performance_salary,
|
||||
})
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<!-- 天河投资模板下载动作 -->
|
||||
<record id="salary_year_wizard_downloads_tianhetouzi_action" model="ir.actions.act_url">
|
||||
<field name="name">天河投资模板下载</field>
|
||||
<field name="target">self</field>
|
||||
<field name="url">/yuthon_salary/static/others/salary_year_thtz.xlsx</field>
|
||||
</record>
|
||||
<!-- 天河物管模板下载动作 -->
|
||||
<record id="salary_year_wizard_downloads_tianhewuguan_action" model="ir.actions.act_url">
|
||||
<field name="name">天河物管模板下载</field>
|
||||
<field name="target">self</field>
|
||||
<field name="url">/yuthon_salary/static/others/salary_year_thwg.xlsx</field>
|
||||
</record>
|
||||
<!-- 天河粮储模板下载动作 -->
|
||||
<record id="salary_year_wizard_downloads_tianheliangchu_action" model="ir.actions.act_url">
|
||||
<field name="name">天河粮储模板下载</field>
|
||||
<field name="target">self</field>
|
||||
<field name="url">/yuthon_salary/static/others/salary_year_thlc.xlsx</field>
|
||||
</record>
|
||||
|
||||
<record id="salary_year_wizard_form" model="ir.ui.view">
|
||||
<field name="name">弹窗</field>
|
||||
<field name="model">salary.year.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<header>
|
||||
<button name="%(salary_year_wizard_downloads_tianhetouzi_action)d" string="模板下载" type="action"
|
||||
class="btn btn-primary" invisible="company_name != '集团本部'"/>
|
||||
<button name="%(salary_year_wizard_downloads_tianhewuguan_action)d" string="模板下载" type="action"
|
||||
class="btn btn-primary" invisible="company_name != '天河物管'"/>
|
||||
<button name="%(salary_year_wizard_downloads_tianheliangchu_action)d" string="模板下载" type="action"
|
||||
class="btn btn-primary" invisible="company_name != '天河粮储'"/>
|
||||
</header>
|
||||
<group>
|
||||
<group>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="company_name" invisible="1"/>
|
||||
<field name="excel_file" filename="excel_name"/>
|
||||
<field name="excel_name" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
<footer>
|
||||
<button name="confirm" string="确认" type="object" class="oe_highlight"/>
|
||||
<button string="返回" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user