Commit 15e62c9a by 799284587@qq.com

Merge branch '本地新都测试表核对' into develop

parents e6133e28 744355d3
......@@ -13,7 +13,7 @@
},
"Application": {
//登录过期时间
"ExpirationMinutes": "5",
"ExpirationMinutes": "420",
//验证码过期
"SmsCodeMinutes": "5",
//护士长二次绩效管理员
......
......@@ -61,43 +61,116 @@ public enum SheetType
/// <summary>
/// 绩效类型
/// </summary>
public enum PerformanceType
//public enum PerformanceType
//{
// /// <summary> </summary>
// [Description("")]
// Null = 0,
// /// <summary> 绩效基数临床科室主任(专门用来计算科主任绩效,由此产生=>>临床科室主任人均绩效)</summary>
// [Description("绩效基数临床科室主任")]
// StandardDirector = 1,
// /// <summary> 绩效基数临床科室副主任(专门用来计算科主任绩效,由此产生=>>临床科室副主任人均绩效) </summary>
// [Description("绩效基数临床科室副主任")]
// StandardDeputyDirector = 2,
// /// <summary> 绩效基数临床科室护士长(专门用来计算科主任绩效,由此产生=>>临床科室护士长人均绩效) </summary>
// [Description("绩效基数临床科室护士长")]
// StandardNurse = 3,
// /// <summary> 绩效基数医技科室主任(专门用来计算科主任绩效,由此产生=>>医技科室主任人均绩效) </summary>
// [Description("绩效基数医技科室主任")]
// StandardDirectorYJ = 14,
// /// <summary> 临床科室主任人均绩效 (绩效标准取 科室主任人均绩效) </summary>
// [Description("临床科室主任人均绩效")]
// ReferenceDirector = 4,
// /// <summary> 临床科室中层人均绩效 (绩效标准取 科室主任/护士长/科室副主任/医技主任 平均值) </summary>
// [Description("临床科室中层人均绩效")]
// ReferenceDirectorAvg = 5,
// /// <summary> 临床科室护士长人均绩效 (绩效标准取 护士长 平均值)</summary>
// [Description("临床科室护士长人均绩效")]
// ReferenceHeadNurse = 7,
// /// <summary> 临床科室副主任人均绩效 </summary>
// [Description("临床科室副主任人均绩效")]
// ReferenceDeputyDirector = 8,
// /// <summary> 临床科室医生人均绩效 </summary>
// [Description("临床科室医生人均绩效")]
// ReferenceDoctor = 9,
// /// <summary> 临床科室护士人均绩效 </summary>
// [Description("临床科室护士人均绩效")]
// ReferenceNurse = 10,
// /// <summary> 行政工勤人均绩效 </summary>
// [Description("行政工勤人均绩效")]
// LogisticsWorker = 11,
// /// <summary> 行政中层人均绩效 </summary>
// [Description("行政中层人均绩效")]
// MiddleManager = 12,
// /// <summary> 行政高层人均绩效 </summary>
// [Description("行政高层人均绩效")]
// TopManager = 13,
//}
/// <summary>
/// 核算单元类型
/// </summary>
public enum AccountUnitType
{
/// <summary> </summary>
[Description("")]
Null = 0,
/// <summary> 绩效基数临床科室主任(专门用来计算科主任绩效,由此产生=>>临床科室主任人均绩效)</summary>
[Description("绩效基数临床科室主任")]
StandardDirector = 1,
/// <summary> 绩效基数临床科室副主任(专门用来计算科主任绩效,由此产生=>>临床科室副主任人均绩效) </summary>
[Description("绩效基数临床科室副主任")]
StandardDeputyDirector = 2,
/// <summary> 绩效基数临床科室护士长(专门用来计算科主任绩效,由此产生=>>临床科室护士长人均绩效) </summary>
[Description("绩效基数临床科室护士长")]
StandardNurse = 3,
Null = 1,
/// <summary> 临床科室 </summary>
[Description("临床科室")]
临床科室 = 2,
/// <summary> 临床科室 </summary>
[Description("医技科室")]
医技科室 = 3,
/// <summary> 行政高层 </summary>
[Description("行政高层")]
行政高层 = 4,
/// <summary> 临床科室 </summary>
[Description("行政中层")]
行政中层 = 5,
/// <summary> 临床科室 </summary>
[Description("行政工勤")]
行政工勤 = 6,
}
/// <summary> 临床科室主任人均绩效 (绩效标准取 科室主任人均绩效) </summary>
public enum PerforType
{
[Description("临床科室主任人均绩效")]
ReferenceDirector = 4,
/// <summary> 临床科室中层人均绩效 (绩效标准取 科室主任/护士长/科室副主任/医技主任 平均值) </summary>
[Description("临床科室中层人均绩效")]
ReferenceDirectorAvg = 5,
/// <summary> 临床科室护士长人均绩效 (绩效标准取 护士长 平均值)</summary>
[Description("临床科室护士长人均绩效")]
ReferenceHeadNurse = 7,
/// <summary> 临床科室副主任人均绩效 </summary>
临床主任,
[Description("临床科室副主任人均绩效")]
ReferenceDeputyDirector = 8,
/// <summary> 临床科室医生人均绩效 </summary>
[Description("临床科室医生人均绩效")]
ReferenceDoctor = 9,
/// <summary> 临床科室护士人均绩效 </summary>
[Description("临床科室护士人均绩效")]
ReferenceNurse = 10,
/// <summary> 行政工勤人均绩效 </summary>
临床副主任,
[Description("医技科室主任人均绩效")]
医技主任,
[Description("医技科室副主任人均绩效")]
医技副主任,
[Description("护士长人均绩效")]
护士长,
[Description("护士人均绩效")]
护士,
[Description("临床主任护士长平均")]
临床主任护士长平均,
[Description("临床医生人均绩效")]
临床医生,
[Description("医技医生人均绩效")]
医技医生,
[Description("行政中层人均绩效")]
行政中层,
[Description("行政工勤人均绩效")]
LogisticsWorker = 11,
行政工勤,
}
/// <summary>
/// 当前枚举为效率绩效、规模绩效中系数中文名称
/// 对应表cof_director中JobTitle 全文字匹配
/// </summary>
public enum DirectorType
{
临床科室主任,
临床科室副主任,
医技科室主任,
医技科室副主任,
临床科室护士长,
}
}
......@@ -60,36 +60,27 @@ public class PerDataAccountDoctor : IPerData
/// </summary>
public decimal Income { get; set; }
/// <summary>
/// 工作量绩效
/// </summary>
public decimal WorkloadFee { get; set; }
private decimal perforFee;
private decimal perforTotal;
private decimal avg;
private decimal giveFee;
/// <summary>
/// 绩效合计
/// </summary>
public decimal PerforTotal { get => PerforFee + WorkloadFee + OtherPerfor1; set => perforTotal = value; }
public decimal PerforTotal { get; set; }
/// <summary>
/// 业绩绩效
/// </summary>
public decimal PerforFee { get => Income * (BasicFactor + (BasicFactor * SlopeFactor)); set => perforFee = value; }
public decimal PerforFee { get; set; }
/// <summary>
/// 实发绩效
/// </summary>
public decimal RealGiveFee { get => (PerforTotal * ScoringAverage + Extra + OtherPerfor2) * (AdjustFactor == 0 ? 1 : AdjustFactor); set => giveFee = value; }
public decimal RealGiveFee { get; set; }
/// <summary>
/// 人均绩效
/// </summary>
public decimal Avg { get => Number == 0 ? 0 : PerforTotal / Number; set => avg = value; }
public decimal Avg { get; set; }
}
}
......@@ -65,30 +65,23 @@ public class PerDataAccountNurse : IPerData
/// </summary>
public decimal WorkloadFee { get; set; }
private decimal perforFee;
private decimal perforTotal;
private decimal avg;
private decimal giveFee;
/// <summary>
/// 绩效合计
/// </summary>
public decimal PerforTotal { get => PerforFee + WorkloadFee + OtherPerfor1; set => perforTotal = value; }
public decimal PerforTotal { get; set; }
/// <summary>
/// 业绩绩效
/// </summary>
public decimal PerforFee { get => Income * (BasicFactor + (BasicFactor * SlopeFactor)); set => perforFee = value; }
public decimal PerforFee { get; set; }
/// <summary>
/// 实发绩效
/// </summary>
public decimal RealGiveFee { get => (PerforTotal * ScoringAverage + Extra + OtherPerfor2) * (AdjustFactor == 0 ? 1 : AdjustFactor); set => giveFee = value; }
public decimal RealGiveFee { get; set; }
/// <summary>
/// 人均绩效
/// </summary>
public decimal Avg { get => Number == 0 ? 0 : PerforTotal / Number; set => avg = value; }
public decimal Avg { get; set; }
}
}
......@@ -32,6 +32,11 @@ public class res_compute
public Nullable<int> SheetID { get; set; }
/// <summary>
/// 核算单元类型(医技科室、临床科室等)
/// </summary>
public string AccountType { get; set; }
/// <summary>
/// 核算单元
/// </summary>
public string AccountingUnit { get; set; }
......
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
......@@ -7,47 +8,99 @@
namespace Performance.Services.AllotCompute
{
/// <summary>
/// 绩效标准数据
/// </summary>
public class BaiscNormService : IAutoInjection
{
/// <summary>
/// 获取绩效标准基础值
/// 绩效标准计算 主任 副主任 护士长
/// </summary>
/// <param name="baiscnorms"></param>
/// <param name="type"></param>
/// <param name="computes"></param>
/// <returns></returns>
public decimal? GetBaiscNorm(List<res_baiscnorm> baiscnorms, PerformanceType type)
public List<res_baiscnorm> ComputeAvg(List<res_baiscnorm> baiscnormList, List<ComputeResult> computes, List<im_employee> empolyeeList)
{
decimal? result = null;
if (type == PerformanceType.ReferenceDirector || type == PerformanceType.Null)
var keyList = new[]
{
result = baiscnorms.FirstOrDefault(t => t.PositionName == "临床科主任")?.AvgValue;
}
else if (type == PerformanceType.ReferenceDirectorAvg)
//绩效基数平均值项目
new { type = AccountUnitType.临床科室, reference = PerforType.临床主任 },
new { type = AccountUnitType.临床科室, reference = PerforType.临床副主任 },
new { type = AccountUnitType.临床科室, reference = PerforType.护士长 },
new { type = AccountUnitType.医技科室, reference = PerforType.医技主任 },
new { type = AccountUnitType.医技科室, reference = PerforType.医技副主任 },
};
foreach (var item in keyList)
{
List<string> avgObjectList = new List<string> { "临床科主任", "临床科副主任", "医技科主任", "临床科护长" };
var baisc = baiscnorms.Where(t => avgObjectList.Contains(t.PositionName));
result = baisc.Sum(s => s.TotelValue) / baisc.Sum(s => s.TotelNumber);
var count = empolyeeList.Count(t => t.AccountType == item.type.ToString() && t.FitPeople == EnumHelper.GetDescription(item.reference));
if (count > 0)
{
var dataList = computes.Where(t => t.AccountType == item.type.ToString() && t.FitPeople == EnumHelper.GetDescription(item.reference));
var baiscnorm = new res_baiscnorm
{
PositionName = EnumHelper.GetDescription(item.reference),
TotelNumber = count,
TotelValue = dataList.Sum(t => t.GiveFee),
AvgValue = dataList.Sum(t => t.GiveFee) / count
};
baiscnormList.Add(baiscnorm);
}
}
else if (type == PerformanceType.ReferenceHeadNurse)
return baiscnormList;
}
/// <summary>
/// 院领导、行政中层、行政工勤 平均值
/// </summary>
/// <param name="computes"></param>
/// <returns></returns>
public List<res_baiscnorm> ComputeOtherAvg(List<res_baiscnorm> baiscnormList, List<ComputeResult> computes, List<im_employee> empolyeeList)
{
var keyList = new[]
{
result = baiscnorms.FirstOrDefault(t => t.PositionName == "临床科护长")?.AvgValue;
}
else if (type == PerformanceType.ReferenceNurse)
//行政绩效平均值项目
new { type = AccountUnitType.行政中层, reference = PerforType.行政中层 },
new { type = AccountUnitType.行政工勤, reference = PerforType.行政工勤 },
};
foreach (var item in keyList)
{
result = baiscnorms.FirstOrDefault(t => t.PositionName == "临床护士")?.AvgValue;
var count = empolyeeList.Count(t => t.AccountType == item.type.ToString());
if (count > 0)
{
var dataList = computes.Where(t => t.AccountType == item.type.ToString());
var baiscnorm = new res_baiscnorm
{
PositionName = EnumHelper.GetDescription(item.reference),
TotelNumber = count,
TotelValue = dataList.Sum(t => t.GiveFee),
AvgValue = dataList.Sum(t => t.GiveFee) / count
};
baiscnormList.Add(baiscnorm);
}
}
else if (type == PerformanceType.ReferenceDoctor)
return baiscnormList;
}
/// <summary>
/// 获取绩效标准基础值
/// </summary>
/// <param name="baiscnorms"></param>
/// <param name="type"></param>
/// <returns></returns>
public decimal? GetBaiscNorm(List<res_baiscnorm> baiscnorms, PerforType type)
{
decimal? result = null;
if (type == PerforType.临床主任护士长平均)
{
result = baiscnorms.FirstOrDefault(t => t.PositionName == "临床医生")?.AvgValue;
var lczrValue = baiscnorms.FirstOrDefault(t => t.PositionName == EnumHelper.GetDescription(PerforType.临床主任))?.AvgValue;
var hszValue = baiscnorms.FirstOrDefault(t => t.PositionName == EnumHelper.GetDescription(PerforType.护士长))?.AvgValue;
result = ((lczrValue ?? 0) + (hszValue ?? 0)) / 2;
}
else if (type == PerformanceType.LogisticsWorker)
else
{
result = baiscnorms.FirstOrDefault(t => t.PositionName == "行政工勤")?.AvgValue;
result = baiscnorms.FirstOrDefault(t => t.PositionName == EnumHelper.GetDescription(type))?.AvgValue;
}
if (result.HasValue)
result = Math.Round(result.Value, 4);
return result;
......@@ -58,47 +111,19 @@ public class BaiscNormService : IAutoInjection
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
public res_baiscnorm NurseBaiscnorm(List<PerSheet> list)
public List<res_baiscnorm> NurseBaiscnorm(List<res_baiscnorm> baiscnormList, List<PerSheet> list)
{
var sheet = list.FirstOrDefault(t => t.SheetType == SheetType.ComputeNurseAccount);
var perdata = sheet.PerData.Select(t => (PerDataAccountNurse)t);
return new res_baiscnorm
var baiscnorm = new res_baiscnorm
{
PositionName = "临床护士",
PositionName = EnumHelper.GetDescription(PerforType.护士),
TotelNumber = perdata.Sum(t => t.Number),
TotelValue = perdata.Sum(t => t.PerforTotal),
AvgValue = perdata.Sum(t => t.PerforTotal) / perdata.Sum(t => t.Number)
};
}
/// <summary>
/// 绩效标准计算
/// </summary>
/// <param name="computes"></param>
/// <returns></returns>
public List<res_baiscnorm> ComputeAvg(List<ComputeResult> computes)
{
var keyList = new[]
{
new { type = "临床科室", reference = "科室主任人均绩效", groupname = "临床科主任" },
new { type = "临床科室", reference = "科室副主任人均绩效", groupname = "临床科副主任" },
new { type = "医技科室", reference = "科室主任人均绩效", groupname = "医技科主任" },
new { type = "临床科室", reference = "科室护士长人均绩效", groupname = "临床科护长" },
};
var groupList = from cp in computes
join gp in keyList on new { type = cp.AccountType, reference = cp.FitPeople } equals new { gp.type, gp.reference }
select new { gp.groupname, cp };
var result = groupList.GroupBy(t => t.groupname)
.Select(s => new res_baiscnorm
{
PositionName = s.Key,
TotelNumber = s.Count(),
TotelValue = s.Sum(t => t.cp.GiveFee),
AvgValue = s.Sum(t => t.cp.GiveFee) / s.Count()
});
return result.ToList();
baiscnormList.Add(baiscnorm);
return baiscnormList;
}
}
}
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Repository;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Performance.Infrastructure;
using System.Text;
namespace Performance.Services.AllotCompute
{
......@@ -156,12 +156,7 @@ public bool CheckData(PerExcel excel, per_allot allot)
if (sheet.SheetName.StartsWith("医院人员名单"))
{
List<string> accountType = new List<string>() { "临床科室", "医技科室", "行政工勤", "行政中高层", "" };
List<string> fitPeople = new List<string>();
foreach (var name in EnumHelper.GetNames<PerformanceType>())
{
var a = (int)Enum.Parse(typeof(PerformanceType), name);
fitPeople.Add(EnumHelper.GetDescription((PerformanceType)a));
}
List<string> fitPeople = EnumHelper.GetItems<PerforType>().Select(t => t.Description).ToList();
var dataList = sheet.PerData.Select(t => (PerDataEmployee)t);
foreach (var item in dataList)
{
......@@ -209,7 +204,7 @@ public bool CheckData(PerExcel excel, per_allot allot)
var dataList = sheet.PerData.Select(t => (PerDataAccountBaisc)t);
foreach (var item in dataList)
{
if (string.IsNullOrEmpty(item.AccountingUnit))
if (string.IsNullOrEmpty(item.AccountingUnit) && string.IsNullOrEmpty(item.Department))
{
flag = false;
rowNumber.Add(item.RowNumber + 1);
......
......@@ -223,38 +223,94 @@ private List<PerSheet> MergeCompute(PerExcel excel, int allotid)
var deptAccounting = excel.PerSheet.FirstOrDefault(t => t.SheetType == SheetType.AccountBasic);
var dataList = deptAccounting.PerData.Select(t => (PerDataAccountBaisc)t);
var doctorSheet = ComputeDoctor(dataList, twiceEconomicResult.PerData, twiceWorkloadResult1.PerData);
perSheet.Add(doctorSheet);
var nurseSheet = ComputeNurse(dataList, twiceEconomicResult.PerData, twiceWorkloadResult2.PerData);
perSheet.Add(nurseSheet);
return perSheet;
}
/// <summary>
/// 计算医生组科室绩效
/// </summary>
/// <param name="dataList"></param>
/// <param name="economicData"></param>
/// <param name="workloadData"></param>
/// <returns></returns>
private PerSheet ComputeDoctor(IEnumerable<PerDataAccountBaisc> dataList, List<PerData> economicData, List<PerData> workloadData)
{
PerSheet doctorSheet = new PerSheet("医生组临床科室单元核算表", "医生组临床科室单元核算表", SheetType.ComputeDoctorAccount, new List<PerHeader>(), new List<IPerData>());
PerSheet nurseSheet = new PerSheet("护理组临床科室单元核算表", "护理组临床科室单元核算表", SheetType.ComputeNurseAccount, new List<PerHeader>(), new List<IPerData>());
foreach (var dept in dataList)
{
var doctor = Mapper.Map<PerDataAccountDoctor>(dept);
var econDoctor = twiceEconomicResult.PerData.FirstOrDefault(t => t.UnitType == "医生组" && t.AccountingUnit == dept.AccountingUnit);
doctor.Income = econDoctor?.CellValue ?? 0;
var workDoctor = twiceWorkloadResult1.PerData.FirstOrDefault(t => t.UnitType == "医生组" && t.AccountingUnit == dept.AccountingUnit);
doctor.WorkloadFee = workDoctor?.CellValue ?? 0;
if (string.IsNullOrEmpty(dept.AccountingUnit)) continue;
var econDoctor = economicData.FirstOrDefault(t => t.UnitType == "医生组" && t.AccountingUnit == dept.AccountingUnit);
var workDoctor = workloadData.FirstOrDefault(t => t.UnitType == "医生组" && t.AccountingUnit == dept.AccountingUnit);
var doctor = new PerDataAccountDoctor
{
AccountingUnit = dept.AccountingUnit,
Department = dept.AccountingUnit,
Number = dept.DoctorNumber,
BasicFactor = dept.DoctorBasicFactor,
SlopeFactor = dept.DoctorSlopeFactor,
OtherPerfor1 = dept.DoctorOtherPerfor1,
OtherPerfor2 = dept.DoctorOtherPerfor2,
Extra = dept.DoctorExtra,
ScoringAverage = dept.DoctorScoringAverage == 0m ? 1 : dept.DoctorScoringAverage,
AdjustFactor = dept.DoctorAdjustFactor == 0m ? 1 : dept.DoctorAdjustFactor,
Income = econDoctor?.CellValue ?? 0,
WorkloadFee = workDoctor?.CellValue ?? 0,
};
doctor.PerforFee = doctor.Income * (doctor.BasicFactor + (doctor.BasicFactor * doctor.SlopeFactor));
doctor.PerforTotal = doctor.PerforFee + doctor.WorkloadFee + doctor.OtherPerfor1;
doctor.RealGiveFee = (doctor.PerforTotal * doctor.ScoringAverage + doctor.Extra + doctor.OtherPerfor2) * doctor.AdjustFactor;
doctor.Avg = doctor.Number == 0 ? 0 : doctor.PerforTotal / doctor.Number;
doctorSheet.PerData.Add(doctor);
}
return doctorSheet;
}
var nurse = Mapper.Map<PerDataAccountNurse>(dept);
if (nurse.AdjustFactor == 0m) nurse.AdjustFactor = 1;
if (nurse.ScoringAverage == 0m) nurse.ScoringAverage = 1;
var econNurse = twiceEconomicResult.PerData.FirstOrDefault(t => t.UnitType == "护理组" && t.AccountingUnit == dept.AccountingUnit);
nurse.Income = econNurse?.CellValue ?? 0;
var workNurse = twiceWorkloadResult2.PerData.FirstOrDefault(t => t.UnitType == "护理组" && t.AccountingUnit == dept.AccountingUnit);
nurse.WorkloadFee = workNurse?.CellValue ?? 0;
if (nurse.PerforTotal == 0m && nurse.Extra == 0m && nurse.OtherPerfor2 == 0m && nurse.ScoringAverage == 1m && nurse.AdjustFactor == 1m)
/// <summary>
/// 计算护理组科室绩效
/// </summary>
/// <param name="dataList"></param>
/// <param name="economicData"></param>
/// <param name="workloadData"></param>
private PerSheet ComputeNurse(IEnumerable<PerDataAccountBaisc> dataList, List<PerData> economicData, List<PerData> workloadData)
{
PerSheet nurseSheet = new PerSheet("护理组临床科室单元核算表", "护理组临床科室单元核算表", SheetType.ComputeNurseAccount, new List<PerHeader>(), new List<IPerData>());
foreach (var dept in dataList)
{
if (string.IsNullOrEmpty(dept.Department)) continue;
var econNurse = economicData.FirstOrDefault(t => t.UnitType == "护理组" && t.AccountingUnit == dept.Department);
var workNurse = workloadData.FirstOrDefault(t => t.UnitType == "护理组" && t.AccountingUnit == dept.Department);
var nurse = new PerDataAccountNurse
{
nurse.AdjustFactor = 0;
nurse.ScoringAverage = 0;
}
AccountingUnit = dept.Department,
Department = dept.Department,
Number = dept.NurseNumber,
BasicFactor = dept.NurseBasicFactor,
SlopeFactor = dept.NurseSlopeFactor,
OtherPerfor1 = dept.NurseOtherPerfor1,
OtherPerfor2 = dept.NurseOtherPerfor2,
Extra = dept.NurseExtra,
ScoringAverage = dept.NurseScoringAverage == 0m ? 1 : dept.NurseScoringAverage,
AdjustFactor = dept.NurseAdjustFactor == 0m ? 1 : dept.NurseAdjustFactor,
Income = econNurse?.CellValue ?? 0,
WorkloadFee = workNurse?.CellValue ?? 0,
};
nurse.PerforFee = nurse.Income * (nurse.BasicFactor + (nurse.BasicFactor * nurse.SlopeFactor));
nurse.PerforTotal = nurse.PerforFee + nurse.WorkloadFee + nurse.OtherPerfor1;
nurse.RealGiveFee = (nurse.PerforTotal * nurse.ScoringAverage + nurse.Extra + nurse.OtherPerfor2) * nurse.AdjustFactor;
nurse.Avg = nurse.Number == 0 ? 0 : nurse.PerforTotal / nurse.Number;
nurseSheet.PerData.Add(nurse);
}
perSheet.Add(doctorSheet);
perSheet.Add(nurseSheet);
return perSheet;
return nurseSheet;
}
/// <summary>
/// 获取药占比分割比例
/// </summary>
......
......@@ -15,32 +15,22 @@ namespace Performance.Services.AllotCompute
/// </summary>
public class ResultComputeService : IAutoInjection
{
private BaiscNormService baiscNormService;
private ComputeDirector computeDirector;
private PerforImemployeeRepository perforImEmployeeRepository;
private PerforCofworkyearRepository perforCofworkyearRepository;
private PerforCofdirectorRepository perforCofdirectorRepository;
private PerforResaccountdoctorRepository perforResAccountdoctorRepository;
private PerforResaccountnurseRepository perforResAccountnurseRepository;
private PerforRescomputeRepository perforRescomputeRepository;
private PerforResbaiscnormRepository perforResbaiscnormRepository;
private PerforResspecialunitRepository perforResspecialunitRepository;
public ResultComputeService(
PerforImemployeeRepository perforImEmployeeRepository,
PerforCofworkyearRepository perforCofworkyearRepository,
PerforCofdirectorRepository perforCofdirectorRepository,
PerforResaccountdoctorRepository perforResAccountdoctorRepository,
PerforResaccountnurseRepository perforResAccountnurseRepository,
PerforRescomputeRepository perforRescomputeRepository,
PerforResbaiscnormRepository perforResbaiscnormRepository,
PerforResspecialunitRepository perforResspecialunitRepository,
ComputeDirector computeDirector)
BaiscNormService baiscNormService, ComputeDirector computeDirector)
{
this.baiscNormService = baiscNormService;
this.computeDirector = computeDirector;
this.perforImEmployeeRepository = perforImEmployeeRepository;
this.perforCofworkyearRepository = perforCofworkyearRepository;
this.perforCofdirectorRepository = perforCofdirectorRepository;
this.perforResAccountdoctorRepository = perforResAccountdoctorRepository;
this.perforResAccountnurseRepository = perforResAccountnurseRepository;
this.perforRescomputeRepository = perforRescomputeRepository;
this.perforResbaiscnormRepository = perforResbaiscnormRepository;
this.perforResspecialunitRepository = perforResspecialunitRepository;
......@@ -50,34 +40,22 @@ public class ResultComputeService : IAutoInjection
/// 计算最终数据
/// </summary>
/// <param name="excel"></param>
public List<res_baiscnorm> Compute(per_allot allot, PerExcel excel, res_baiscnorm baiscnorm)
public List<res_baiscnorm> Compute(per_allot allot, PerExcel excel, List<PerSheet> perSheets)
{
//取出人员信息
var empolyeeList = perforImEmployeeRepository.GetEntities(t => t.AllotID == allot.ID);
//年资系数
var workyearList = perforCofworkyearRepository.GetEntities(t => t.AllotID == allot.ID);
//规模绩效和效率绩效配置表
var directorList = perforCofdirectorRepository.GetEntities(t => t.AllotID == allot.ID);
//取出医生科室
var doctorList = perforResAccountdoctorRepository.GetEntities(t => t.AllotID == allot.ID);
//取出护士科室
var nurseList = perforResAccountnurseRepository.GetEntities(t => t.AllotID == allot.ID);
List<ComputeEmployee> computeEmployees = Mapper.Map<List<ComputeEmployee>>(empolyeeList);
List<ComputeSource> computeSources = new List<ComputeSource>();
computeSources.AddRange(Mapper.Map<List<ComputeSource>>(doctorList));
computeSources.AddRange(Mapper.Map<List<ComputeSource>>(nurseList));
var computResult = computeDirector.Compute(computeEmployees, computeSources, directorList);
var computResult = computeDirector.Compute(computeEmployees, allot);
//计算 绩效标准 基数(科主任、副主任、护士长 =>> 平均值)
var baiscnormList = computeDirector.ComputeAvg(computResult);
baiscnormList.Add(baiscnorm);
List<res_baiscnorm> baiscnormList = new List<res_baiscnorm>();
baiscNormService.ComputeAvg(baiscnormList, computResult, empolyeeList);
baiscNormService.NurseBaiscnorm(baiscnormList, perSheets);
var computResult2 = computeDirector.Compute(computeEmployees, baiscnormList, workyearList);
var computResult2 = computeDirector.Compute(computeEmployees, allot, baiscnormList);
//计算 行政人员 平均值
var baiscnormList2 = computeDirector.ComputeOtherAvg(computResult2);
baiscnormList.AddRange(baiscnormList2);
baiscNormService.ComputeOtherAvg(baiscnormList, computResult2, empolyeeList);
var computes = Mapper.Map<List<res_compute>>(computResult);
computes.AddRange(Mapper.Map<List<res_compute>>(computResult2));
......@@ -101,40 +79,62 @@ public void SpecialUnitCompute(PerExcel excel, per_allot allot, List<res_baiscno
var specialUnit = excel.PerSheet.FirstOrDefault(t => t.SheetType == SheetType.SpecialUnit);
if (specialUnit == null || specialUnit.PerData.Count == 0)
return;
var typeList = EnumHelper.GetItems<PerforType>();
var dataList = specialUnit.PerData.Select(t => (PerDataSpecialUnit)t);
BaiscNormService baiscNormService = new BaiscNormService();
var typeList = EnumHelper.GetItems<PerformanceType>();
List<res_specialunit> resDataList = new List<res_specialunit>();
foreach (var t in dataList)
//替换考核基数
foreach (var item in dataList)
{
var type = typeList.FirstOrDefault(o => o.Description == t.QuantitativeIndicators);
var type = typeList.FirstOrDefault(o => o.Description == item.QuantitativeIndicators);
if (type != null)
{
var radio = perforImEmployeeRepository.GetEntities(p => p.FitPeople == EnumHelper.GetDescription((PerformanceType)type.Value) && p.AllotID == allot.ID)
var radio = perforImEmployeeRepository.GetEntities(p => p.FitPeople == EnumHelper.GetDescription((PerforType)type.Value) && p.AllotID == allot.ID)
?.FirstOrDefault().FitPeopleRatio ?? 1;
var basic = baiscNormService.GetBaiscNorm(baiscnormList, (PerformanceType)type.Value);
t.Quantity = basic != null ? basic * radio : 0; //添加参数计算
var basic = baiscNormService.GetBaiscNorm(baiscnormList, (PerforType)type.Value);
// 添加参数计算
// 新都医院在特殊科室计算时,如果取核算基数计算时带入人数计算
item.Quantity = basic != null ? basic * radio * (!item.Number.HasValue || item.Number == 0 ? 1 : item.Number) : null;
}
}
List<res_specialunit> resDataList = new List<res_specialunit>();
var groupSpeList = dataList.GroupBy(t => t.AccountingUnit).Select(t => new
{
AccountingUnit = t.Key,
Number = t.Sum(p => p.Number),
ScoringAverage = t.Sum(p => p.ScoringAverage),
OtherPerfor = t.Sum(p => p.OtherPerfor),
Punishment = t.Sum(p => p.Punishment),
Adjust = t.Sum(p => p.Adjust),
});
var res = new res_specialunit
foreach (var group in groupSpeList)
{
//获取需要聚合的科室
var accountDataList = dataList.Where(t => t.AccountingUnit == group.AccountingUnit);
//计算量化指标子项合计
var sumValue = accountDataList.Sum(t => t.Quantity * t.QuantitativeIndicatorsValue);
foreach (var item in accountDataList)
{
AllotID = allot.ID,
AccountingUnit = t.AccountingUnit,
Department = t.AccountingUnit,
Number = t.Number,
QuantitativeIndicators = t.QuantitativeIndicators,
Quantity = t.Quantity,
QuantitativeIndicatorsValue = t.QuantitativeIndicatorsValue,
ScoringAverage = t.ScoringAverage,
OtherPerfor = t.OtherPerfor,
Punishment = t.Punishment,
Adjust = t.Adjust ?? 1,
Avg = t.Number != 0 ? t.Quantity * t.QuantitativeIndicatorsValue / t.Number : null,
GiveFee = t.Quantity * t.QuantitativeIndicatorsValue,
RealGiveFee = (t.Quantity * t.QuantitativeIndicatorsValue + (t.OtherPerfor ?? 0) + (t.Punishment ?? 0)) * (t.Adjust ?? 1),
};
resDataList.Add(res);
var res = new res_specialunit
{
AllotID = allot.ID,
AccountingUnit = group.AccountingUnit,
Department = group.AccountingUnit,
Number = group.Number,
QuantitativeIndicators = item.QuantitativeIndicators,
Quantity = item.Quantity,
QuantitativeIndicatorsValue = item.QuantitativeIndicatorsValue,
ScoringAverage = group.ScoringAverage,
OtherPerfor = group.OtherPerfor,
Punishment = group.Punishment,
Adjust = group.Adjust == 0 ? 1 : group.Adjust,
Avg = group.Number != 0 ? sumValue / group.Number : null,
GiveFee = sumValue,
RealGiveFee = (sumValue + (group.OtherPerfor ?? 0) + (group.Punishment ?? 0)) * (group.Adjust == 0 ? 1 : group.Adjust),
};
resDataList.Add(res);
}
}
perforResspecialunitRepository.AddRange(resDataList.ToArray());
}
......
......@@ -220,11 +220,11 @@ public void Generate(per_allot allot, string mail)
logdbug.Add(allot.ID, "计算合并数据", JsonHelper.Serialize(allot));
List<PerSheet> list = processComputService.MergeAndSave(excel, allot);
var baiscnorm = baiscNormService.NurseBaiscnorm(list);
logdbug.Add(allot.ID, "护士平均绩效", JsonHelper.Serialize(baiscnorm));
//var baiscnorm = baiscNormService.NurseBaiscnorm(list);
//logdbug.Add(allot.ID, "护士平均绩效", JsonHelper.Serialize(baiscnorm));
// 计算最总数据
logdbug.Add(allot.ID, "绩效结果计算数据开始", "");
var baiscnormList = resultComputeService.Compute(allot, excel, baiscnorm);
var baiscnormList = resultComputeService.Compute(allot, excel, list);
resultComputeService.SpecialUnitCompute(excel, allot, baiscnormList);
_allotRepository.UpdateAllotStates(allot.ID, (int)AllotStates.GenerateSucceed, EnumHelper.GetDescription(AllotStates.GenerateSucceed));
......
......@@ -51,27 +51,40 @@ public class ComputeService : IAutoInjection
public List<ResComputeResponse> GetCompute(int allotId, int type)
{
var data = new List<ResComputeResponse>();
Dictionary<int, List<PerformanceType>> keyValues = new Dictionary<int, List<PerformanceType>>
{
{ 1,new List<PerformanceType>{ PerformanceType.ReferenceDirector } },
{ 2,new List<PerformanceType>{ PerformanceType.ReferenceDirectorAvg } },
{ 3,new List<PerformanceType>{ PerformanceType.LogisticsWorker, PerformanceType.ReferenceHeadNurse, PerformanceType.ReferenceNurse, PerformanceType.Null } },
{ 4,new List<PerformanceType>{ PerformanceType.ReferenceDoctor, PerformanceType.StandardDeputyDirector } },
{ 5,new List<PerformanceType>{ PerformanceType.ReferenceNurse } }
};
List<res_compute> conpute = new List<res_compute>();
if (keyValues.ContainsKey(type))
if ((new int[] { 1, 2, 3 }).Contains(type))
{
var conList = keyValues[type].Select(t => EnumHelper.GetDescription(t));
var list = _perforRescomputeRepository.GetEntities(t => t.AllotID == allotId && conList.Contains(t.FitPeople))
?.OrderBy(t => t.AccountingUnit).ThenBy(t => t.FitPeople).ToList();
data = Mapper.Map<List<ResComputeResponse>>(list);
data?.ForEach(t => t.WorkTime = string.IsNullOrEmpty(t.WorkTime) ? null : Convert.ToDateTime(t.WorkTime).ToString("yyyy-MM-dd"));
var keyValues2 = new[]
{
new { type = 1, accounttype = AccountUnitType.行政高层 },
new { type = 2, accounttype = AccountUnitType.行政中层 },
new { type = 3, accounttype = AccountUnitType.行政工勤 },
};
var obj = keyValues2.First(t => t.type == type);
conpute = _perforRescomputeRepository.GetEntities(t => t.AllotID == allotId && t.AccountType == obj.accounttype.ToString())
?.OrderBy(t => t.AccountingUnit).ThenBy(t => t.FitPeople).ToList();
}
else if ((new int[] { 4, 5 }).Contains(type))
{
var types = new PerforType[] { PerforType.临床主任, PerforType.临床副主任, PerforType.医技主任, PerforType.医技副主任 };
var keyValues2 = new[]
{
new { type = 4, accounttype = types.Select(t=>EnumHelper.GetDescription(t)).ToList() },
new { type = 5, accounttype = new List<string>{ EnumHelper.GetDescription(PerforType.护士长) }},
};
var obj = keyValues2.First(t => t.type == type);
var dept = new string[] { AccountUnitType.临床科室.ToString(), AccountUnitType.医技科室.ToString() };
conpute = _perforRescomputeRepository
.GetEntities(t => t.AllotID == allotId && dept.Contains(t.AccountType) && obj.accounttype.Contains(t.FitPeople))
?.OrderBy(t => t.AccountingUnit).ThenBy(t => t.FitPeople).ToList();
}
else
{
throw new PerformanceException("参数错误,type无效");
}
data = Mapper.Map<List<ResComputeResponse>>(conpute);
data?.ForEach(t => t.WorkTime = string.IsNullOrEmpty(t.WorkTime) ? null : Convert.ToDateTime(t.WorkTime).ToString("yyyy-MM-dd"));
return data;
}
......@@ -83,7 +96,12 @@ public List<ResComputeResponse> GetCompute(int allotId, int type)
public List<res_specialunit> GetSpecial(int allotId)
{
var list = _perforResspecialunitRepository.GetEntities(t => t.AllotID == allotId);
return Mapper.Map<List<res_specialunit>>(list);
if (list != null && list.Any())
{
list = list.OrderBy(t => t.AccountingUnit).ToList();
return Mapper.Map<List<res_specialunit>>(list);
}
return new List<res_specialunit>();
}
/// <summary>
......
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Repository;
using Performance.Services.AllotCompute;
using System;
using System.Collections.Generic;
......@@ -14,10 +15,23 @@ namespace Performance.Services
/// </summary>
public class ComputeDirector : IAutoInjection
{
private BaiscNormService baiscNormService;
public ComputeDirector(BaiscNormService baiscNormService)
private readonly BaiscNormService baiscNormService;
private readonly PerforCofdirectorRepository perforCofdirectorRepository;
private readonly PerforCofworkyearRepository perforCofworkyearRepository;
private readonly PerforResaccountnurseRepository perforResAccountnurseRepository;
private readonly PerforResaccountdoctorRepository perforResAccountdoctorRepository;
public ComputeDirector(BaiscNormService baiscNormService,
PerforCofdirectorRepository perforCofdirectorRepository,
PerforCofworkyearRepository perforCofworkyearRepository,
PerforResaccountnurseRepository perforResAccountnurseRepository,
PerforResaccountdoctorRepository perforResAccountdoctorRepository)
{
this.baiscNormService = baiscNormService;
this.perforCofdirectorRepository = perforCofdirectorRepository;
this.perforCofworkyearRepository = perforCofworkyearRepository;
this.perforResAccountnurseRepository = perforResAccountnurseRepository;
this.perforResAccountdoctorRepository = perforResAccountdoctorRepository;
}
/// <summary>
......@@ -27,24 +41,57 @@ public ComputeDirector(BaiscNormService baiscNormService)
/// <param name="nurseList"></param>
/// <param name="directorList"></param>
/// <returns></returns>
public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, List<ComputeSource> nurseList, List<cof_director> directorList)
public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, per_allot allot)
{
Dictionary<PerformanceType, string> keyValues = new Dictionary<PerformanceType, string>
{
{ PerformanceType.StandardDirector, "临床科室主任"},
{ PerformanceType.StandardDeputyDirector, "临床科室副主任"},
{ PerformanceType.StandardNurse, "临床科室护士长"},
};
//规模绩效和效率绩效配置表
var directorList = perforCofdirectorRepository.GetEntities(t => t.AllotID == allot.ID);
//取出医生科室
var doctorList = perforResAccountdoctorRepository.GetEntities(t => t.AllotID == allot.ID);
//取出护士科室
var nurseList = perforResAccountnurseRepository.GetEntities(t => t.AllotID == allot.ID);
List<ComputeResult> computeList = new List<ComputeResult>();
foreach (var key in keyValues.Keys)
// 主任及护士长 对应 效率绩效/规模绩效 关系
// 科室名称 确定绩效计算人员中的人群
// 绩效考核基数参考对象 确定科室下那些考核对象归纳为 科室主任 护士长
// 数据库存放的文本 与枚举 全文字中文匹配
var basicRuleList = new[]
{
new { AccountUnitType = AccountUnitType.临床科室, PerforType = PerforType.临床主任, DirectorType = DirectorType.临床科室主任 },
new { AccountUnitType = AccountUnitType.临床科室, PerforType = PerforType.临床副主任, DirectorType = DirectorType.临床科室副主任 },
new { AccountUnitType = AccountUnitType.医技科室, PerforType = PerforType.医技主任, DirectorType = DirectorType.医技科室主任 },
new { AccountUnitType = AccountUnitType.医技科室, PerforType = PerforType.医技副主任, DirectorType = DirectorType.医技科室副主任 },
new { AccountUnitType = AccountUnitType.临床科室, PerforType = PerforType.护士长, DirectorType = DirectorType.临床科室护士长 },
};
foreach (var basicRule in basicRuleList)
{
var needCompute = empolyeeList.Where(t => t.FitPeople == EnumHelper.GetDescription(key));
var needCompute = empolyeeList.Where(t => t.AccountType == basicRule.AccountUnitType.ToString() && t.FitPeople.Trim() == EnumHelper.GetDescription(basicRule.PerforType));
foreach (var item in needCompute)
{
var resAccount = nurseList.FirstOrDefault(t => t.AccountingUnit == item.AccountingUnit);
var efficiency = directorList.FirstOrDefault(t => t.TypeName == "效率绩效" && t.JobTitle == keyValues[key]);
var scale = directorList.FirstOrDefault(t => t.TypeName == "规模绩效" && t.JobTitle == keyValues[key]);
//分别取出对应的 计算 人员 平均值等信息
decimal? number, perforTotal, avg;
if (basicRule.PerforType == PerforType.护士长)
{
var resAccount = nurseList.FirstOrDefault(t => t.AccountingUnit == item.AccountingUnit);
number = resAccount?.Number;
perforTotal = resAccount?.PerforTotal;
avg = resAccount?.Avg;
}
else
{
var resAccount = doctorList.FirstOrDefault(t => t.AccountingUnit == item.AccountingUnit);
number = resAccount?.Number;
perforTotal = resAccount?.PerforTotal;
avg = resAccount?.Avg;
}
var efficiency = directorList.FirstOrDefault(t => t.TypeName == "效率绩效" && t.JobTitle == basicRule.DirectorType.ToString());
var scale = directorList.FirstOrDefault(t => t.TypeName == "规模绩效" && t.JobTitle == basicRule.DirectorType.ToString());
// 科室单独规模绩效 效率绩效 系数
var efficAccount = directorList.FirstOrDefault(t => t.TypeName == "效率绩效" && t.JobTitle == item.AccountingUnit);
var scaleAccount = directorList.FirstOrDefault(t => t.TypeName == "规模绩效" && t.JobTitle == item.AccountingUnit);
var compute = new ComputeResult
{
AccountType = item.AccountType,
......@@ -53,11 +100,11 @@ public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, List<Comp
FitPeople = item.FitPeople,
JobTitle = item.JobTitle,
Number = resAccount?.Number,
PerforTotal = resAccount?.PerforTotal,
Avg = resAccount?.Avg,
Efficiency = efficiency?.Value * resAccount?.Avg,
Scale = scale?.Value * resAccount?.PerforTotal,
Number = number,
PerforTotal = perforTotal,
Avg = avg,
Efficiency = avg * efficiency?.Value * (efficAccount?.Value ?? 1),
Scale = perforTotal * scale?.Value * (scaleAccount?.Value ?? 1),
Grant = item.Grant ?? 1,
ScoreAverageRate = item.ScoreAverageRate,
Punishment = item.Punishment,
......@@ -66,17 +113,19 @@ public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, List<Comp
Workload = item.Workload
};
//应发管理绩效
compute.ShouldGiveFee = (efficiency?.Value * resAccount?.Avg + scale?.Value * resAccount?.PerforTotal) * (item.Grant ?? 1);
compute.ShouldGiveFee = (compute.Efficiency + compute.Scale) * (item.Grant ?? 1);
//绩效合计
var perforSumFee = (compute.Avg + compute.Efficiency + compute.Scale) * (item.Grant ?? 1);
if (perforSumFee > (compute.Avg ?? 0) * 2.5m)
compute.PerforSumFee = (compute.Avg ?? 0) * 2.5m;
else
compute.PerforSumFee = perforSumFee;
// 在科主任护士长绩效测试时,有特殊情况需要乘一个基数
//if (perforSumFee > (compute.Avg ?? 0) * 2.5m)
// compute.PerforSumFee = (compute.Avg ?? 0) * 2.5m;
//else
compute.PerforSumFee = perforSumFee;
//应发绩效
compute.GiveFee = compute.Avg * (item.Grant ?? 1) + (compute.Efficiency + compute.Scale) * (item.Grant ?? 1) * compute.ScoreAverageRate + (item.Punishment ?? 0) + (item.OtherPerfor ?? 0);
//实发绩效
compute.RealGiveFee = compute.GiveFee * (item.Adjust ?? 1m) - compute.ShouldGiveFee * item.ScoreAverageRate * (item.Grant ?? 1) * 0.1m;
//compute.RealGiveFee = compute.GiveFee * (item.Adjust ?? 1m) - compute.ShouldGiveFee * item.ScoreAverageRate * (item.Grant ?? 1) * 0.1m;
compute.RealGiveFee = compute.GiveFee;
computeList.Add(compute);
}
......@@ -85,135 +134,70 @@ public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, List<Comp
}
/// <summary>
/// 绩效标准计算
/// </summary>
/// <param name="computes"></param>
/// <returns></returns>
public List<res_baiscnorm> ComputeAvg(List<ComputeResult> computes)
{
var keyList = new[]
{
//绩效基数平均值项目
new { type = "临床科室", reference = EnumHelper.GetDescription(PerformanceType.StandardDirector), groupname = "临床科主任" },
new { type = "临床科室", reference = EnumHelper.GetDescription(PerformanceType.StandardDeputyDirector), groupname = "临床科副主任" },
new { type = "医技科室", reference = EnumHelper.GetDescription(PerformanceType.StandardDirector), groupname = "医技科主任" },
new { type = "医技科室", reference = EnumHelper.GetDescription(PerformanceType.StandardDeputyDirector), groupname = "医技科副主任" },
new { type = "临床科室", reference = EnumHelper.GetDescription(PerformanceType.StandardNurse), groupname = "临床科护长" },
};
var groupList = from cp in computes
join gp in keyList on new { type = cp.AccountType, reference = cp.FitPeople } equals new { gp.type, gp.reference }
select new { gp.groupname, cp };
var result = groupList.GroupBy(t => t.groupname)
.Select(s => new res_baiscnorm
{
PositionName = s.Key,
TotelNumber = s.Count(),
TotelValue = s.Sum(t => t.cp.GiveFee),
AvgValue = s.Sum(t => t.cp.GiveFee) / s.Count()
});
return result.ToList();
}
/// <summary>
/// 绩效标准计算
/// </summary>
/// <param name="computes"></param>
/// <returns></returns>
public List<res_baiscnorm> ComputeOtherAvg(List<ComputeResult> computes)
{
var keyList = new[]
{
//行政绩效平均值项目
new { type = "行政中高层", groupname = "行政中高层" },
new { type = "行政高层", groupname = "行政高层" },
new { type = "行政中层", groupname = "行政中层" },
new { type = "行政工勤", groupname = "行政工勤" },
};
var groupList = from cp in computes
join gp in keyList on cp.AccountType equals gp.type
select new { gp.groupname, cp };
var result = groupList.GroupBy(t => t.groupname)
.Select(s => new res_baiscnorm
{
PositionName = s.Key,
TotelNumber = s.Count(),
TotelValue = s.Sum(t => t.cp.GiveFee),
AvgValue = s.Sum(t => t.cp.GiveFee) / s.Count()
});
return result.ToList();
}
/// <summary>
/// 院领导、业务中层、工勤人员 计算
/// </summary>
/// <param name="empolyeeList"></param>
/// <param name="baiscnormList"></param>
/// <returns></returns>
public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, List<res_baiscnorm> baiscnormList, List<cof_workyear> workyearList)
public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, per_allot allot, List<res_baiscnorm> baiscnormList)
{
PerformanceType[] types = new PerformanceType[]
{
PerformanceType.ReferenceDirector,
PerformanceType.ReferenceDirectorAvg,
PerformanceType.ReferenceNurse,
PerformanceType.ReferenceHeadNurse,
PerformanceType.Null,
};
PerformanceType[] yearTypes = new PerformanceType[]
{
PerformanceType.ReferenceNurse,
PerformanceType.ReferenceHeadNurse,
PerformanceType.Null,
};
//年资系数
var workyearList = perforCofworkyearRepository.GetEntities(t => t.AllotID == allot.ID);
List<ComputeResult> computeList = new List<ComputeResult>();
foreach (var type in types)
{
var needCompute = empolyeeList.Where(t => t.FitPeople == EnumHelper.GetDescription(type));
if (!needCompute.Any())
continue;
var baiscnorm = baiscNormService.GetBaiscNorm(baiscnormList, type);
List<string> involve = new List<string> { AccountUnitType.行政高层.ToString(), AccountUnitType.行政中层.ToString(), AccountUnitType.行政工勤.ToString() };
var needCompute = empolyeeList.Where(t => involve.Contains(t.AccountType));
foreach (var item in needCompute)
if (!needCompute.Any()) return computeList;
var perforTypeArray = EnumHelper.GetItems<PerforType>();
foreach (var item in needCompute)
{
var compute = new ComputeResult
{
var compute = new ComputeResult
{
AccountType = item.AccountType,
AccountingUnit = item.AccountingUnit,
EmployeeName = item.DoctorName,
FitPeople = item.FitPeople,
Grant = item.Grant ?? 1,
WorkTime = item.WorkTime,
BaiscNormValue = baiscnorm * (item.FitPeopleRatio ?? 1), //添加参数计算
PostCoefficient = item.PostCoefficient,
Attendance = item.Attendance,
ScoreAverageRate = item.ScoreAverageRate,
Punishment = item.Punishment,
OtherPerfor = item.OtherPerfor,
JobTitle = item.JobTitle,
Adjust = item.Adjust,
Workload = item.Workload
AccountType = item.AccountType,
AccountingUnit = item.AccountingUnit,
EmployeeName = item.DoctorName,
FitPeople = item.FitPeople,
Grant = item.Grant ?? 1,
WorkTime = item.WorkTime,
PostCoefficient = item.PostCoefficient,
Attendance = item.Attendance,
ScoreAverageRate = item.ScoreAverageRate,
Punishment = item.Punishment,
OtherPerfor = item.OtherPerfor,
JobTitle = item.JobTitle,
Adjust = item.Adjust,
Workload = item.Workload
};
decimal? baiscnorm = 1;
var perforTypeItem = perforTypeArray.FirstOrDefault(t => t.Description == item.FitPeople);
if (perforTypeItem != null)
{
var perforType = (PerforType)perforTypeItem.Value;
baiscnorm = baiscNormService.GetBaiscNorm(baiscnormList, perforType);
};
//年资系数
if (yearTypes.Contains(type) && item.WorkTime.HasValue && item.WorkTime.Value > new DateTime(1970, 1, 1))
if (item.FitPeople == AccountUnitType.行政工勤.ToString() && item.WorkTime.HasValue && item.WorkTime.Value > new DateTime(1970, 1, 1))
{
var years = ((DateTime.Now.Year - item.WorkTime.Value.Year) * 12 + (DateTime.Now.Month - item.WorkTime.Value.Month)) / 12.0m;
var value = workyearList.FirstOrDefault(t => t.MinRange < years && years <= t.MaxRange)?.Value;
compute.WorkYear = value;
}
//应发绩效
compute.GiveFee = baiscnorm * compute.PostCoefficient * compute.Attendance * compute.ScoreAverageRate * (compute.WorkYear ?? 1) + (compute.OtherPerfor ?? 0) + (item.Workload ?? 0) + (compute.Punishment ?? 0);
//实发绩效
var adjust = item.Adjust ?? 1m;
compute.RealGiveFee = compute.GiveFee * adjust * (item.Grant ?? 1);
computeList.Add(compute);
}
//添加参数计算
compute.BaiscNormValue = baiscnorm * (item.FitPeopleRatio ?? 1);
//应发绩效
compute.GiveFee = compute.BaiscNormValue * (compute.PostCoefficient + item.Adjust ?? 0)
* (item.Grant ?? 1) * compute.Attendance * compute.ScoreAverageRate * (compute.WorkYear ?? 1)
+ (compute.OtherPerfor ?? 0) + (item.Workload ?? 0) + (compute.Punishment ?? 0);
//实发绩效
compute.RealGiveFee = compute.GiveFee;
computeList.Add(compute);
}
return computeList;
}
}
......
......@@ -13,14 +13,21 @@ public class NopiSevice
{
if (cell != null)
{
switch (cell.CellType)
try
{
case CellType.Numeric:
return ConvertHelper.To<decimal?>(cell.NumericCellValue);
case CellType.String:
return ConvertHelper.To<decimal?>(cell.StringCellValue);
case CellType.Formula:
return ConvertHelper.To<decimal?>(cell.NumericCellValue);
switch (cell.CellType)
{
case CellType.Numeric:
return ConvertHelper.To<decimal?>(cell.NumericCellValue);
case CellType.String:
return ConvertHelper.To<decimal?>(cell.StringCellValue);
case CellType.Formula:
return ConvertHelper.To<decimal?>(cell.NumericCellValue);
}
}
catch (Exception ex)
{
//throw ex;
}
}
return null;
......
......@@ -75,109 +75,5 @@ public SheetType GetSheetType(string sheetName)
return SheetType.SpecialUnit;
return SheetType.Unidentifiable;
}
internal List<PerSheet> ProcessCompute(PerExcel excel, int allotid)
{
List<PerSheet> perSheet = new List<PerSheet>();
//合并科室收入、支出
var incomeconfs = _perforCofincomeRepository.GetEntities();
var economicCompute = new PerSheetDataComputeEconomic();
var mergeResult = economicCompute.MergeCompute(excel, incomeconfs);
//一次计算
var onceEconomic = economicCompute.OnceCompute(mergeResult);
//二次计算
var twiceEconomicResult = economicCompute.TwiceCompute(onceEconomic);
twiceEconomicResult.Sheet.SheetType = SheetType.ComputeEconomic;
perSheet.Add(twiceEconomicResult.Sheet);
//工作量
var workloadCompute = new PerSheetDataComputeWorkload();
var workload1 = excel.PerSheet.FirstOrDefault(t => t.SheetType == SheetType.Workload && t.SheetName.Contains("医生组"));
workload1.SheetName = "医生组工作量绩效测算表";
var confs = GetDrugConfig(excel, allotid);
//医生组 一次计算
var onceWorkload1 = workloadCompute.OnceCompute(workload1, confs);
//医生组 二次计算
var twiceWorkloadResult1 = workloadCompute.TwiceCompute(onceWorkload1);
twiceWorkloadResult1.Sheet.SheetType = SheetType.ComputeDoctorWorkload;
perSheet.Add(twiceWorkloadResult1.Sheet);
var workload2 = excel.PerSheet.FirstOrDefault(t => t.SheetType == SheetType.Workload && t.SheetName.Contains("护理组"));
workload2.SheetName = "护理组工作量绩效测算表";
//护理组 一次计算
var onceWorkload2 = workloadCompute.OnceCompute(workload2);
//护理组 二次计算
var twiceWorkloadResult2 = workloadCompute.TwiceCompute(onceWorkload2);
twiceWorkloadResult2.Sheet.SheetType = SheetType.ComputeNurseWorkload;
perSheet.Add(twiceWorkloadResult2.Sheet);
var deptAccounting = excel.PerSheet.FirstOrDefault(t => t.SheetType == SheetType.AccountBasic);
var dataList = deptAccounting.PerData.Select(t => (PerDataAccountBaisc)t);
PerSheet doctorSheet = new PerSheet("医生组临床科室单元核算表", "医生组临床科室单元核算表", SheetType.ComputeDoctorAccount, new List<PerHeader>(), new List<IPerData>());
PerSheet nurseSheet = new PerSheet("护理组临床科室单元核算表", "护理组临床科室单元核算表", SheetType.ComputeNurseAccount, new List<PerHeader>(), new List<IPerData>());
foreach (var dept in dataList)
{
var doctor = Mapper.Map<PerDataAccountDoctor>(dept);
var econDoctor = twiceEconomicResult.PerData.FirstOrDefault(t => t.UnitType == "医生组" && t.AccountingUnit == dept.AccountingUnit);
doctor.Income = econDoctor?.CellValue ?? 0;
var workDoctor = twiceWorkloadResult1.PerData.FirstOrDefault(t => t.UnitType == "医生组" && t.AccountingUnit == dept.AccountingUnit);
doctor.WorkloadFee = workDoctor?.CellValue ?? 0;
doctorSheet.PerData.Add(doctor);
var nurse = Mapper.Map<PerDataAccountNurse>(dept);
var econNurse = twiceEconomicResult.PerData.FirstOrDefault(t => t.UnitType == "护理组" && t.AccountingUnit == dept.AccountingUnit);
nurse.Income = econNurse?.CellValue ?? 0;
var workNurse = twiceWorkloadResult2.PerData.FirstOrDefault(t => t.UnitType == "护理组" && t.AccountingUnit == dept.AccountingUnit);
nurse.WorkloadFee = workNurse?.CellValue ?? 0;
nurseSheet.PerData.Add(nurse);
}
perSheet.Add(doctorSheet);
perSheet.Add(nurseSheet);
return perSheet;
}
/// <summary>
/// 获取药占比分割比例
/// </summary>
/// <param name="excel"></param>
/// <returns></returns>
private List<CofDrugProp> GetDrugConfig(PerExcel excel, int allotid)
{
//计算药占比
List<CofDrugProp> cofs = new List<CofDrugProp>();
var incomeSheet = excel.PerSheet.FirstOrDefault(t => t.SheetType == SheetType.Income && t.SheetName.Contains("门诊") && t.SheetName.Contains("就诊"));
var datalist = incomeSheet.PerData.Select(t => (PerData)t);
var drugtype = _perforCofdrugtypeRepository.GetEntities(t => t.AllotID == allotid)?.Select(t => t.Charge).ToList();
var drugData = datalist.Where(t => drugtype.Contains(t.TypeName)).GroupBy(t => t.AccountingUnit).Select(t => new { AccountingUnit = t.Key, SumValue = t.Sum(s => s.CellValue) });
var allData = datalist.GroupBy(t => t.AccountingUnit).Select(t => new { AccountingUnit = t.Key, SumValue = t.Sum(s => s.CellValue) });
var cofList = _perforCofdrugpropRepository.GetEntities();
var unitList = drugData.Select(t => t.AccountingUnit).Union(allData.Select(t => t.AccountingUnit));
foreach (var unit in unitList)
{
var dsv = drugData.FirstOrDefault(t => t.AccountingUnit == unit)?.SumValue;
var asv = allData.FirstOrDefault(t => t.AccountingUnit == unit)?.SumValue;
var prop = asv.HasValue && asv.Value > 0 ? Math.Round((dsv ?? 0) / asv.Value, 2) : 0;
var fvalue = prop == 0
? 0
: cofList.FirstOrDefault(t => prop > t.MinRange && prop <= t.MaxRange)?.Value ?? 0;
cofs.Add(new CofDrugProp { AccoutingUnit = unit, Factor = fvalue, Prop = prop });
}
return cofs;
}
}
}
......@@ -60,7 +60,7 @@ public PerSheet MergeCompute(PerExcel excel, List<EntityModels.cof_income> incom
PerHeader childHeader = new PerHeader(1, childPointCell, typeName, 1, 1, 1, null, 2);
headList.Add(childHeader);
var ds = group.Where(t => t.CellValue.HasValue && t.CellValue.Value > 0)
var ds = group.Where(t => !string.IsNullOrWhiteSpace(t.AccountingUnit) && t.CellValue.HasValue && t.CellValue.Value > 0)
.GroupBy(t => t.AccountingUnit).Select(t => new PerData
{
SignID = childHeader.SignID,
......
......@@ -29,13 +29,11 @@ public List<IPerData> ReadData(ISheet sheet, List<PerHeader> perHeader)
{
var row = sheet.GetRow(r);
if (row == null) continue;
var accountingUnit = row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "核算单元").PointCell)?.ToString();
PerDataAccountBaisc unifyUnit = new PerDataAccountBaisc();
unifyUnit.RowNumber = r;
unifyUnit.AccountingUnit = row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "核算单元").PointCell)?.ToString();
unifyUnit.Department = row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "科室").PointCell)?.ToString();
unifyUnit.AccountingUnit = row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "核算单元(医生组)").PointCell)?.ToString();
unifyUnit.Department = row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "核算单元(护理组)").PointCell)?.ToString();
unifyUnit.DoctorNumber = ConvertHelper.To<decimal>(row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "核算单元医生数量" && p.Parent.CellValue == "医生组").PointCell)?.ToString());
unifyUnit.DoctorBasicFactor = ConvertHelper.To<decimal>(row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "基础系数" && p.Parent.CellValue == "医生组").PointCell)?.ToString());
unifyUnit.DoctorSlopeFactor = ConvertHelper.To<decimal>(row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "倾斜系数" && p.Parent.CellValue == "医生组").PointCell)?.ToString());
......@@ -44,6 +42,7 @@ public List<IPerData> ReadData(ISheet sheet, List<PerHeader> perHeader)
unifyUnit.DoctorExtra = ConvertHelper.To<decimal>(row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "医院奖罚" && p.Parent.CellValue == "医生组").PointCell)?.ToString());
unifyUnit.DoctorScoringAverage = ConvertHelper.To<decimal>(row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "考核得分率" && p.Parent.CellValue == "医生组").PointCell)?.ToString());
unifyUnit.DoctorAdjustFactor = ConvertHelper.To<decimal>(row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "调节系数" && p.Parent.CellValue == "医生组").PointCell)?.ToString());
unifyUnit.NurseNumber = ConvertHelper.To<decimal>(row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "核算单元护士数量" && p.Parent.CellValue == "护理组").PointCell)?.ToString());
unifyUnit.NurseBasicFactor = ConvertHelper.To<decimal>(row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "基础系数" && p.Parent.CellValue == "护理组").PointCell)?.ToString());
unifyUnit.NurseSlopeFactor = ConvertHelper.To<decimal>(row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "倾斜系数" && p.Parent.CellValue == "护理组").PointCell)?.ToString());
......
......@@ -21,7 +21,8 @@ public class PerSheetDataReadSpecialUnit : IPerSheetDataRead
public List<IPerData> ReadData(ISheet sheet, List<PerHeader> perHeader)
{
List<IPerData> dataList = new List<IPerData>();
// 特殊科室多科室聚合,合并时保留科室名称
string lastAccount = "";
for (int r = Point.DataFirstRowNum.Value; r < sheet.LastRowNum + 1; r++)
{
var row = sheet.GetRow(r);
......@@ -29,12 +30,12 @@ public List<IPerData> ReadData(ISheet sheet, List<PerHeader> perHeader)
var accountingUnit = row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "科室").PointCell)?.ToString();
if (string.IsNullOrEmpty(accountingUnit))
continue;
accountingUnit = lastAccount;
PerDataSpecialUnit employee = new PerDataSpecialUnit
{
RowNumber = r,
AccountingUnit = row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "科室").PointCell)?.ToString(),
Department = row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "科室").PointCell)?.ToString(),
AccountingUnit = accountingUnit,
Department = accountingUnit,
Number = ConvertHelper.To<decimal?>(row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "人数").PointCell)?.ToString()),
QuantitativeIndicators = row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "量化指标").PointCell)?.ToString(),
Quantity = ConvertHelper.To<decimal?>(row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "数量").PointCell)?.ToString()),
......@@ -45,6 +46,7 @@ public List<IPerData> ReadData(ISheet sheet, List<PerHeader> perHeader)
Adjust = ConvertHelper.To<decimal?>(row.GetCell(perHeader.FirstOrDefault(p => p.CellValue == "调节系数").PointCell)?.ToString()),
};
dataList.Add(employee);
lastAccount = employee.AccountingUnit;
}
return dataList;
......
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