二次分配结果四舍五入功能开发

parent 258012cb
...@@ -27,6 +27,7 @@ public class SecondAllotController : ControllerBase ...@@ -27,6 +27,7 @@ public class SecondAllotController : ControllerBase
{ {
private readonly ILogger<SecondAllotController> _logger; private readonly ILogger<SecondAllotController> _logger;
private readonly ClaimService claimService; private readonly ClaimService claimService;
private readonly HospitalService _hospitalService;
private readonly AllotService _allotService; private readonly AllotService _allotService;
private readonly SecondAllotService secondAllotService; private readonly SecondAllotService secondAllotService;
private readonly ResultComputeService resultComputeService; private readonly ResultComputeService resultComputeService;
...@@ -36,6 +37,7 @@ public class SecondAllotController : ControllerBase ...@@ -36,6 +37,7 @@ public class SecondAllotController : ControllerBase
public SecondAllotController( public SecondAllotController(
ILogger<SecondAllotController> logger, ILogger<SecondAllotController> logger,
ClaimService claimService, ClaimService claimService,
HospitalService hospitalService,
AllotService allotService, AllotService allotService,
SecondAllotService secondAllotService, SecondAllotService secondAllotService,
ResultComputeService resultComputeService, ResultComputeService resultComputeService,
...@@ -45,6 +47,7 @@ RedistributionService redistributionService ...@@ -45,6 +47,7 @@ RedistributionService redistributionService
{ {
_logger = logger; _logger = logger;
this.claimService = claimService; this.claimService = claimService;
_hospitalService = hospitalService;
_allotService = allotService; _allotService = allotService;
this.secondAllotService = secondAllotService; this.secondAllotService = secondAllotService;
this.resultComputeService = resultComputeService; this.resultComputeService = resultComputeService;
...@@ -716,6 +719,11 @@ public ApiResponse RedistributionCompute([FromBody] SecondComputeDto request) ...@@ -716,6 +719,11 @@ public ApiResponse RedistributionCompute([FromBody] SecondComputeDto request)
var allot = _allotService.GetAllot(second.AllotId.Value); var allot = _allotService.GetAllot(second.AllotId.Value);
if (allot == null) if (allot == null)
throw new PerformanceException("绩效记录不存在!"); throw new PerformanceException("绩效记录不存在!");
var hospital = _hospitalService.GetHopital(allot.HospitalId);
if (hospital == null)
return new ApiResponse(ResponseType.Fail, "医院信息不存在");
// 年资职称绩效占比与工作量绩效占比 校验 // 年资职称绩效占比与工作量绩效占比 校验
var loads = _redistributionService.GetWorkLoads(allot, second); var loads = _redistributionService.GetWorkLoads(allot, second);
var workloadGroups = _redistributionService.GetTopWorkloadBodyGroups(loads); var workloadGroups = _redistributionService.GetTopWorkloadBodyGroups(loads);
...@@ -747,11 +755,11 @@ public ApiResponse RedistributionCompute([FromBody] SecondComputeDto request) ...@@ -747,11 +755,11 @@ public ApiResponse RedistributionCompute([FromBody] SecondComputeDto request)
throw new PerformanceException("提交参数都是无效数据,请重新填写数据后查看计算结果!"); throw new PerformanceException("提交参数都是无效数据,请重新填写数据后查看计算结果!");
// 计算提交数据结果 // 计算提交数据结果
_redistributionService.ResultCompute((ComputeMode)request.ComputeMode, request.Head, cleanDatas, loads, workloadGroups); _redistributionService.ResultCompute((ComputeMode)request.ComputeMode, request.Head, cleanDatas, loads, workloadGroups, hospital);
// 补充医院其他绩效 // 补充医院其他绩效
_redistributionService.SupplementOtherPerfor(second, cleanDatas); _redistributionService.SupplementOtherPerfor(second, cleanDatas);
// 重算部分数据 // 重算部分数据
_redistributionService.RedistributionCompute((ComputeMode)request.ComputeMode, request.Head, cleanDatas); _redistributionService.RedistributionCompute((ComputeMode)request.ComputeMode, request.Head, cleanDatas, hospital);
_redistributionService.ClearInvalidValue(cleanDatas); _redistributionService.ClearInvalidValue(cleanDatas);
var dic = _redistributionService.GetTableHeaderDictionary((ComputeMode)request.ComputeMode, allot, second, loads, workloadGroups); var dic = _redistributionService.GetTableHeaderDictionary((ComputeMode)request.ComputeMode, allot, second, loads, workloadGroups);
...@@ -788,6 +796,9 @@ public ApiResponse RedistributionSave([FromBody] SecondComputeDto request) ...@@ -788,6 +796,9 @@ public ApiResponse RedistributionSave([FromBody] SecondComputeDto request)
var allot = _allotService.GetAllot(second.AllotId.Value); var allot = _allotService.GetAllot(second.AllotId.Value);
if (allot == null) if (allot == null)
throw new PerformanceException("绩效记录不存在!"); throw new PerformanceException("绩效记录不存在!");
var hospital = _hospitalService.GetHopital(allot.HospitalId);
if (hospital == null)
return new ApiResponse(ResponseType.Fail, "医院信息不存在");
var loads = _redistributionService.GetWorkLoads(allot, second); var loads = _redistributionService.GetWorkLoads(allot, second);
var workloadGroups = _redistributionService.GetTopWorkloadBodyGroups(loads); var workloadGroups = _redistributionService.GetTopWorkloadBodyGroups(loads);
...@@ -807,11 +818,11 @@ public ApiResponse RedistributionSave([FromBody] SecondComputeDto request) ...@@ -807,11 +818,11 @@ public ApiResponse RedistributionSave([FromBody] SecondComputeDto request)
throw new PerformanceException("提交参数都是无效数据,请重新填写数据后保存!"); throw new PerformanceException("提交参数都是无效数据,请重新填写数据后保存!");
// 计算提交数据结果 // 计算提交数据结果
_redistributionService.ResultCompute((ComputeMode)request.ComputeMode, request.Head, cleanDatas, loads, workloadGroups); _redistributionService.ResultCompute((ComputeMode)request.ComputeMode, request.Head, cleanDatas, loads, workloadGroups, hospital);
// 补充医院其他绩效 // 补充医院其他绩效
_redistributionService.SupplementOtherPerfor(second, cleanDatas); _redistributionService.SupplementOtherPerfor(second, cleanDatas);
// 重算部分数据 // 重算部分数据
_redistributionService.RedistributionCompute((ComputeMode)request.ComputeMode, request.Head, cleanDatas); _redistributionService.RedistributionCompute((ComputeMode)request.ComputeMode, request.Head, cleanDatas, hospital);
var result = secondAllotService.RedistributionSave(allot, second, request.Head, cleanDatas); var result = secondAllotService.RedistributionSave(allot, second, request.Head, cleanDatas);
return result ? new ApiResponse(ResponseType.OK) : new ApiResponse(ResponseType.Fail, "保存失败"); return result ? new ApiResponse(ResponseType.OK) : new ApiResponse(ResponseType.Fail, "保存失败");
...@@ -847,6 +858,9 @@ public ApiResponse RedistributionSubmit([FromBody] SecondComputeDto request) ...@@ -847,6 +858,9 @@ public ApiResponse RedistributionSubmit([FromBody] SecondComputeDto request)
var allot = _allotService.GetAllot(second.AllotId.Value); var allot = _allotService.GetAllot(second.AllotId.Value);
if (allot == null) if (allot == null)
throw new PerformanceException("绩效记录不存在!"); throw new PerformanceException("绩效记录不存在!");
var hospital = _hospitalService.GetHopital(allot.HospitalId);
if (hospital == null)
return new ApiResponse(ResponseType.Fail, "医院信息不存在");
if (!new int[] { (int)AllotStates.绩效下发, (int)AllotStates.归档 }.Contains(allot.States)) if (!new int[] { (int)AllotStates.绩效下发, (int)AllotStates.归档 }.Contains(allot.States))
throw new PerformanceException("绩效未下发,无法提交!"); throw new PerformanceException("绩效未下发,无法提交!");
...@@ -871,11 +885,11 @@ public ApiResponse RedistributionSubmit([FromBody] SecondComputeDto request) ...@@ -871,11 +885,11 @@ public ApiResponse RedistributionSubmit([FromBody] SecondComputeDto request)
throw new PerformanceException("提交参数都是无效数据,请重新填写数据后查看计算结果!"); throw new PerformanceException("提交参数都是无效数据,请重新填写数据后查看计算结果!");
// 计算提交数据结果 // 计算提交数据结果
_redistributionService.ResultCompute((ComputeMode)request.ComputeMode, request.Head, cleanDatas, loads, workloadGroups); _redistributionService.ResultCompute((ComputeMode)request.ComputeMode, request.Head, cleanDatas, loads, workloadGroups, hospital);
// 补充医院其他绩效 // 补充医院其他绩效
_redistributionService.SupplementOtherPerfor(second, cleanDatas); _redistributionService.SupplementOtherPerfor(second, cleanDatas);
// 重算部分数据 // 重算部分数据
_redistributionService.RedistributionCompute((ComputeMode)request.ComputeMode, request.Head, cleanDatas); _redistributionService.RedistributionCompute((ComputeMode)request.ComputeMode, request.Head, cleanDatas, hospital);
var saveResult = secondAllotService.RedistributionSave(allot, second, request.Head, cleanDatas); var saveResult = secondAllotService.RedistributionSave(allot, second, request.Head, cleanDatas);
......
...@@ -103,9 +103,7 @@ ...@@ -103,9 +103,7 @@
</ItemGroup> </ItemGroup>
<ProjectExtensions> <ProjectExtensions>
<VisualStudio> <VisualStudio><UserProperties appsettings_1json__JSONSchema="" appsettings_1localhost_1json__JsonSchema="https://cdn.jsdelivr.net/gh/roadrunner-server/roadrunner@latest/schemas/config/2.0.schema.json" /></VisualStudio>
<UserProperties appsettings_1json__JSONSchema="" />
</VisualStudio>
</ProjectExtensions> </ProjectExtensions>
</Project> </Project>
...@@ -8783,6 +8783,16 @@ ...@@ -8783,6 +8783,16 @@
是否显示调节系数 1 显示 2 不显示 是否显示调节系数 1 显示 2 不显示
</summary> </summary>
</member> </member>
<member name="P:Performance.EntityModels.sys_hospital.SecondRoundNumber">
<summary>
二次分配可分配绩效保留小数位数
</summary>
</member>
<member name="P:Performance.EntityModels.sys_hospital.SecondReservedRoundNumber">
<summary>
二次分配预留绩效保留小数位数
</summary>
</member>
<member name="T:Performance.EntityModels.sys_hospitalconfig"> <member name="T:Performance.EntityModels.sys_hospitalconfig">
<summary> <summary>
......
...@@ -130,5 +130,13 @@ public class sys_hospital ...@@ -130,5 +130,13 @@ public class sys_hospital
/// 是否显示调节系数 1 显示 2 不显示 /// 是否显示调节系数 1 显示 2 不显示
/// </summary> /// </summary>
public Nullable<int> IsShowAdjust { get; set; } public Nullable<int> IsShowAdjust { get; set; }
/// <summary>
/// 二次分配可分配绩效保留小数位数
/// </summary>
public Nullable<int> SecondRoundNumber { get; set; }
/// <summary>
/// 二次分配预留绩效保留小数位数
/// </summary>
public Nullable<int> SecondReservedRoundNumber { get; set; }
} }
} }
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
using System.Drawing; using System.Drawing;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace Performance.Services namespace Performance.Services
{ {
...@@ -1027,7 +1028,7 @@ private void otherPerformance(Dictionary<string, object> head, List<Dictionary<s ...@@ -1027,7 +1028,7 @@ private void otherPerformance(Dictionary<string, object> head, List<Dictionary<s
/// <param name="rows"></param> /// <param name="rows"></param>
/// <param name="loads"></param> /// <param name="loads"></param>
/// <param name="workloadGroups"></param> /// <param name="workloadGroups"></param>
public void ResultCompute(ComputeMode computeMode, Dictionary<string, object> head, List<Dictionary<string, object>> rows, List<TitleValue<string, decimal?>> loads, List<SecondWorkLoadDto> workloadGroups) public void ResultCompute(ComputeMode computeMode, Dictionary<string, object> head, List<Dictionary<string, object>> rows, List<TitleValue<string, decimal?>> loads, List<SecondWorkLoadDto> workloadGroups, sys_hospital hospital)
{ {
var specialPostName = new string[] { "科主任/护士长", "主任", "是", }; var specialPostName = new string[] { "科主任/护士长", "主任", "是", };
...@@ -1043,6 +1044,8 @@ public void ResultCompute(ComputeMode computeMode, Dictionary<string, object> he ...@@ -1043,6 +1044,8 @@ public void ResultCompute(ComputeMode computeMode, Dictionary<string, object> he
preDeptRewardCalculate(rows); preDeptRewardCalculate(rows);
// 行内可分配绩效 // 行内可分配绩效
distPerformanceCalculate(rows); distPerformanceCalculate(rows);
// 行内预留绩效
reservedAmountCalculate(rows, hospital.SecondReservedRoundNumber ?? 2);
// 行内实发绩效 // 行内实发绩效
realAmountCalculate(rows); realAmountCalculate(rows);
} }
...@@ -1069,7 +1072,9 @@ public void ResultCompute(ComputeMode computeMode, Dictionary<string, object> he ...@@ -1069,7 +1072,9 @@ public void ResultCompute(ComputeMode computeMode, Dictionary<string, object> he
// 行内可分配绩效 // 行内可分配绩效
distPerformanceCalculate(rows); distPerformanceCalculate(rows);
// 差额从主任或第一个人身上扣除 // 差额从主任或第一个人身上扣除
balanceTotalDistPerformance(head, rows, specialPostName); balanceTotalDistPerformance(head, rows, specialPostName, hospital.SecondRoundNumber ?? 2);
// 行内预留绩效
reservedAmountCalculate(rows, hospital.SecondReservedRoundNumber ?? 2);
// 行内实发绩效 // 行内实发绩效
realAmountCalculate(rows); realAmountCalculate(rows);
} }
...@@ -1080,10 +1085,13 @@ public void ResultCompute(ComputeMode computeMode, Dictionary<string, object> he ...@@ -1080,10 +1085,13 @@ public void ResultCompute(ComputeMode computeMode, Dictionary<string, object> he
/// </summary> /// </summary>
/// <param name="head"></param> /// <param name="head"></param>
/// <param name="rows"></param> /// <param name="rows"></param>
public void RedistributionCompute(ComputeMode computeMode, Dictionary<string, object> head, List<Dictionary<string, object>> rows) public void RedistributionCompute(ComputeMode computeMode, Dictionary<string, object> head, List<Dictionary<string, object>> rows, sys_hospital hospital)
{ {
var specialPostName = new string[] { "科主任/护士长", "主任", "是", };
// 重算顶部医院其他绩效 // 重算顶部医院其他绩效
otherPerformance(head, rows); otherPerformance(head, rows);
// 行内预留绩效
reservedAmountCalculate(rows, hospital.SecondReservedRoundNumber ?? 2);
// 重算行内实发绩效 // 重算行内实发绩效
realAmountCalculate(rows); realAmountCalculate(rows);
} }
...@@ -1424,14 +1432,27 @@ private void distPerformanceCalculate(List<Dictionary<string, object>> rows) ...@@ -1424,14 +1432,27 @@ private void distPerformanceCalculate(List<Dictionary<string, object>> rows)
/// <param name="head"></param> /// <param name="head"></param>
/// <param name="rows"></param> /// <param name="rows"></param>
/// <param name="specialPostName"></param> /// <param name="specialPostName"></param>
private void balanceTotalDistPerformance(Dictionary<string, object> head, List<Dictionary<string, object>> rows, string[] specialPostName) private void balanceTotalDistPerformance(Dictionary<string, object> head, List<Dictionary<string, object>> rows, string[] specialPostName, int roundNumber)
{ {
var totalPerformance = GetDecimal2(head, nameof(ag_headsource.TotalPerformance)); var totalPerformance = GetDecimal2(head, nameof(ag_headsource.TotalPerformance));
var totalPreAccountingReward = GetDecimal2(head, nameof(ag_headsource.TotalPreAccountingReward)); var totalPreAccountingReward = GetDecimal2(head, nameof(ag_headsource.TotalPreAccountingReward));
var total_distPerformance = rows.Sum(row => GetDecimal2(row, nameof(ag_bodysource.DistPerformance)));
var difference = total_distPerformance - (totalPerformance + totalPreAccountingReward);
if (Math.Abs(difference) <= 1) // 2023-01-13李崇荣提出动态小数位个数处理
//var total_distPerformance = rows.Sum(row => GetDecimal2(row, nameof(ag_bodysource.DistPerformance)));
var total_distPerformance = 0m;
roundNumber = roundNumber >= 0 && roundNumber <= 4 ? roundNumber : 2;
foreach (var row in rows)
{
// 可分配绩效
var distPerformance = row.GetDecimal(nameof(ag_bodysource.DistPerformance));
// 小数尾数处理
distPerformance = Math.Round(distPerformance, roundNumber, MidpointRounding.AwayFromZero);
total_distPerformance += distPerformance;
row.AddOrUpdate(nameof(ag_bodysource.DistPerformance), distPerformance);
}
var difference = total_distPerformance - (totalPerformance + totalPreAccountingReward);
if (roundNumber == 0 || Math.Abs(difference) <= 1)
{ {
var atRow = rows.Where(row => specialPostName.Contains(row.GetString(nameof(ag_bodysource.Post)))); var atRow = rows.Where(row => specialPostName.Contains(row.GetString(nameof(ag_bodysource.Post))));
if (atRow == null || atRow.Count() == 0) if (atRow == null || atRow.Count() == 0)
...@@ -1439,25 +1460,46 @@ private void balanceTotalDistPerformance(Dictionary<string, object> head, List<D ...@@ -1439,25 +1460,46 @@ private void balanceTotalDistPerformance(Dictionary<string, object> head, List<D
if (atRow != null && atRow.Count() > 0) if (atRow != null && atRow.Count() > 0)
{ {
var distPerformance = GetDecimal2(atRow.ElementAt(0), nameof(ag_bodysource.DistPerformance)); for (int i = 0; i < atRow.Count(); i++)
atRow.ElementAt(0).AddOrUpdate(nameof(ag_bodysource.DistPerformance), distPerformance - difference); {
var row = atRow.ElementAt(i);
var distPerformance = GetDecimal2(row, nameof(ag_bodysource.DistPerformance));
if (distPerformance == 0) continue; // 0不扣减
row.AddOrUpdate(nameof(ag_bodysource.DistPerformance), distPerformance - difference);
}
} }
} }
} }
/// <summary> /// <summary>
/// 行内实发绩效 /// 行内预留绩效
/// </summary> /// </summary>
/// <param name="head"></param> /// <param name="head"></param>
/// <param name="rows"></param> /// <param name="rows"></param>
/// <param name="specialPostName"></param> /// <param name="specialPostName"></param>
private void realAmountCalculate(List<Dictionary<string, object>> rows) private void reservedAmountCalculate(List<Dictionary<string, object>> rows, int roundNumber)
{ {
roundNumber = roundNumber >= 0 && roundNumber <= 4 ? roundNumber : 2;
foreach (var row in rows) foreach (var row in rows)
{ {
// ReservedAmount 年度考核发放金额 DistPerformance 可分配绩效 // ReservedAmount 年度考核发放金额 DistPerformance 可分配绩效
var reservedAmount = GetDecimal2(row, nameof(ag_bodysource.DistPerformance)) * GetDecimal2(row, nameof(ag_bodysource.ReservedRatio)); var reservedAmount = GetDecimal2(row, nameof(ag_bodysource.DistPerformance)) * GetDecimal2(row, nameof(ag_bodysource.ReservedRatio));
// 尾数动态保留位数
reservedAmount = Math.Round(reservedAmount, roundNumber, MidpointRounding.AwayFromZero);
row.AddOrUpdate(nameof(ag_bodysource.ReservedAmount), reservedAmount); row.AddOrUpdate(nameof(ag_bodysource.ReservedAmount), reservedAmount);
}
}
/// <summary>
/// 行内实发绩效
/// </summary>
/// <param name="head"></param>
/// <param name="rows"></param>
/// <param name="specialPostName"></param>
private void realAmountCalculate(List<Dictionary<string, object>> rows)
{
foreach (var row in rows)
{
// 实发绩效 = 可分配绩效 - 预留绩效 + 夜班工作量绩效  // 实发绩效 = 可分配绩效 - 预留绩效 + 夜班工作量绩效 
var realAmount = GetDecimal2(row, nameof(ag_bodysource.DistPerformance)) - GetDecimal2(row, nameof(ag_bodysource.ReservedAmount)) + GetDecimal2(row, nameof(ag_bodysource.NightWorkPerformance)); var realAmount = GetDecimal2(row, nameof(ag_bodysource.DistPerformance)) - GetDecimal2(row, nameof(ag_bodysource.ReservedAmount)) + GetDecimal2(row, nameof(ag_bodysource.NightWorkPerformance));
row.AddOrUpdate(nameof(ag_bodysource.RealAmount), realAmount); row.AddOrUpdate(nameof(ag_bodysource.RealAmount), realAmount);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment