diff --git a/yuthon_property_approval/wizard/property_reconciliation_wizard.py b/yuthon_property_approval/wizard/property_reconciliation_wizard.py index 6b35cbafb..49373b80f 100644 --- a/yuthon_property_approval/wizard/property_reconciliation_wizard.py +++ b/yuthon_property_approval/wizard/property_reconciliation_wizard.py @@ -328,9 +328,12 @@ class PropertyReconciliationWizard(models.Model): 'user': information.name, 'name': rec.bank_id.name, }) + remaining_amount = 0 + for line in rec.reconciliation_line_ids: + remaining_amount += line.amount - if rec.actual_total > rec.receivable_total: - rec.bank_id.registered = rec.actual_total - rec.receivable_total + if rec.actual_total > rec.remaining_amount: + rec.bank_id.registered = rec.actual_total - rec.remaining_amount rec.bank_id.bank_state = 'registered' else: rec.bank_id.registered = 0 diff --git a/yuthon_salary/wizard/salary_compute_wizard.py b/yuthon_salary/wizard/salary_compute_wizard.py index 9d304c542..24a3bbc42 100644 --- a/yuthon_salary/wizard/salary_compute_wizard.py +++ b/yuthon_salary/wizard/salary_compute_wizard.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +from dateutil.relativedelta import relativedelta + from odoo import models, fields, api, _, SUPERUSER_ID from odoo.exceptions import ValidationError, UserError from odoo.exceptions import ValidationError @@ -37,7 +39,7 @@ class SalaryComputeWizard(models.Model): # 计算当月第一天和最后一天 first_day = datetime(year, month, 1).strftime('%Y-%m-%d') - last_day = datetime(year, month, calendar.monthrange(year, month)[1]).strftime('%Y-%m-%d') + last_day = datetime(year, month, 15).strftime('%Y-%m-%d') if self.company_id: employees = self.env['hr.employee'].search([ @@ -57,8 +59,8 @@ class SalaryComputeWizard(models.Model): ]) self.employee_ids = [(6, 0, employees.ids)] self.employee_number = len(employees) - # for employee in employees: - # print(f"员工姓名: {employee.name}") + for employee in employees: + print(f"员工姓名: {employee.name}") @api.onchange('employee_ids') def onchange_employee_ids(self): @@ -97,7 +99,7 @@ class SalaryComputeWizard(models.Model): 'state': 'draft', 'payslip_count': 0 }) - query_date = datetime(year, month, 1).date() + query_date = datetime(year, month, 1).date() - relativedelta(months=1) vacation_report = self.env['yuthon.vacation.reports'].search([ ('employee_id', '=', employee.id), ('vacation_date', '=', query_date) @@ -202,7 +204,7 @@ class SalaryComputeWizard(models.Model): original_end_date = internship_id.date_to if is_turnover or is_probation: - days = 21.75 # 总工作日 + days = 21 # 总工作日 if is_turnover: # 离职日期前的工作日 @@ -222,86 +224,99 @@ class SalaryComputeWizard(models.Model): internship_start = max(original_start_date, contract_start_date) internship_end = min(original_end_date, contract_end_date) + # 判断该员工是否需补发上月工资 + if contract_start_date.year == internship_start.year and contract_start_date.month == (internship_start - relativedelta(months=1)).month and contract_start_date.day > 15: + last_internship_days = self._process_shift_days(contract_start_date, internship_start - relativedelta(days=1)) + else: + last_internship_days = 0 + if internship_start <= internship_end: # 判断是否整月都是实习期(无转正后工作日) if contract_end_date >= original_end_date: - # 整月都是实习期,实习和转正工作日均为21.75 - internship_days = 21.75 - work_days = 21.75 + # 整月都是实习期,实习和转正工作日均为21.75 # todo 21.75 待定 + internship_days = 21 + work_days = 21 else: # 部分时间是实习期,计算实际工作日 internship_days = self._process_shift_days(internship_start, internship_end) - work_days = 21.75 - internship_days + work_days = 21 - internship_days if internship_id.line_ids: if is_probation and not internship_id.employee_id.is_annual_salary: target_names = { - '基本工资': 'base_salary', - '职级工资': 'rank_salary', + '基本工资': 'base_salary', # 0.8 + '职级工资': 'rank_salary', # 0.8 '岗位工资': 'position_salary', - '预发绩效奖金': 'performance_bonuses', + '全勤奖': 'full_attendance_award', + '预发绩效奖金': 'performance_bonuses', # 0.8 '通讯补贴': 'commuting_allowance', '工龄工资': 'seniority_salary', '工会会费': 'union_dues', '住房公积金': 'housing_provident_fund', '企业(职业)年金': 'b_year', # 企业年金 } + # 定义比例常量,便于统一维护 + RATIO_80 = 0.8 + for line in internship_id.line_ids: - if line.name in target_names: - field_name = target_names[line.name] - # 初始化result为默认值,避免未赋值的情况 - result = 0 + if line.name not in target_names: + continue + field_name = target_names[line.name] + result = 0.0 # 初始化浮点型结果 - if field_name == 'performance_bonuses': - if work_days != days: - result = round(line.total * work_days / days) - else: - result = 0 - elif field_name in ['commuting_allowance', 'seniority_salary']: - if work_days != days: - result = line.total * internship_days / days + line.total * work_days / days - else: - result = line.total * internship_days / days - elif field_name in ['rank_salary', 'base_salary']: - if work_days != days: - result = round(math.ceil( - line.total * 0.8) * internship_days / days + line.total * work_days / days) - else: - result = line.total * 0.8 * internship_days / days - elif field_name == 'union_dues': # 单独处理工会会费 - base_salary = getattr(internship_id, 'base_salary', 0) - result = base_salary * 0.005 - elif field_name == 'housing_provident_fund': # 单独处理住房公积金 - # 获取合同入职日期的年份和月份 - contract_year = str(contract_start_date.year) - contract_month = str(contract_start_date.month) - # 判断是否为入职当月 - if contract_year == self.select_year and contract_month == self.select_time: - result = 0 # 入职当月住房公积金为0 - # 新增:非入职当月时的默认值(根据业务需求调整) - else: - result = abs(line.total)*-1 # 或其他合理默认值 - elif field_name == 'b_year': - # 获取合同转正日期的年份和月份 - if contract_end_date: # 确保转正日期存在 - contract_end_year = str(contract_end_date.year) - contract_end_month = str(contract_end_date.month) - # 判断是否为转正当月 - if contract_end_year == self.select_year and contract_end_month == self.select_time: - last_year_salary = internship_id.employee_id.last_year_salary or 0 - result = last_year_salary * 0.002 - else: - result = 0 # 非转正当月默认值 - else: - result = 0 # 无转正日期时的默认值 + # 计算80%比例的基础值(提前处理ceil逻辑)向上取整 + base_80 = math.ceil(line.total * RATIO_80) if field_name in ['rank_salary', 'base_salary', 'performance_bonuses'] else (line.total * RATIO_80) + + if field_name == 'performance_bonuses': + if work_days == days: + result = (base_80 * work_days + line.total * last_internship_days * RATIO_80) / days + elif field_name == 'full_attendance_award': + result = line.total * last_internship_days / days + elif field_name in ['commuting_allowance', 'seniority_salary']: + if work_days != days: + result = (line.total * internship_days + line.total * work_days + line.total * last_internship_days * RATIO_80) / days else: - if work_days != days: - result = line.total * 0.8 * internship_days / days + line.total * work_days / days - else: - result = line.total * 0.8 * internship_days / days + result = line.total * (internship_days + last_internship_days) / days + elif field_name in ['rank_salary', 'base_salary']: + if work_days != days: + result = ( base_80 * internship_days + base_80 * work_days + line.total * last_internship_days * RATIO_80) / days + else: + result = base_80 * (internship_days + last_internship_days) / days - setattr(internship_id, field_name, result) - line.write({'total': result}) + result = round(result, 2) + elif field_name == 'union_dues': # 单独处理工会会费 + base_salary = getattr(internship_id, 'base_salary', 0) + result = base_salary * 0.005 + elif field_name == 'housing_provident_fund': # 单独处理住房公积金 + # 获取合同入职日期的年份和月份 + contract_year = str(contract_start_date.year) + contract_month = str(contract_start_date.month) + # 判断是否为入职当月 + if contract_year == self.select_year and contract_month == self.select_time: + result = 0 # 入职当月住房公积金为0 + # 新增:非入职当月时的默认值(根据业务需求调整) + else: + result = abs(line.total)*-1 # 或其他合理默认值 + elif field_name == 'b_year': + # 获取合同转正日期的年份和月份 + if contract_end_date: # 确保转正日期存在 + contract_end_year = str(contract_end_date.year) + contract_end_month = str(contract_end_date.month) + # 判断是否为转正当月 + if contract_end_year == self.select_year and contract_end_month == self.select_time: + last_year_salary = internship_id.employee_id.last_year_salary or 0 + result = last_year_salary * 0.002 + else: + result = 0 # 非转正当月默认值 + else: + result = 0 # 无转正日期时的默认值 + else: + if work_days != days: + result = line.total * 0.8 * internship_days / days + line.total * work_days / days + else: + result = line.total * 0.8 * internship_days / days + setattr(internship_id, field_name, result) + line.write({'total': result}) if is_turnover: target_names = {