Commit d05ae030 by ruyun.zhang@suvalue.com

Merge branch 'extend' into develop

parents f3e391c2 7a0906ab
......@@ -5,6 +5,7 @@
using Newtonsoft.Json.Linq;
using Performance.DtoModels;
using Performance.DtoModels.AppSettings;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Services;
using System;
......@@ -135,7 +136,6 @@ public ApiResponse Delete([CustomizeValidator(RuleSet = "Delete"), FromBody]Drug
}
#endregion
#region drugprop
/// <summary>
/// 获取 药占比类型信息列表
......@@ -355,5 +355,73 @@ public ApiResponse AgainDelete([CustomizeValidator(RuleSet = "Delete"), FromBody
return new ApiResponse(ResponseType.OK);
}
#endregion
#region workitem
/// <summary>
/// 获取工作量绩效配置列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[Route("workitemlist")]
[HttpPost]
public ApiResponse<List<cof_workitem>> GetWorkItems([CustomizeValidator(RuleSet = "Select"), FromBody]WorkItemRequest request)
{
var list = _configService.GetWorkItems(request.AllotID);
return new ApiResponse<List<cof_workitem>>(ResponseType.OK, "ok", list);
}
/// <summary>
/// 新增工作量绩效配置
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[Route("workiteminsert")]
[HttpPost]
public ApiResponse<cof_workitem> WorkItemInsert([CustomizeValidator(RuleSet = "Insert"), FromBody]WorkItemRequest request)
{
var workyear = _configService.WorkItemInsert(request);
return new ApiResponse<cof_workitem>(ResponseType.OK, workyear);
}
/// <summary>
/// 修改工作量绩效配置
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[Route("workitemupdate")]
[HttpPost]
public ApiResponse<cof_workitem> WorkItemUpdate([CustomizeValidator(RuleSet = "Update"), FromBody]WorkItemRequest request)
{
var workyear = _configService.WorkItemUpdate(request);
return new ApiResponse<cof_workitem>(ResponseType.OK, workyear);
}
/// <summary>
/// 删除工作量绩效配置
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[Route("workitemdelete")]
[HttpPost]
public ApiResponse WorkItemDelete([CustomizeValidator(RuleSet = "Delete"), FromBody]WorkItemRequest request)
{
if (!_configService.WorkItemkDelete(request))
return new ApiResponse(ResponseType.Fail);
return new ApiResponse(ResponseType.OK);
}
#endregion
/// <summary>
/// 获取工作量绩效列头
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[Route("workheader")]
[HttpPost]
public ApiResponse WorkHeader([CustomizeValidator(RuleSet = "Select"), FromBody]WorkItemRequest request)
{
var list = _configService.WorkHeader(request.AllotID);
return new ApiResponse(ResponseType.OK, "ok", list);
}
}
}
\ No newline at end of file
......@@ -58,7 +58,7 @@ public class TemplateController : Controller
}
/// <summary>
/// 从WebAPI下载模板
/// 从WebAPI下载模板 1、医院绩效模板 2、医院二次分配绩效模板 3、医院绩效模板(无执行科室)
/// </summary>
/// <returns></returns>
[Route("downtemplate")]
......@@ -66,9 +66,19 @@ public class TemplateController : Controller
[AllowAnonymous]
public IActionResult DownFile(int type = 1)
{
string path = (type == 1)
? Path.Combine(env.ContentRootPath, "Template", "医院绩效模板.xlsx")
: Path.Combine(env.ContentRootPath, "Template", "医院二次分配绩效模板.xlsx");
string path = "";
switch (type)
{
case 1:
path = Path.Combine(env.ContentRootPath, "Template", "医院绩效模板.xlsx");
break;
case 2:
path = Path.Combine(env.ContentRootPath, "Template", "医院二次分配绩效模板.xlsx");
break;
case 3:
path = Path.Combine(env.ContentRootPath, "Template", "医院绩效模板(无执行科室).xlsx");
break;
}
var memoryStream = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
......@@ -343,7 +353,7 @@ public ApiResponse SaveFile([FromForm] IFormCollection form, int allotId, int ho
{
logger.LogInformation($"保存提取文件异常{ex.ToString()}");
LogHelper.Error($"保存失败:" + ex.ToString(), "保存提取文件");
return new ApiResponse(ResponseType.Error,ex.Message);
return new ApiResponse(ResponseType.Error, ex.Message);
}
}
}
......
......@@ -27,6 +27,10 @@
</ItemGroup>
<ItemGroup>
<None Remove="Template\~%24医院绩效模板.xlsx" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="8.0.0" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="6.0.0" />
<PackageReference Include="CSRedisCore" Version="3.0.45" />
......@@ -72,6 +76,9 @@
<None Update="Template\医院二次分配绩效模板.xlsx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Template\医院绩效模板%28无执行科室%29.xlsx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Template\医院绩效模板.xlsx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
......
......@@ -179,6 +179,13 @@
<param name="request"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.AllotController.AllotLog(Performance.DtoModels.AllotRequest)">
<summary>
绩效历史日志
</summary>
<param name="request"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.ComputeController.GetCompute(Performance.DtoModels.ComputerRequest)">
<summary>
获取绩效发放列表
......@@ -403,6 +410,34 @@
<param name="request"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.ConfigController.GetWorkItems(Performance.DtoModels.WorkItemRequest)">
<summary>
获取工作量绩效配置列表
</summary>
<param name="request"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.ConfigController.WorkItemInsert(Performance.DtoModels.WorkItemRequest)">
<summary>
新增工作量绩效配置
</summary>
<param name="request"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.ConfigController.WorkItemUpdate(Performance.DtoModels.WorkItemRequest)">
<summary>
修改工作量绩效配置
</summary>
<param name="request"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.ConfigController.WorkItemDelete(Performance.DtoModels.WorkItemRequest)">
<summary>
删除工作量绩效配置
</summary>
<param name="request"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.EmployeeController.GetEmployeeList(Performance.DtoModels.EmployeeRequest)">
<summary>
获取人员列表
......@@ -655,7 +690,7 @@
</member>
<member name="M:Performance.Api.Controllers.TemplateController.DownFile(System.Int32)">
<summary>
从WebAPI下载模板
从WebAPI下载模板 1、医院绩效模板 2、医院二次分配绩效模板 3、医院绩效模板(无执行科室)
</summary>
<returns></returns>
</member>
......
......@@ -1476,6 +1476,11 @@
用户科室
</summary>
</member>
<member name="P:Performance.DtoModels.WorkItemRequest.Item">
<summary>
工作量绩效项
</summary>
</member>
<member name="P:Performance.DtoModels.WorkyearRequest.MaxRange">
<summary>
最大工龄范围(小于)
......
......@@ -138,7 +138,8 @@ public enum MinimumType
保底医技医生 = 2,
[Description("保底绩效护士人均绩效")]
保底护士 = 3,
[Description("保底绩效行政工勤人均绩效")]
保底工勤 = 4,
}
///// <summary>
......
using FluentValidation;
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.DtoModels
{
public class WorkItemRequest
{
public int ID { get; set; }
public int AllotID { get; set; }
/// <summary>
/// 工作量绩效项
/// </summary>
public string Item { get; set; }
public class WorkItemRequestValidator : AbstractValidator<WorkItemRequest>
{
public WorkItemRequestValidator()
{
RuleSet("Select", () =>
{
RuleFor(x => x.AllotID).NotNull().NotEmpty().GreaterThan(0);
});
RuleSet("Insert", () =>
{
RuleFor(x => x.AllotID).NotNull().GreaterThan(0);
});
RuleSet("Update", () =>
{
RuleFor(x => x.ID).NotNull().GreaterThan(0);
});
RuleSet("Delete", () =>
{
RuleFor(x => x.ID).NotNull().GreaterThan(0);
});
}
}
}
}
......@@ -44,6 +44,8 @@ public PerformanceDbContext(DbContextOptions<PerformanceDbContext> options)
public virtual DbSet<cof_income> cof_income { get; set; }
/// <summary> 特殊绩效项指标 </summary>
public virtual DbSet<cof_singlefactor> cof_singlefactor { get; set; }
/// <summary> </summary>
public virtual DbSet<cof_workitem> cof_workitem { get; set; }
/// <summary> 工龄对应绩效系数配置 </summary>
public virtual DbSet<cof_workyear> cof_workyear { get; set; }
/// <summary> </summary>
......@@ -80,10 +82,10 @@ public PerformanceDbContext(DbContextOptions<PerformanceDbContext> options)
public virtual DbSet<per_sheet> per_sheet { get; set; }
/// <summary> 科室核算结果 </summary>
public virtual DbSet<res_account> res_account { get; set; }
///// <summary> 医生科室核算结果 </summary>
//public virtual DbSet<res_accountdoctor> res_accountdoctor { get; set; }
///// <summary> 护理科室核算结果 </summary>
//public virtual DbSet<res_accountnurse> res_accountnurse { get; set; }
/// <summary> 医生科室核算结果 </summary>
public virtual DbSet<res_accountdoctor> res_accountdoctor { get; set; }
/// <summary> 护理科室核算结果 </summary>
public virtual DbSet<res_accountnurse> res_accountnurse { get; set; }
/// <summary> 核算基础标准 </summary>
public virtual DbSet<res_baiscnorm> res_baiscnorm { get; set; }
/// <summary> </summary>
......
//-----------------------------------------------------------------------
// <copyright file=" cof_workitem.cs">
// * FileName: .cs
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Performance.EntityModels
{
/// <summary>
///
/// </summary>
[Table("cof_workitem")]
public class cof_workitem
{
/// <summary>
///
/// </summary>
[Key]
public int ID { get; set; }
/// <summary>
///
/// </summary>
public Nullable<int> AllotID { get; set; }
/// <summary>
/// 工作量中需做运算的项
/// </summary>
public string Item { get; set; }
}
}
......@@ -42,7 +42,7 @@ public class log_dbug
public string Message { get; set; }
/// <summary>
///
/// 1、信息(info)2、警告(warn)3、错误(error)4、异常(exception)5、成功(success)
/// </summary>
public Nullable<int> Level { get; set; }
}
......
//-----------------------------------------------------------------------
// <copyright file=" cof_workitem.cs">
// * FileName: cof_workitem.cs
// </copyright>
//-----------------------------------------------------------------------
using System;
using Performance.EntityModels;
namespace Performance.Repository
{
/// <summary>
/// cof_workitem Repository
/// </summary>
public partial class PerforCofworkitemRepository : PerforRepository<cof_workitem>
{
public PerforCofworkitemRepository(PerformanceDbContext context) : base(context)
{
}
}
}
////-----------------------------------------------------------------------
//// <copyright file=" res_accountdoctor.cs">
//// * FileName: res_accountdoctor.cs
//// </copyright>
////-----------------------------------------------------------------------
//using System;
//using Performance.EntityModels;
//-----------------------------------------------------------------------
// <copyright file=" res_accountdoctor.cs">
// * FileName: res_accountdoctor.cs
// </copyright>
//-----------------------------------------------------------------------
using System;
using Performance.EntityModels;
//namespace Performance.Repository
//{
// /// <summary>
// /// res_accountdoctor Repository
// /// </summary>
// public partial class PerforResaccountdoctorRepository : PerforRepository<res_accountdoctor>
// {
// public PerforResaccountdoctorRepository(PerformanceDbContext context) : base(context)
// {
// }
// }
//}
namespace Performance.Repository
{
/// <summary>
/// res_accountdoctor Repository
/// </summary>
public partial class PerforResaccountdoctorRepository : PerforRepository<res_accountdoctor>
{
public PerforResaccountdoctorRepository(PerformanceDbContext context) : base(context)
{
}
}
}
////-----------------------------------------------------------------------
//// <copyright file=" res_accountnurse.cs">
//// * FileName: res_accountnurse.cs
//// </copyright>
////-----------------------------------------------------------------------
//using System;
//using Performance.EntityModels;
//-----------------------------------------------------------------------
// <copyright file=" res_accountnurse.cs">
// * FileName: res_accountnurse.cs
// </copyright>
//-----------------------------------------------------------------------
using System;
using Performance.EntityModels;
//namespace Performance.Repository
//{
// /// <summary>
// /// res_accountnurse Repository
// /// </summary>
// public partial class PerforResaccountnurseRepository : PerforRepository<res_accountnurse>
// {
// public PerforResaccountnurseRepository(PerformanceDbContext context) : base(context)
// {
// }
// }
//}
namespace Performance.Repository
{
/// <summary>
/// res_accountnurse Repository
/// </summary>
public partial class PerforResaccountnurseRepository : PerforRepository<res_accountnurse>
{
public PerforResaccountnurseRepository(PerformanceDbContext context) : base(context)
{
}
}
}
......@@ -97,7 +97,7 @@ public bool Discern(PerExcel excel, per_allot allot)
cellValue = cellValue.Union(item.Children.Select(t => t.CellValue)).ToList();
}
var headerCheck = perforCofcheckRepository.GetEntities(t => t.Type == (int)sheet.SheetType)
.Select(t => t.CellName).Distinct().ToList();
?.Select(t => t.CellName).Distinct().ToList();
if (headerCheck != null)
{
var list = cellValue.Intersect(headerCheck).ToList(); //求交集,提交的列头和数据库中保存的列头
......@@ -168,7 +168,8 @@ public bool CheckData(PerExcel excel, per_allot allot)
{
var doctor = item.Where(t => t.UnitType == "医生组").FirstOrDefault();
var nurse = item.Where(t => t.UnitType == "护理组").FirstOrDefault();
if (string.IsNullOrEmpty(doctor.AccountingUnit) && string.IsNullOrEmpty(nurse.AccountingUnit))
var technician = item.Where(t => t.UnitType == "医技组").FirstOrDefault();
if (string.IsNullOrEmpty(doctor?.AccountingUnit) && string.IsNullOrEmpty(nurse?.AccountingUnit) && string.IsNullOrEmpty(technician?.AccountingUnit))
{
flag = false;
rowNumber.Add(doctor.RowNumber + 1);
......
......@@ -84,6 +84,7 @@ private PerExcel Import(per_allot allot)
IWorkbook workbook = (excel.Version == ExcelVersion.xlsx)
? (IWorkbook)(new XSSFWorkbook(fs))
: (IWorkbook)(new HSSFWorkbook(fs));
bool isnew = false;
for (int i = 0; i < workbook.NumberOfSheets; i++)
{
var sheet = workbook.GetSheetAt(i);
......@@ -92,9 +93,14 @@ private PerExcel Import(per_allot allot)
if (SheetType.Unidentifiable != sheetType)
{
logManageService.WriteMsg("开始读取excel文件", $"开始读取sheet -- {sheet.SheetName}", 1, allot.ID, "ReceiveMessage", true);
var st = perSheetService.Sheet(sheet);
var st = perSheetService.Sheet(sheet, isnew);
excel.PerSheet.Add(st);
}
else
{
if (sheet.SheetName.Contains("无执行科室"))
isnew = true;
}
}
logManageService.WriteMsg("开始读取excel文件", $"excel文件基础数据读取完成!", 1, allot.ID, "ReceiveMessage", true);
return excel;
......
......@@ -47,7 +47,7 @@ public class ResultComputeService : IAutoInjection
/// 计算最终数据
/// </summary>
/// <param name="excel"></param>
public List<res_baiscnorm> Compute(per_allot allot, PerExcel excel, List<PerSheet> perSheets)
public List<res_baiscnorm> Compute(per_allot allot, PerExcel excel, List<PerSheet> accountSheet, bool isSave = true)
{
//取出人员信息
var empolyeeList = perforImEmployeeRepository.GetEntities(t => t.AllotID == allot.ID);
......@@ -56,25 +56,27 @@ public List<res_baiscnorm> Compute(per_allot allot, PerExcel excel, List<PerShee
List<ComputeEmployee> computeEmployees = Mapper.Map<List<ComputeEmployee>>(empolyeeList);
logManageService.WriteMsg("正在生成绩效", "临床科室主任、临床科室副主任、临床科室护士长 最终绩效数据计算", 1, allot.ID, "ReceiveMessage");
var computResult = computeDirector.Compute(computeEmployees, accountbasicList, allot);
var computResult = computeDirector.Compute(computeEmployees, accountbasicList, accountSheet, allot);
//计算 绩效标准 基数(科主任、副主任、护士长 =>> 平均值)
List<res_baiscnorm> baiscnormList = new List<res_baiscnorm>();
baiscNormService.ComputeAvg(baiscnormList, accountbasicList, computResult);
baiscNormService.DocterNurseBaiscnorm(baiscnormList, accountbasicList, perSheets);
baiscNormService.DocterNurseBaiscnorm(baiscnormList, accountbasicList, accountSheet);
logManageService.WriteMsg("正在生成绩效", "院领导、业务中层、工勤人员 最终绩效数据计算", 1, allot.ID, "ReceiveMessage");
var computResult2 = computeDirector.Compute(computeEmployees, allot, baiscnormList);
//计算 行政人员 平均值
baiscNormService.ComputeOtherAvg(baiscnormList, computResult2, empolyeeList);
if (isSave)
{
var computes = Mapper.Map<List<res_compute>>(computResult);
computes.AddRange(Mapper.Map<List<res_compute>>(computResult2));
computes.ForEach(t => t.AllotID = allot.ID);
perforRescomputeRepository.AddRange(computes.ToArray());
}
baiscnormList.ForEach(t => t.AllotID = allot.ID);
logManageService.WriteMsg("正在生成绩效", "保存最终绩效数据", 1, allot.ID, "ReceiveMessage");
perforResbaiscnormRepository.AddRange(baiscnormList.ToArray());
return baiscnormList;
}
......
......@@ -34,6 +34,8 @@ public class AllotService : IAutoInjection
private PerforPeragainallotRepository _againallotRepository;
private PerforLogcheckRepository perforLogcheckRepository;
private readonly PerforHospitalRepository perforHospitalRepository;
private readonly PerforResbaiscnormRepository perforResbaiscnormRepository;
//private readonly IHubContext<AllotLogHub> hubContext;
private readonly LogManageService logManageService;
......@@ -51,6 +53,7 @@ public class AllotService : IAutoInjection
PerforPeragainallotRepository againallotRepository,
PerforLogcheckRepository perforLogcheckRepository,
PerforHospitalRepository perforHospitalRepository,
PerforResbaiscnormRepository perforResbaiscnormRepository,
//IHubContext<AllotLogHub> hubContext
LogManageService logManageService)
{
......@@ -69,6 +72,7 @@ public class AllotService : IAutoInjection
this.logdbug = logdbug;
this.perforLogcheckRepository = perforLogcheckRepository;
this.perforHospitalRepository = perforHospitalRepository;
this.perforResbaiscnormRepository = perforResbaiscnormRepository;
//this.hubContext = hubContext;
this.logManageService = logManageService;
}
......@@ -230,18 +234,61 @@ public void Generate(per_allot allot, string mail)
}
UpdateAllotStates(allot.ID, (int)AllotStates.InGenerate, EnumHelper.GetDescription(AllotStates.InGenerate));
// 计算合并数据
logManageService.WriteMsg("正在生成绩效", "计算合并数据", 1, allot.ID, "ReceiveMessage", true);
List<PerSheet> list = processComputService.MergeAndSave(excel, allot);
//var baiscnorm = baiscNormService.NurseBaiscnorm(list);
//保底绩效计算需分两次进行;
//第一次计算包含(保底绩效临床医生人均绩效、保底绩效医技医生人均绩效、保底绩效护士人均绩效)得出科室业绩绩效;
//根据当前业绩绩效核算各人群人均绩效,取工勤人均作为 保底工勤人均绩效
//第二次计算包含(保底绩效临床医生人均绩效、保底绩效医技医生人均绩效、保底绩效护士人均绩效、保底工勤人均绩效)得出科室业绩绩效;
//根据当前业绩绩效核算出最终绩效结果
//科室经济核算汇总、工作量汇总
logManageService.WriteMsg("科室业绩汇总", "正在生成科室收入支出汇总、工作量汇总", 1, allot.ID, "ReceiveMessage", true);
var (list, mergeSheets) = processComputService.MergeCompute(excel, allot.ID);
processComputService.Save(list, allot.ID);
//计算保底绩效参考标准(保底绩效临床医生人均绩效、保底绩效医技医生人均绩效、保底绩效护士人均绩效)
logManageService.WriteMsg("计算保底绩效参考标准值", "正在保底绩效临床医生人均绩效、保底绩效医技医生人均绩效、保底绩效护士人均绩效", 1, allot.ID, "ReceiveMessage", true);
var minimumBaiscnorm = processComputService.ComputeMinimum(excel, mergeSheets, allot.ID);
//计算科室业绩(含保底绩效临床医生人均绩效、保底绩效医技医生人均绩效、保底绩效护士人均绩效)保底绩效
logManageService.WriteMsg("计算保底绩效参考标准值", "计算科室业绩", 1, allot.ID, "ReceiveMessage", true);
var sheet = processComputService.Compute(excel, mergeSheets, minimumBaiscnorm);
//计算各人群人均保底绩效
logManageService.WriteMsg("计算保底绩效参考标准值", "正在生成保底绩效行政工勤人均绩效", 1, allot.ID, "ReceiveMessage", true);
var minimumBaiscnorm2 = resultComputeService.Compute(allot, excel, sheet, false);
if (minimumBaiscnorm2 != null && minimumBaiscnorm2.Any(t => t.PositionName == EnumHelper.GetDescription(PerforType.行政工勤)))
{
var minimum = minimumBaiscnorm2.First(t => t.PositionName == EnumHelper.GetDescription(PerforType.行政工勤));
minimum.PositionName = EnumHelper.GetDescription(MinimumType.保底工勤);
minimumBaiscnorm.Add(minimum);
}
//保存 保底绩效参考标准
logManageService.WriteMsg("计算保底绩效参考标准值", "保存保底绩效参考标准", 1, allot.ID, "ReceiveMessage", true);
perforResbaiscnormRepository.AddRange(minimumBaiscnorm.ToArray());
//重新计算科室业绩(含所有提供保底金额)
logManageService.WriteMsg("正在生成绩效", "重新计算科室业绩,包含所有保底金额计算科室业绩", 1, allot.ID, "ReceiveMessage", true);
var sheetLast = processComputService.Compute(excel, mergeSheets, minimumBaiscnorm);
//保存计算过程数据
logManageService.WriteMsg("正在生成绩效", "保存科室业绩结果及计算过程中产生的数据", 1, allot.ID, "ReceiveMessage", true);
processComputService.Save(sheetLast, allot.ID);
// 计算最总数据
logManageService.WriteMsg("正在生成绩效", "计算最终绩效数据", 1, allot.ID, "ReceiveMessage", true);
var baiscnormList = resultComputeService.Compute(allot, excel, list);
var baiscnormList = resultComputeService.Compute(allot, excel, sheetLast);
logManageService.WriteMsg("正在生成绩效", "计算最终特殊科室绩效数据", 1, allot.ID, "ReceiveMessage", true);
resultComputeService.SpecialUnitCompute(excel, allot, baiscnormList);
logManageService.WriteMsg("正在生成绩效", "保存最终特殊科室绩效数据", 1, allot.ID, "ReceiveMessage", true);
//保存 绩效人均参考标准
logManageService.WriteMsg("正在生成绩效", "保存绩效人均参考标准", 1, allot.ID, "ReceiveMessage", true);
perforResbaiscnormRepository.AddRange(baiscnormList.ToArray());
UpdateAllotStates(allot.ID, (int)AllotStates.GenerateSucceed, EnumHelper.GetDescription(AllotStates.GenerateSucceed));
//发送邮件
SendEmail(allot, mail, 1, time);
......
......@@ -18,11 +18,14 @@ public class ConfigService : IAutoInjection
private PerforCofdrugpropRepository _drugpropRepository;
private PerforCofincomeRepository _incomeRepository;
private PerforCofworkyearRepository _workyearRepository;
private PerforCofworkitemRepository _workitemRepository;
private PerforCofagainRepository _againRepository;
private PerforCofdrugtypeRepository _drugtypeRepository;
private PerforPerallotRepository perforPerAllotRepository;
private PerforPeragainallotRepository perforPeragainallotRepository;
private PerforHospitalRepository perforHospitalRepository;
private PerforPersheetRepository perforPersheetRepository;
private PerforImheaderRepository perforImheaderRepository;
//private PerforLogdbugRepository logdbug;
private readonly LogManageService logManageService;
public ConfigService(PerforCofdirectorRepository cofdirectorRepository,
......@@ -34,6 +37,9 @@ public class ConfigService : IAutoInjection
PerforPerallotRepository perforPerAllotRepository,
PerforPeragainallotRepository perforPeragainallotRepository,
PerforHospitalRepository perforHospitalRepository,
PerforCofworkitemRepository workitemRepository,
PerforPersheetRepository perforPersheetRepository,
PerforImheaderRepository perforImheaderRepository,
//PerforLogdbugRepository logdbug
LogManageService logManageService)
{
......@@ -41,11 +47,14 @@ public class ConfigService : IAutoInjection
this._drugpropRepository = cofdrugpropRepository;
this._incomeRepository = cofincomeRepository;
this._workyearRepository = cofworkyearRepository;
this._workitemRepository = workitemRepository;
this._againRepository = againRepository;
this._drugtypeRepository = drugtypeRepository;
this.perforPerAllotRepository = perforPerAllotRepository;
this.perforPeragainallotRepository = perforPeragainallotRepository;
this.perforHospitalRepository = perforHospitalRepository;
this.perforPersheetRepository = perforPersheetRepository;
this.perforImheaderRepository = perforImheaderRepository;
//this.logdbug = logdbug;
this.logManageService = logManageService;
}
......@@ -348,6 +357,63 @@ public bool WorkDelete(WorkyearRequest request)
}
#endregion
#region cof_workitem 工作量绩效
/// <summary>
/// 获取cof_workitem列表
/// </summary>
/// <returns></returns>
public List<cof_workitem> GetWorkItems(int allotId)
{
var list = _workitemRepository.GetEntities(t => t.AllotID == allotId);
return Mapper.Map<List<cof_workitem>>(list);
}
/// <summary>
/// 添加数据
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public cof_workitem WorkItemInsert(WorkItemRequest request)
{
var workyear = Mapper.Map<cof_workitem>(request);
if (!_workitemRepository.Add(workyear))
throw new PerformanceException("保存失败");
return Mapper.Map<cof_workitem>(workyear);
}
/// <summary>
/// 更新数据
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public cof_workitem WorkItemUpdate(WorkItemRequest request)
{
var workyear = _workitemRepository.GetEntity(t => t.ID == request.ID);
if (null == workyear)
throw new PerformanceException($"ID不存在 :{request.ID}");
workyear.Item = request.Item;
if (!_workitemRepository.Update(workyear))
throw new PerformanceException("保存失败");
return Mapper.Map<cof_workitem>(workyear);
}
/// <summary>
/// 删除数据
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public bool WorkItemkDelete(WorkItemRequest request)
{
var workyear = _workitemRepository.GetEntity(t => t.ID == request.ID);
if (null == workyear)
throw new PerformanceException($"ID不存在 :{request.ID}");
return _workitemRepository.Remove(workyear);
}
#endregion
#region Copy
/// <summary>
/// 复制报表基础配置
......@@ -412,6 +478,17 @@ public void Copy(per_allot allot)
_drugtypeRepository.AddRange(newAgains.ToArray());
}
var workItem = _workitemRepository.GetEntities(t => t.AllotID == allot.ID);
if (hospital != null && hospital?.IsOpenDrugprop == 1 && (workItem == null || workItem.Count == 0))
{
workItem = _workitemRepository.GetEntities(t => t.AllotID == allotId);
if (workItem != null && workItem.Count > 0)
{
var newWorkItem = workItem.Select(t => new cof_workitem { AllotID = allot.ID, Item = t.Item });
_workitemRepository.AddRange(newWorkItem.ToArray());
}
}
var data = _againRepository.GetEntities(t => t.AllotID == allot.ID);
if (data == null || data.Count == 0)
{
......@@ -502,5 +579,18 @@ public void ClearAgain(int againId)
logManageService.WriteMsg("清理无效数据", $"清除二次绩效中无效数据,受影响行数:{count}", 1, againId, "ReceiveMessage", true);
}
#endregion
/// <summary>
/// 获取工作量绩效列头
/// </summary>
/// <returns></returns>
public List<TitleValue> WorkHeader(int allotId)
{
var sheets = perforPersheetRepository.GetEntities(t => t.AllotID == allotId && t.SheetName.Contains("工作量"));
if (sheets == null)
return new List<TitleValue>();
var header = perforImheaderRepository.GetEntities(t => sheets.Select(s => s.ID).Contains(t.SheetID.Value) && !t.CellValue.Contains("核算单元") && t.CellValue != "科室名称")?.ToList();
return header?.Select(t => new TitleValue { Title = t.CellValue, Value = t.CellValue }).Distinct().ToList();
}
}
}
......@@ -137,7 +137,7 @@ public class ComputeDirector : IAutoInjection
/// <param name="nurseList"></param>
/// <param name="directorList"></param>
/// <returns></returns>
public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, List<im_accountbasic> accountbasicList, per_allot allot)
public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, List<im_accountbasic> accountbasicList, List<PerSheet> accountSheet, per_allot allot)
{
var basicRuleList = new[]
{
......@@ -146,8 +146,11 @@ public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, List<im_a
new { AccountUnitType = AccountUnitType.科主任, UnitType = UnitType.医技组 },
};
//取出科室
var dataList = perforResaccountRepository.GetEntities(t => t.AllotID == allot.ID);
List<res_account> dataList = new List<res_account>();
foreach (var account in accountSheet)
{
dataList.AddRange(AutoMapper.Mapper.Map<List<res_account>>(account.PerData.Select(t => (PerDataAccountBaisc)t)));
}
List<ComputeResult> computeList = new List<ComputeResult>();
foreach (var accountbasic in accountbasicList)
{
......@@ -268,7 +271,7 @@ public List<ComputeResult> Compute(List<ComputeEmployee> empolyeeList, per_allot
}
}
//添加参数计算
compute.BaiscNormValue = baiscnorm * (item.FitPeopleRatio ?? 1);
compute.BaiscNormValue = baiscnorm * (item.FitPeopleRatio == null || item.FitPeopleRatio == 0 ? 1 : item.FitPeopleRatio);
//应发绩效
compute.GiveFee = compute.BaiscNormValue * compute.PostCoefficient * (compute.WorkYear ?? 1) * compute.Attendance * compute.ScoreAverageRate
+ (compute.OtherPerfor ?? 0) + (compute.Punishment ?? 0);
......
......@@ -15,7 +15,7 @@ public class PerSheetDataFactory
/// </summary>
/// <param name="sheetType"></param>
/// <returns></returns>
public static IPerSheetDataRead GetDataRead(SheetType sheetType)
public static IPerSheetDataRead GetDataRead(SheetType sheetType, bool isnew = false)
{
IPerSheetDataRead dataread = null;
switch (sheetType)
......@@ -24,6 +24,9 @@ public static IPerSheetDataRead GetDataRead(SheetType sheetType)
dataread = new PerSheetDataReadEmployee();
break;
case SheetType.Income:
if (isnew)
dataread = new PerSheetDataReadBillIncome();
else
dataread = new PerSheetDataReadIncome();
break;
case SheetType.OtherIncome:
......
......@@ -33,7 +33,7 @@ public class PerSheetService : IAutoInjection
/// </summary>
/// <param name="sheet"></param>
/// <returns></returns>
public PerSheet Sheet(ISheet sheet)
public PerSheet Sheet(ISheet sheet, bool isnew)
{
PerSheet perSheet = new PerSheet();
perSheet.SheetName = sheet.SheetName;
......@@ -43,7 +43,7 @@ public PerSheet Sheet(ISheet sheet)
if (perSheet.SheetType == SheetType.Unidentifiable)
return null;
var sheetRead = PerSheetDataFactory.GetDataRead(perSheet.SheetType);
var sheetRead = PerSheetDataFactory.GetDataRead(perSheet.SheetType, isnew);
var perHeader = _perHeader.GetPerHeader(sheet, sheetRead.Point);
var headerReverse = _perHeader.GetPerHeaderReverse(perHeader);
......
......@@ -52,7 +52,7 @@ public PerSheet MergeCompute(PerExcel excel, List<EntityModels.cof_income> incom
//判断是否创建头部
if (!isHasData && dataList != null && dataList.Count() > 0)
isHasData = true;
foreach (var item in EnumHelper.GetItems<UnitType>())
foreach (var item in EnumHelper.GetItems<UnitType>().Where(t => t.Name != "专家组"))
{
var group = dataList.Where(t => t.UnitType == item.Name);
......@@ -161,7 +161,7 @@ public PerSheet OnceCompute(PerSheet sheet)
var typeClass = dataList.Where(t => header.Children.Select(s => s.CellValue).Contains(t.TypeName));
int pointcell = 0;
foreach (var item in EnumHelper.GetItems<UnitType>())
foreach (var item in EnumHelper.GetItems<UnitType>().Where(t => t.Name != "专家组"))
{
pointcell++;
var group = typeClass.Where(t => t.UnitType == item.Name);
......
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using System;
using System.Collections.Generic;
......@@ -98,7 +99,7 @@ public PerSheet OnceCompute(PerSheet sheet, List<CofDrugProp> confs = null)
/// </summary>
/// <param name="sheet"></param>
/// <returns></returns>
public (PerSheet Sheet, List<PerData> PerData) TwiceCompute(PerSheet sheet)
public (PerSheet Sheet, List<PerData> PerData) TwiceCompute(PerSheet sheet, List<CofDrugProp> confs = null, List<cof_workitem> workitems = null)
{
//获取最大列坐标位置
int thiscell = sheet.PerHeader.OrderByDescending(t => t.PointCell).FirstOrDefault().PointCell + 1;
......@@ -117,7 +118,7 @@ public PerSheet OnceCompute(PerSheet sheet, List<CofDrugProp> confs = null)
UnitType = group.Key.UnitType,
AccountingUnit = group.Key.AccountingUnit,
//CellValue = group.Sum(s => s.CellValue),
CellValue = group.Sum(s => s.IsFactor ? s.CellValue * s.FactorValue : s.CellValue),
CellValue = ComputValue(group, confs, workitems),
TypeName = group.Key.UnitType,
RowNumber = group.FirstOrDefault()?.RowNumber ?? 0,
IsTotal = 1,
......@@ -131,6 +132,24 @@ public PerSheet OnceCompute(PerSheet sheet, List<CofDrugProp> confs = null)
sheet.PerData.AddRange(perDataList);
return (sheet, perDataList);
}
private decimal? ComputValue(IGrouping<object, PerData> group, List<CofDrugProp> confs = null, List<cof_workitem> workitems = null)
{
if (confs == null || workitems == null)
return group.Sum(s => s.IsFactor ? s.CellValue * s.FactorValue : s.CellValue);
else
{
var factor = confs.FirstOrDefault(t => t.AccoutingUnit == group.First().AccountingUnit)?.Factor ?? 1;
//需要乘系数的项
var fgroup = group.Where(t => workitems.Select(s => s.Item).Contains(t.TypeName));
//需要乘系数的项
var ngroup = group.Where(t => !workitems.Select(s => s.Item).Contains(t.TypeName));
var value = fgroup.Sum(s => s.IsFactor ? s.CellValue * s.FactorValue : s.CellValue) * factor;
value += ngroup.Sum(s => s.IsFactor ? s.CellValue * s.FactorValue : s.CellValue);
return value;
}
}
#endregion
}
}
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Performance.Services
{
/// <summary>
/// 无执行科室医院收入
/// </summary>
public class PerSheetDataReadBillIncome : IPerSheetDataRead
{
public PerSheetPoint Point => new PerSheetPoint
{
HeaderFirstRowNum = 5,
HeaderLastRowNum = 5,
HeaderFirstCellNum = 0,
DataFirstRowNum = 6,
AccountingUnit = new List<AccountingUnit>
{
//核算单元(医技组)
new AccountingUnit
{
AccountingUnitCellNum = -1,
UnitType = "医技组",
DeptCellNum = 2,
FactorRow = 3,
},
//核算单元(医生组)
new AccountingUnit
{
AccountingUnitCellNum = 0,
UnitType = "医生组",
DeptCellNum = 2,
FactorRow = 2,
},
//核算单元(护理组)
new AccountingUnit
{
AccountingUnitCellNum = 1,
UnitType = "护理组",
DeptCellNum = 2,
FactorRow = 1,
}
}
};
public List<IPerData> ReadData(ISheet sheet, List<PerHeader> perHeader)
{
List<IPerData> dataList = new List<IPerData>();
//循环 当前有几个核算单元
foreach (var unit in Point.AccountingUnit)
{
if (unit.UnitType == "医技组") continue;
//查询除了 核算单元 科室名称 有效数据列头位置
var vhead = perHeader.Where(t => !Point.AccountingUnit.Select(p => p.AccountingUnitCellNum).Contains(t.PointCell)
&& !Point.AccountingUnit.Select(p => p.DeptCellNum).Contains(t.PointCell)).OrderBy(t => t.PointCell);
for (int r = Point.DataFirstRowNum.Value; r < sheet.LastRowNum + 1; r++)
{
var row = sheet.GetRow(r);
if (row == null) continue;
for (int c = 0; c < vhead.Count(); c++)
{
var athead = vhead.ElementAt(c);
var cellValue = NopiSevice.GetCellValue(row.GetCell(athead.PointCell));
if (!cellValue.HasValue || cellValue.Value == 0)
continue;
PerData data = new PerData
{
RowNumber = r,
SignID = athead.SignID,
AccountingUnit = row.GetCell(unit.AccountingUnitCellNum.Value)?.ToString(),
Department = row.GetCell(unit.DeptCellNum.Value)?.ToString(),
TypeName = athead?.CellValue,
CellValue = cellValue,
Annotation = row.GetCell(athead.PointCell)?.CellComment?.String?.String,
UnitType = unit.UnitType, //手动匹配
FactorValue = ConvertHelper.To<decimal?>(sheet.GetRow(unit.FactorRow.Value).GetCell(athead.PointCell)?.ToString()),
IsFactor = true,
};
dataList.Add(data);
}
}
}
var tunit = Point.AccountingUnit[0];
var rownum = sheet.LastRowNum + 1;
var technicianRow = sheet.GetRow(4);
if (technicianRow != null)
{
//查询除了 核算单元 科室名称 有效数据列头位置
var vhead = perHeader.Where(t => !Point.AccountingUnit.Select(p => p.AccountingUnitCellNum).Contains(t.PointCell)
&& !Point.AccountingUnit.Select(p => p.DeptCellNum).Contains(t.PointCell)).OrderBy(t => t.PointCell);
for (int c = 0; c < vhead.Count(); c++)
{
var athead = vhead.ElementAt(c);
var cellValue = technicianRow.GetCell(athead.PointCell).StringCellValue;
if (string.IsNullOrEmpty(cellValue))
continue;
PerData data = new PerData
{
RowNumber = rownum,
SignID = athead.SignID,
AccountingUnit = cellValue,
Department = cellValue,
TypeName = athead?.CellValue,
CellValue = (dataList.Select(t => (PerData)t)?.Where(t => t.TypeName == athead.CellValue).Sum(t => t.CellValue) ?? 0) / 2,
Annotation = technicianRow.GetCell(athead.PointCell)?.CellComment?.String?.String,
UnitType = tunit.UnitType, //手动匹配
FactorValue = ConvertHelper.To<decimal?>(sheet.GetRow(tunit.FactorRow.Value).GetCell(athead.PointCell)?.ToString()),
IsFactor = true,
};
dataList.Add(data);
}
}
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