From da517f81bb37347840c74c2db7a0cab15b05c725 Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Sun, 13 Jul 2025 20:38:48 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../views/inherit_hr_contract_views.xml | 1 -
yuthon_salary/models/__init__.py | 3 +-
yuthon_salary/models/inherit_hr_payslip.py | 87 +++++++++++++
.../models/inherit_hr_payslip_line.py | 20 +++
.../models/yuthon_payroll_project.py | 2 +-
.../views/inherit_hr_payslip_views.xml | 14 +++
.../initialize_payroll_wizard_views.xml | 6 +-
yuthon_salary/wizard/salary_compute_wizard.py | 114 ++++++++++++------
8 files changed, 206 insertions(+), 41 deletions(-)
create mode 100644 yuthon_salary/models/inherit_hr_payslip_line.py
diff --git a/yuthon_contract/views/inherit_hr_contract_views.xml b/yuthon_contract/views/inherit_hr_contract_views.xml
index 689048128..da824eb96 100644
--- a/yuthon_contract/views/inherit_hr_contract_views.xml
+++ b/yuthon_contract/views/inherit_hr_contract_views.xml
@@ -38,7 +38,6 @@
-
diff --git a/yuthon_salary/models/__init__.py b/yuthon_salary/models/__init__.py
index b715ff945..6a4d01795 100644
--- a/yuthon_salary/models/__init__.py
+++ b/yuthon_salary/models/__init__.py
@@ -12,4 +12,5 @@ from . import yuthon_salary_project
from . import yuthon_salary_asset
from . import salary_payroll_distribution
from . import yuthon_welfare_expenses
-from . import inherit_hr_payslip_run
\ No newline at end of file
+from . import inherit_hr_payslip_run
+from . import inherit_hr_payslip_line
\ No newline at end of file
diff --git a/yuthon_salary/models/inherit_hr_payslip.py b/yuthon_salary/models/inherit_hr_payslip.py
index 4964f5f7e..e2cc55d51 100644
--- a/yuthon_salary/models/inherit_hr_payslip.py
+++ b/yuthon_salary/models/inherit_hr_payslip.py
@@ -2,6 +2,9 @@ from odoo import api, fields, models, _
from odoo.exceptions import ValidationError, UserError
import json
from odoo.tools import date_utils
+from dateutil.relativedelta import relativedelta
+import re
+from datetime import datetime
import logging
_logger = logging.getLogger(__name__)
@@ -144,6 +147,90 @@ class InheritHrPayslip(models.Model):
base_salary_deduction = fields.Float(string='扣发基本工资', compute='_compute_deduction', store=True)
specialized_deduction = fields.Float(string='累计专项扣除')
+ @api.onchange('payslip_run_id')
+ def _onchange_payslip_run_id(self):
+ if not self.payslip_run_id:
+ self.date_from = False
+ self.date_to = False
+ return
+ batch_name = self.payslip_run_id.name
+ pattern = r'(\d{4})年-([一二三四五六七八九十]{1,2})月'
+ match = re.search(pattern, batch_name)
+ if match:
+ year = int(match.group(1))
+ month_name = match.group(2)
+ month_mapping = {
+ '一': 1, '二': 2, '三': 3, '四': 4, '五': 5, '六': 6,
+ '七': 7, '八': 8, '九': 9, '十': 10, '十一': 11, '十二': 12
+ }
+ month = month_mapping.get(month_name)
+ if month:
+ self.date_from = datetime(year, month, 1).date()
+ self.date_to = (datetime(year, month, 1) + relativedelta(months=1, days=-1)).date()
+
+
+ @api.model_create_multi
+ def create(self, vals_list):
+ # 存储每个工资单的检查结果
+ existing_payslips = {}
+ for vals in vals_list:
+ employee_id = vals.get('employee_id')
+ payslip_run_id = vals.get('payslip_run_id')
+ if not employee_id or not payslip_run_id:
+ continue
+ # 检查工资单是否存在于各个状态
+ conditions = [
+ (_('薪资审定'), [
+ ('employee_id', '=', employee_id),
+ ('payslip_run_id', '=', payslip_run_id),
+ ('is_salary_push', '=', True),
+ ('is_salary_release', '=', False)
+ ]),
+ (_('薪资归档'), [
+ ('employee_id', '=', employee_id),
+ ('payslip_run_id', '=', payslip_run_id),
+ ('is_salary_push', '=', True),
+ ('is_salary_release', '=', True)
+ ]),
+ (_('薪资计算'), [
+ ('employee_id', '=', employee_id),
+ ('payslip_run_id', '=', payslip_run_id),
+ ('is_push', '=', False)
+ ]),
+ (_('个税计算'), [
+ ('employee_id', '=', employee_id),
+ ('payslip_run_id', '=', payslip_run_id),
+ ('is_push', '=', True),
+ ('is_salary_push', '=', False)
+ ])
+ ]
+
+ for state_name, domain in conditions:
+ existing = self.search(domain, limit=1)
+ if existing:
+ # 获取员工和批次名称用于错误提示
+ employee = self.env['hr.employee'].browse(employee_id)
+ payslip_run = self.env['hr.payslip.run'].browse(payslip_run_id)
+
+ existing_payslips[(employee_id, payslip_run_id)] = {
+ 'employee_name': employee.name,
+ 'batch_name': payslip_run.name,
+ 'state': state_name
+ }
+ break
+ if existing_payslips:
+ error_messages = []
+ for key, info in existing_payslips.items():
+ msg = _("员工 %(employee)s 在批次 '%(batch)s' 的工资单已存在于'%(state)s'中!") % {
+ 'employee': info['employee_name'],
+ 'batch': info['batch_name'],
+ 'state': info['state']
+ }
+ error_messages.append(msg)
+ raise UserError('\n'.join(error_messages))
+ res = super(InheritHrPayslip, self).create(vals_list)
+ return res
+
@api.ondelete(at_uninstall=False)
def _unlink_if_draft_or_cancel(self):
if any(payslip.state not in ('draft', 'cancel') for payslip in self):
diff --git a/yuthon_salary/models/inherit_hr_payslip_line.py b/yuthon_salary/models/inherit_hr_payslip_line.py
new file mode 100644
index 000000000..56764f9dc
--- /dev/null
+++ b/yuthon_salary/models/inherit_hr_payslip_line.py
@@ -0,0 +1,20 @@
+from odoo import api, fields, models, _
+from odoo.exceptions import ValidationError, UserError
+import json
+from odoo.tools import date_utils
+import logging
+
+
+
+class InheritHrPayslipLine(models.Model):
+ _inherit = 'hr.payslip.line'
+
+ is_amount = fields.Boolean(string='金额是否一至', default=False)
+
+ @api.onchange('total')
+ def _onchange_total(self):
+ if self.total and self.amount:
+ if self.total != self.amount:
+ self.is_amount = True
+ else:
+ self.is_amount = False
\ No newline at end of file
diff --git a/yuthon_salary/models/yuthon_payroll_project.py b/yuthon_salary/models/yuthon_payroll_project.py
index 427d6b4bc..e9027b5fa 100644
--- a/yuthon_salary/models/yuthon_payroll_project.py
+++ b/yuthon_salary/models/yuthon_payroll_project.py
@@ -96,7 +96,7 @@ class YuthonPayrollCommon(models.Model):
if ins.name == '环境作业津贴':
formula_salary = "result = 0"
if ins.name == '春节福利' and ins.company_id.name == '天河物管':
- formula_salary = "result = 680 if employee.department_id.name != '领导班子' else 0"
+ 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 ['集团本部', '天河物管']:
diff --git a/yuthon_salary/views/inherit_hr_payslip_views.xml b/yuthon_salary/views/inherit_hr_payslip_views.xml
index bfc148f00..f7d43f225 100644
--- a/yuthon_salary/views/inherit_hr_payslip_views.xml
+++ b/yuthon_salary/views/inherit_hr_payslip_views.xml
@@ -128,10 +128,24 @@
1
+
+
+
+
+
+ is_amount
+ category_id
0
+
+ 工资批次
+
+
+
+
+
1
diff --git a/yuthon_salary/wizard/initialize_payroll_wizard_views.xml b/yuthon_salary/wizard/initialize_payroll_wizard_views.xml
index 634e4fcda..6184c2240 100644
--- a/yuthon_salary/wizard/initialize_payroll_wizard_views.xml
+++ b/yuthon_salary/wizard/initialize_payroll_wizard_views.xml
@@ -9,9 +9,9 @@
-
-
-
+
+
+