Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
performance
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zry
performance
Commits
65b03bc5
Commit
65b03bc5
authored
Jun 21, 2021
by
ruyun.zhang@suvalue.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
初稿
parent
28e2c18b
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
1561 additions
and
92 deletions
+1561
-92
performance/Performance.Api/Controllers/SecondAllotController.cs
+136
-5
performance/Performance.Api/wwwroot/Performance.Api.xml
+35
-0
performance/Performance.Api/wwwroot/Performance.DtoModels.xml
+56
-0
performance/Performance.Api/wwwroot/Performance.EntityModels.xml
+5
-15
performance/Performance.DtoModels/Enum.cs
+4
-0
performance/Performance.DtoModels/HandsonTable.cs
+14
-4
performance/Performance.DtoModels/Request/SecondEmpRequest.cs
+0
-8
performance/Performance.DtoModels/ResponseType.cs
+1
-0
performance/Performance.DtoModels/Second/Constant.cs
+45
-0
performance/Performance.DtoModels/Second/SecondColumnDictionary.cs
+22
-0
performance/Performance.DtoModels/Second/SecondComputeCheckResultDto.cs
+18
-0
performance/Performance.DtoModels/Second/SecondComputeDto.cs
+10
-0
performance/Performance.DtoModels/Second/SecondDetailDto.cs
+11
-0
performance/Performance.DtoModels/Second/SecondLoadDto.cs
+15
-0
performance/Performance.DtoModels/Second/SecondWorkLoadDto.cs
+32
-0
performance/Performance.EntityModels/Entity/ag_bodysource.cs
+15
-10
performance/Performance.EntityModels/Entity/ag_headsource.cs
+8
-3
performance/Performance.Infrastructure/Extensions/Extensions.Dictionary.cs
+22
-6
performance/Performance.Infrastructure/Extensions/Extensions.String.cs
+22
-0
performance/Performance.Repository/PerforPerapramounthideRepository.cs
+1
-1
performance/Performance.Services/PersonService.cs
+1
-1
performance/Performance.Services/RedistributionService.cs
+1085
-36
performance/Performance.Services/SecondAllot/SecondAllotDetails.cs
+1
-1
performance/Performance.Services/SecondAllotService.cs
+2
-2
No files found.
performance/Performance.Api/Controllers/SecondAllotController.cs
View file @
65b03bc5
...
@@ -10,6 +10,8 @@
...
@@ -10,6 +10,8 @@
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Linq
;
using
System.Threading.Tasks
;
using
System.Threading.Tasks
;
using
Performance.Infrastructure
;
using
Performance.DtoModels.Second
;
namespace
Performance.Api.Controllers
namespace
Performance.Api.Controllers
{
{
...
@@ -20,6 +22,7 @@ namespace Performance.Api.Controllers
...
@@ -20,6 +22,7 @@ namespace Performance.Api.Controllers
public
class
SecondAllotController
:
ControllerBase
public
class
SecondAllotController
:
ControllerBase
{
{
private
readonly
ClaimService
claimService
;
private
readonly
ClaimService
claimService
;
private
readonly
AllotService
_allotService
;
private
readonly
SecondAllotService
secondAllotService
;
private
readonly
SecondAllotService
secondAllotService
;
private
readonly
ResultComputeService
resultComputeService
;
private
readonly
ResultComputeService
resultComputeService
;
private
readonly
SecondAllotDetails
secondAllotDetails
;
private
readonly
SecondAllotDetails
secondAllotDetails
;
...
@@ -27,6 +30,7 @@ public class SecondAllotController : ControllerBase
...
@@ -27,6 +30,7 @@ public class SecondAllotController : ControllerBase
public
SecondAllotController
(
public
SecondAllotController
(
ClaimService
claimService
,
ClaimService
claimService
,
AllotService
allotService
,
SecondAllotService
secondAllotService
,
SecondAllotService
secondAllotService
,
ResultComputeService
resultComputeService
,
ResultComputeService
resultComputeService
,
SecondAllotDetails
secondAllotDetails
,
SecondAllotDetails
secondAllotDetails
,
...
@@ -34,6 +38,7 @@ RedistributionService redistributionService
...
@@ -34,6 +38,7 @@ RedistributionService redistributionService
)
)
{
{
this
.
claimService
=
claimService
;
this
.
claimService
=
claimService
;
_allotService
=
allotService
;
this
.
secondAllotService
=
secondAllotService
;
this
.
secondAllotService
=
secondAllotService
;
this
.
resultComputeService
=
resultComputeService
;
this
.
resultComputeService
=
resultComputeService
;
this
.
secondAllotDetails
=
secondAllotDetails
;
this
.
secondAllotDetails
=
secondAllotDetails
;
...
@@ -330,7 +335,7 @@ public ApiResponse SingleDelete([CustomizeValidator(RuleSet = "Delete"), FromBod
...
@@ -330,7 +335,7 @@ public ApiResponse SingleDelete([CustomizeValidator(RuleSet = "Delete"), FromBod
[
Route
(
"/api/second/audit/submit"
)]
[
Route
(
"/api/second/audit/submit"
)]
public
ApiResponse
SubmitAudit
(
SubmitAuditRequest
request
)
public
ApiResponse
SubmitAudit
(
SubmitAuditRequest
request
)
{
{
var
second
=
secondAllotService
.
GetSecond
a
llot
(
request
.
SecondId
);
var
second
=
secondAllotService
.
GetSecond
A
llot
(
request
.
SecondId
);
if
(
second
==
null
)
if
(
second
==
null
)
return
new
ApiResponse
(
ResponseType
.
ParameterError
,
"二次绩效Id无效"
);
return
new
ApiResponse
(
ResponseType
.
ParameterError
,
"二次绩效Id无效"
);
if
(
second
.
Status
==
3
)
if
(
second
.
Status
==
3
)
...
@@ -534,18 +539,144 @@ public ApiResponse AutoCompleteBodyData([FromRoute] int secondId, SecondEmployee
...
@@ -534,18 +539,144 @@ public ApiResponse AutoCompleteBodyData([FromRoute] int secondId, SecondEmployee
return
new
ApiResponse
(
ResponseType
.
OK
,
result
);
return
new
ApiResponse
(
ResponseType
.
OK
,
result
);
}
}
#
region
二次分配后台计算
/// <summary>
/// <summary>
/// 二次绩效录入页面
/// 二次绩效录入页面
/// </summary>
/// </summary>
/// <param name="request"></param>
/// <param name="request"></param>
/// <returns></returns>
/// <returns></returns>
[
Route
(
"api/second/redistribution"
)]
[
Route
(
"api/second/redistribution
/load
"
)]
[
Http
Ge
t
]
[
Http
Pos
t
]
public
ApiResponse
Redistribution
([
FromRoute
]
SecondLoadRequest
request
)
public
ApiResponse
Redistribution
Load
([
FromBody
]
SecondLoadDto
request
)
{
{
var
result
=
_redistributionService
.
Load
(
request
.
SecondId
,
request
.
ComputeMode
);
if
(!
Enum
.
IsDefined
(
typeof
(
ComputeMode
),
request
.
ComputeMode
))
throw
new
PerformanceException
(
"暂不支持当前计算方式!"
);
var
overrideMode
=
OverrideMode
.
Initial
;
if
(
Enum
.
IsDefined
(
typeof
(
OverrideMode
),
request
.
OverrideMode
))
overrideMode
=
(
OverrideMode
)
request
.
OverrideMode
;
var
result
=
_redistributionService
.
Load
(
request
.
SecondId
,
(
ComputeMode
)
request
.
ComputeMode
,
overrideMode
);
return
new
ApiResponse
(
ResponseType
.
OK
,
result
);
return
new
ApiResponse
(
ResponseType
.
OK
,
result
);
}
}
/// <summary>
/// 提交数据正确性检验
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[
Route
(
"api/second/redistribution/check"
)]
[
HttpPost
]
public
ApiResponse
RedistributionCheck
([
FromBody
]
SecondComputeDto
request
)
{
if
(
request
?.
Body
==
null
)
throw
new
PerformanceException
(
"提交空参数,无法查看计算结果!"
);
var
second
=
secondAllotService
.
GetSecondAllot
(
request
.
SecondId
);
if
(
second
==
null
)
throw
new
PerformanceException
(
"参数SecondId无效!"
);
var
allot
=
_allotService
.
GetAllot
(
second
.
AllotId
.
Value
);
if
(
allot
==
null
)
throw
new
PerformanceException
(
"绩效记录不存在!"
);
// 年资职称绩效占比与工作量绩效占比 校验
var
loads
=
_redistributionService
.
GetWorkLoads
(
allot
.
HospitalId
,
second
.
UnitType
,
second
.
Department
);
var
workloadGroups
=
_redistributionService
.
GetTopWorkloadBodyGroups
(
loads
);
var
seniorityTitlesAccountedPerformance
=
request
.
Head
.
GetValue
(
nameof
(
ag_headsource
.
SeniorityTitlesAccountedPerformance
),
0
m
);
var
workloadRatio
=
workloadGroups
.
Sum
(
w
=>
request
.
Head
.
GetValue
(
$"Workload_Ratio_
{
w
.
Name
}
"
,
0
m
));
if
(
seniorityTitlesAccountedPerformance
+
workloadRatio
>
1
)
throw
new
PerformanceException
(
"年资职称绩效占比与工作量绩效占比总和,超过100%!"
);
else
if
(
seniorityTitlesAccountedPerformance
+
workloadRatio
<
1
)
throw
new
PerformanceException
(
"年资职称绩效占比与工作量绩效占比总和,不足100%!"
);
// 二次分配人员信息 校验
var
result
=
_redistributionService
.
CheckData
(
second
,
request
.
Body
);
return
new
ApiResponse
(
ResponseType
.
OK
,
result
);
}
/// <summary>
/// 二次绩效录入页面
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[
Route
(
"api/second/redistribution/compute"
)]
[
HttpPost
]
public
ApiResponse
RedistributionCompute
([
FromBody
]
SecondComputeDto
request
)
{
if
(!
Enum
.
IsDefined
(
typeof
(
ComputeMode
),
request
.
ComputeMode
))
throw
new
PerformanceException
(
"暂不支持当前计算方式!"
);
if
(
request
?.
Body
==
null
)
throw
new
PerformanceException
(
"提交空参数,无法查看计算结果!"
);
var
second
=
secondAllotService
.
GetSecondAllot
(
request
.
SecondId
);
if
(
second
==
null
)
throw
new
PerformanceException
(
"参数SecondId无效!"
);
var
allot
=
_allotService
.
GetAllot
(
second
.
AllotId
.
Value
);
if
(
allot
==
null
)
throw
new
PerformanceException
(
"绩效记录不存在!"
);
// 年资职称绩效占比与工作量绩效占比 校验
var
loads
=
_redistributionService
.
GetWorkLoads
(
allot
.
HospitalId
,
second
.
UnitType
,
second
.
Department
);
var
workloadGroups
=
_redistributionService
.
GetTopWorkloadBodyGroups
(
loads
);
var
seniorityTitlesAccountedPerformance
=
request
.
Head
.
GetValue
(
nameof
(
ag_headsource
.
SeniorityTitlesAccountedPerformance
),
0
m
);
var
workloadRatio
=
workloadGroups
.
Sum
(
w
=>
request
.
Head
.
GetValue
(
$"Workload_Ratio_
{
w
.
Name
}
"
,
0
m
));
if
(
seniorityTitlesAccountedPerformance
+
workloadRatio
>
1
)
throw
new
PerformanceException
(
"年资职称绩效占比与工作量绩效占比总和,超过100%!"
);
else
if
(
seniorityTitlesAccountedPerformance
+
workloadRatio
<
1
)
throw
new
PerformanceException
(
"年资职称绩效占比与工作量绩效占比总和,不足100%!"
);
// 二次分配人员信息 校验
var
checkDatas
=
_redistributionService
.
CheckData
(
second
,
request
.
Body
);
if
(
checkDatas
!=
null
&&
checkDatas
.
Any
(
w
=>
w
.
Level
==
ResponseType
.
Error
.
ToString
()))
return
new
ApiResponse
(
ResponseType
.
Fail
,
"数据验证未通过,请修复后查看计算结果!"
,
checkDatas
.
Where
(
w
=>
w
.
Level
==
ResponseType
.
Error
.
ToString
()));
// 清理无效数据 没有Tab标签的数据才是要计算的数据
var
cleanDatas
=
request
.
Body
.
Where
(
w
=>
w
.
Count
>
0
&&
w
.
GetValue
(
nameof
(
ResponseType
),
""
)
==
ResponseType
.
OK
.
ToString
()).
ToList
();
if
(
cleanDatas
==
null
||
cleanDatas
.
Count
==
0
)
throw
new
PerformanceException
(
"提交参数都是无效数据,请重新填写数据后查看计算结果!"
);
// 计算提交数据结果
_redistributionService
.
ResultCompute
((
ComputeMode
)
request
.
ComputeMode
,
request
.
Head
,
cleanDatas
,
loads
,
workloadGroups
);
// 补充医院其他绩效
_redistributionService
.
SupplementOtherPerfor
(
second
,
cleanDatas
);
// 重算顶部医院其他绩效
_redistributionService
.
OverviewCalculate_OtherPerformance
(
request
.
Head
,
cleanDatas
);
var
dic
=
_redistributionService
.
GetTableHeaderDictionary
(
loads
);
return
new
ApiResponse
(
ResponseType
.
OK
,
new
{
Head
=
request
.
Head
,
Body
=
cleanDatas
,
Dic
=
dic
});
}
/// <summary>
/// 二次绩效保存
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[
Route
(
"api/second/redistribution/save"
)]
[
HttpPost
]
public
ApiResponse
RedistributionSave
([
FromBody
]
SecondComputeDto
request
)
{
secondAllotService
.
SaveSecondAllotData
(
request
.
SecondId
,
request
);
return
new
ApiResponse
(
ResponseType
.
OK
);
}
/// <summary>
/// 二次绩效提交
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[
Route
(
"api/second/redistribution/submit"
)]
[
HttpPost
]
public
ApiResponse
RedistributionSubmit
([
FromBody
]
SecondComputeDto
request
)
{
var
second
=
secondAllotService
.
GetSecondAllot
(
request
.
SecondId
);
if
(
second
==
null
)
return
new
ApiResponse
(
ResponseType
.
ParameterError
,
"二次绩效Id无效"
);
if
(
second
.
Status
==
3
)
return
new
ApiResponse
(
ResponseType
.
Fail
,
"该绩效已\"审核通过\",无需再次提交"
);
var
userid
=
claimService
.
GetUserId
();
var
result
=
secondAllotService
.
AuditSubmit
(
second
,
userid
);
return
result
?
new
ApiResponse
(
ResponseType
.
OK
,
"提交成功"
)
:
new
ApiResponse
(
ResponseType
.
Fail
,
"提交失败"
);
}
#
endregion
}
}
}
}
performance/Performance.Api/wwwroot/Performance.Api.xml
View file @
65b03bc5
...
@@ -1612,6 +1612,41 @@
...
@@ -1612,6 +1612,41 @@
</summary>
</summary>
<returns></returns>
<returns></returns>
</member>
</member>
<member
name=
"M:Performance.Api.Controllers.SecondAllotController.RedistributionLoad(Performance.DtoModels.SecondLoadDto)"
>
<summary>
二次绩效录入页面
</summary>
<param
name=
"request"
></param>
<returns></returns>
</member>
<member
name=
"M:Performance.Api.Controllers.SecondAllotController.RedistributionCheck(Performance.DtoModels.SecondComputeDto)"
>
<summary>
提交数据正确性检验
</summary>
<param
name=
"request"
></param>
<returns></returns>
</member>
<member
name=
"M:Performance.Api.Controllers.SecondAllotController.RedistributionCompute(Performance.DtoModels.SecondComputeDto)"
>
<summary>
二次绩效录入页面
</summary>
<param
name=
"request"
></param>
<returns></returns>
</member>
<member
name=
"M:Performance.Api.Controllers.SecondAllotController.RedistributionSave(Performance.DtoModels.SecondComputeDto)"
>
<summary>
二次绩效保存
</summary>
<param
name=
"request"
></param>
<returns></returns>
</member>
<member
name=
"M:Performance.Api.Controllers.SecondAllotController.RedistributionSubmit(Performance.DtoModels.SecondComputeDto)"
>
<summary>
二次绩效提交
</summary>
<param
name=
"request"
></param>
<returns></returns>
</member>
<member
name=
"M:Performance.Api.Controllers.SheetController.SheetList(Performance.DtoModels.SheetRequest)"
>
<member
name=
"M:Performance.Api.Controllers.SheetController.SheetList(Performance.DtoModels.SheetRequest)"
>
<summary>
<summary>
sheet 列表
sheet 列表
...
...
performance/Performance.Api/wwwroot/Performance.DtoModels.xml
View file @
65b03bc5
...
@@ -179,6 +179,12 @@
...
@@ -179,6 +179,12 @@
<member
name=
"F:Performance.DtoModels.DataFormat.小数"
>
<member
name=
"F:Performance.DtoModels.DataFormat.小数"
>
<summary>
小数
</summary>
<summary>
小数
</summary>
</member>
</member>
<member
name=
"F:Performance.DtoModels.DataFormat.小数1"
>
<summary>
小数
</summary>
</member>
<member
name=
"F:Performance.DtoModels.DataFormat.整数"
>
<summary>
整数
</summary>
</member>
<member
name=
"F:Performance.DtoModels.DataFormat.货币"
>
<member
name=
"F:Performance.DtoModels.DataFormat.货币"
>
<summary>
货币
</summary>
<summary>
货币
</summary>
</member>
</member>
...
@@ -3755,6 +3761,56 @@
...
@@ -3755,6 +3761,56 @@
绩效系数
绩效系数
</summary>
</summary>
</member>
</member>
<member
name=
"T:Performance.DtoModels.Second.ComputeMode"
>
<summary>
二次分配计算方式
</summary>
</member>
<member
name=
"F:Performance.DtoModels.Second.ComputeMode.NotCalculate"
>
<summary>
不计算
</summary>
</member>
<member
name=
"F:Performance.DtoModels.Second.ComputeMode.Horizontal"
>
<summary>
横向计算
</summary>
</member>
<member
name=
"F:Performance.DtoModels.Second.ComputeMode.Vertical"
>
<summary>
纵向计算
</summary>
</member>
<member
name=
"T:Performance.DtoModels.Second.OverrideMode"
>
<summary>
人员带出方式 已保存,上次,字典,测算表
</summary>
</member>
<member
name=
"F:Performance.DtoModels.Second.OverrideMode.Initial"
>
<summary>
初始化(用户保存后的数据)
</summary>
</member>
<member
name=
"F:Performance.DtoModels.Second.OverrideMode.PrevSecondAllot"
>
<summary>
上一个二次绩效记录
</summary>
</member>
<member
name=
"F:Performance.DtoModels.Second.OverrideMode.EmployeeDict"
>
<summary>
人员字典
</summary>
</member>
<member
name=
"P:Performance.DtoModels.SecondLoadDto.ComputeMode"
>
<summary>
计算方式:1 不计算 2 横向计算 3 纵向计算
</summary>
</member>
<member
name=
"P:Performance.DtoModels.SecondLoadDto.OverrideMode"
>
<summary>
数据加载方式:0 保存,1 上次,2 字典,3 测算表
</summary>
</member>
<member
name=
"P:Performance.DtoModels.SelectionOptions.SelectionID"
>
<member
name=
"P:Performance.DtoModels.SelectionOptions.SelectionID"
>
<summary>
<summary>
ID
ID
...
...
performance/Performance.Api/wwwroot/Performance.EntityModels.xml
View file @
65b03bc5
...
@@ -474,19 +474,9 @@
...
@@ -474,19 +474,9 @@
职称绩效
职称绩效
</summary>
</summary>
</member>
</member>
<member
name=
"P:Performance.EntityModels.ag_bodysource.
ManagementAllow
ance"
>
<member
name=
"P:Performance.EntityModels.ag_bodysource.
WorkPerform
ance"
>
<summary>
<summary>
管理津贴
工作量绩效
</summary>
</member>
<member
name=
"P:Performance.EntityModels.ag_bodysource.IndividualReward"
>
<summary>
单项奖励
</summary>
</member>
<member
name=
"P:Performance.EntityModels.ag_bodysource.AllocationOfKeySpecialty"
>
<summary>
重点专科分配
</summary>
</summary>
</member>
</member>
<member
name=
"P:Performance.EntityModels.ag_bodysource.DeptReward"
>
<member
name=
"P:Performance.EntityModels.ag_bodysource.DeptReward"
>
...
@@ -936,12 +926,12 @@
...
@@ -936,12 +926,12 @@
</member>
</member>
<member
name=
"P:Performance.EntityModels.ag_headsource.TheTotalAllocationOfPerformanceResults"
>
<member
name=
"P:Performance.EntityModels.ag_headsource.TheTotalAllocationOfPerformanceResults"
>
<summary>
<summary>
科室单项奖励
业绩分配绩效总额
</summary>
</summary>
</member>
</member>
<member
name=
"P:Performance.EntityModels.ag_headsource.
BasisPerformance
"
>
<member
name=
"P:Performance.EntityModels.ag_headsource.
TotalDeptReward
"
>
<summary>
<summary>
业绩分配绩效总额
科室单项奖励
</summary>
</summary>
</member>
</member>
<member
name=
"P:Performance.EntityModels.ag_headsource.SeniorityTitlesAccountedPerformance"
>
<member
name=
"P:Performance.EntityModels.ag_headsource.SeniorityTitlesAccountedPerformance"
>
...
...
performance/Performance.DtoModels/Enum.cs
View file @
65b03bc5
...
@@ -99,6 +99,10 @@ public enum DataFormat
...
@@ -99,6 +99,10 @@ public enum DataFormat
普通格式
,
普通格式
,
/// <summary> 小数 </summary>
/// <summary> 小数 </summary>
小数
,
小数
,
/// <summary> 小数 </summary>
小数
1
,
/// <summary> 整数 </summary>
整数
,
/// <summary> 货币 </summary>
/// <summary> 货币 </summary>
货币
,
货币
,
/// <summary> 百分比 </summary>
/// <summary> 百分比 </summary>
...
...
performance/Performance.DtoModels/HandsonTable.cs
View file @
65b03bc5
...
@@ -12,12 +12,12 @@ public HandsonTableBase()
...
@@ -12,12 +12,12 @@ public HandsonTableBase()
{
{
ColHeaders
=
new
List
<
string
>();
ColHeaders
=
new
List
<
string
>();
Columns
=
new
List
<
HandsonColumn
>();
Columns
=
new
List
<
HandsonColumn
>();
Data
=
new
List
<
Dictionary
<
string
,
string
>>();
Data
=
new
List
<
Dictionary
<
string
,
object
>>();
NestedHeadersArray
=
new
List
<
List
<
string
>>();
NestedHeadersArray
=
new
List
<
List
<
string
>>();
}
}
public
List
<
string
>
ColHeaders
{
get
;
set
;
}
public
List
<
string
>
ColHeaders
{
get
;
set
;
}
public
List
<
Dictionary
<
string
,
string
>>
Data
{
get
;
set
;
}
public
List
<
Dictionary
<
string
,
object
>>
Data
{
get
;
set
;
}
public
List
<
HandsonColumn
>
Columns
{
get
;
set
;
}
public
List
<
HandsonColumn
>
Columns
{
get
;
set
;
}
public
List
<
List
<
string
>>
NestedHeadersArray
{
get
;
set
;
}
public
List
<
List
<
string
>>
NestedHeadersArray
{
get
;
set
;
}
}
}
...
@@ -95,9 +95,9 @@ private void InitColumns(List<collect_permission> permissions)
...
@@ -95,9 +95,9 @@ private void InitColumns(List<collect_permission> permissions)
Columns
=
columns
;
Columns
=
columns
;
}
}
private
Dictionary
<
string
,
string
>
CreateDataRow
(
string
key
,
string
value
)
private
Dictionary
<
string
,
object
>
CreateDataRow
(
string
key
,
string
value
)
{
{
var
temp
=
new
Dictionary
<
string
,
string
>()
{
{
key
,
value
}
};
var
temp
=
new
Dictionary
<
string
,
object
>()
{
{
key
,
value
}
};
foreach
(
var
item
in
ColHeaders
)
foreach
(
var
item
in
ColHeaders
)
{
{
if
(!
temp
.
ContainsKey
(
item
))
if
(!
temp
.
ContainsKey
(
item
))
...
@@ -125,6 +125,16 @@ public HandsonColumn(string data, bool readOnly = false, DataFormat format = Dat
...
@@ -125,6 +125,16 @@ public HandsonColumn(string data, bool readOnly = false, DataFormat format = Dat
NumericFormat
=
new
NumericFormat
{
Pattern
=
"0,00.00"
};
NumericFormat
=
new
NumericFormat
{
Pattern
=
"0,00.00"
};
break
;
break
;
case
DataFormat
.
小数
1
:
Type
=
"numeric"
;
NumericFormat
=
new
NumericFormat
{
Pattern
=
"0,00.0"
};
break
;
case
DataFormat
.
整数
:
Type
=
"numeric"
;
NumericFormat
=
new
NumericFormat
{
Pattern
=
"0,00"
};
break
;
case
DataFormat
.
百分比
:
case
DataFormat
.
百分比
:
Type
=
"numeric"
;
Type
=
"numeric"
;
NumericFormat
=
new
NumericFormat
{
Pattern
=
"0,00.00%"
};
NumericFormat
=
new
NumericFormat
{
Pattern
=
"0,00.00%"
};
...
...
performance/Performance.DtoModels/Request/SecondEmpRequest.cs
View file @
65b03bc5
...
@@ -5,14 +5,6 @@
...
@@ -5,14 +5,6 @@
namespace
Performance.DtoModels
namespace
Performance.DtoModels
{
{
public
class
SecondLoadRequest
{
public
int
SecondId
{
get
;
set
;
}
/// <summary>
/// 计算方式:1 不计算 2 横向计算 3 纵向计算
/// </summary>
public
int
ComputeMode
{
get
;
set
;
}
}
public
class
SecondEmployeeRequest
public
class
SecondEmployeeRequest
{
{
public
string
EmployeeName
{
get
;
set
;
}
public
string
EmployeeName
{
get
;
set
;
}
...
...
performance/Performance.DtoModels/ResponseType.cs
View file @
65b03bc5
...
@@ -14,5 +14,6 @@ public enum ResponseType
...
@@ -14,5 +14,6 @@ public enum ResponseType
ParameterError
=
6
,
ParameterError
=
6
,
Disable
=
7
,
Disable
=
7
,
TooManyRequests
=
8
,
TooManyRequests
=
8
,
Warning
=
9
,
}
}
}
}
performance/Performance.DtoModels/Second/Constant.cs
0 → 100644
View file @
65b03bc5
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
namespace
Performance.DtoModels.Second
{
/// <summary>
/// 二次分配计算方式
/// </summary>
public
enum
ComputeMode
{
/// <summary>
/// 不计算
/// </summary>
NotCalculate
=
1
,
/// <summary>
/// 横向计算
/// </summary>
Horizontal
=
2
,
/// <summary>
/// 纵向计算
/// </summary>
Vertical
=
3
,
}
/// <summary>
/// 人员带出方式 已保存,上次,字典,测算表
/// </summary>
public
enum
OverrideMode
{
/// <summary>
/// 初始化(用户保存后的数据)
/// </summary>
Initial
=
0
,
/// <summary>
/// 上一个二次绩效记录
/// </summary>
PrevSecondAllot
=
1
,
/// <summary>
/// 人员字典
/// </summary>
EmployeeDict
=
2
,
}
}
performance/Performance.DtoModels/Second/SecondColumnDictionary.cs
0 → 100644
View file @
65b03bc5
namespace
Performance.DtoModels
{
public
class
SecondColumnDictionary
{
public
string
Label
{
get
;
set
;
}
public
string
Key
{
get
;
set
;
}
public
bool
IsTrue
{
get
;
set
;
}
public
int
Sort
{
get
;
set
;
}
public
SecondColumnDictionary
()
{
}
public
SecondColumnDictionary
(
string
label
,
string
key
,
bool
isTrue
,
int
sort
)
{
Label
=
label
;
Key
=
key
;
IsTrue
=
isTrue
;
Sort
=
sort
;
}
}
}
performance/Performance.DtoModels/Second/SecondComputeCheckResultDto.cs
0 → 100644
View file @
65b03bc5
namespace
Performance.DtoModels
{
public
class
SecondComputeCheckResultDto
{
public
SecondComputeCheckResultDto
(
string
level
,
string
personnelNumber
,
string
personnelName
,
string
message
)
{
Level
=
level
;
PersonnelNumber
=
personnelNumber
;
PersonnelName
=
personnelName
;
Message
=
message
;
}
public
string
Level
{
get
;
set
;
}
public
string
PersonnelNumber
{
get
;
set
;
}
public
string
PersonnelName
{
get
;
set
;
}
public
string
Message
{
get
;
set
;
}
}
}
performance/Performance.DtoModels/Second/SecondComputeDto.cs
0 → 100644
View file @
65b03bc5
using
System.Collections.Generic
;
namespace
Performance.DtoModels
{
public
class
SecondComputeDto
:
SecondLoadDto
{
public
Dictionary
<
string
,
object
>
Head
{
get
;
set
;
}
public
List
<
Dictionary
<
string
,
object
>>
Body
{
get
;
set
;
}
}
}
performance/Performance.DtoModels/Second/SecondDetailDto.cs
0 → 100644
View file @
65b03bc5
using
System.Collections.Generic
;
namespace
Performance.DtoModels
{
public
class
SecondDetailDto
{
public
object
Head
{
get
;
set
;
}
public
HandsonTableBase
Body
{
get
;
set
;
}
public
List
<
SecondColumnDictionary
>
Dic
{
get
;
set
;
}
}
}
performance/Performance.DtoModels/Second/SecondLoadDto.cs
0 → 100644
View file @
65b03bc5
namespace
Performance.DtoModels
{
public
class
SecondLoadDto
{
public
int
SecondId
{
get
;
set
;
}
/// <summary>
/// 计算方式:1 不计算 2 横向计算 3 纵向计算
/// </summary>
public
int
ComputeMode
{
get
;
set
;
}
/// <summary>
/// 数据加载方式:0 保存,1 上次,2 字典,3 测算表
/// </summary>
public
int
OverrideMode
{
get
;
set
;
}
}
}
performance/Performance.DtoModels/Second/SecondWorkLoadDto.cs
0 → 100644
View file @
65b03bc5
using
System
;
using
System.Collections.Generic
;
namespace
Performance.DtoModels
{
public
class
SecondWorkLoadDto
{
public
SecondWorkLoadDto
(
string
name
)
{
Name
=
name
;
Unit_Price
=
0
m
;
Items
=
new
List
<
string
>();
AssessmentScore
=
$"AssessmentScore_
{
Name
}
"
;
WorkPerformance
=
$"WorkPerformance_
{
Name
}
"
;
WorkloadScore
=
$"WorkloadScore_
{
Name
}
"
;
}
public
string
AssessmentScore
{
get
;
set
;
}
public
string
WorkPerformance
{
get
;
set
;
}
public
string
WorkloadScore
{
get
;
set
;
}
public
decimal
Unit_Price
{
get
;
set
;
}
public
List
<
string
>
Items
{
get
;
set
;
}
public
string
Name
{
get
;
set
;
}
public
void
AddItem
(
string
name
)
{
if
(!
Items
.
Contains
(
name
))
Items
.
Add
(
name
);
}
}
}
performance/Performance.EntityModels/Entity/ag_bodysource.cs
View file @
65b03bc5
...
@@ -77,19 +77,24 @@ public class ag_bodysource
...
@@ -77,19 +77,24 @@ public class ag_bodysource
public
Nullable
<
decimal
>
TitlePerformance
{
get
;
set
;
}
public
Nullable
<
decimal
>
TitlePerformance
{
get
;
set
;
}
/// <summary>
/// <summary>
///
管理津贴
///
工作量绩效
/// </summary>
/// </summary>
public
Nullable
<
decimal
>
ManagementAllow
ance
{
get
;
set
;
}
public
Nullable
<
decimal
>
WorkPerform
ance
{
get
;
set
;
}
/// <summary>
///
//
<summary>
///
单项奖励
///
// 管理津贴
/// </summary>
///
//
</summary>
public
Nullable
<
decimal
>
IndividualReward
{
get
;
set
;
}
//public Nullable<decimal> ManagementAllowance
{ get; set; }
/// <summary>
///// <summary>
/// 重点专科分配
///// 单项奖励
/// </summary>
///// </summary>
public
Nullable
<
decimal
>
AllocationOfKeySpecialty
{
get
;
set
;
}
//public Nullable<decimal> IndividualReward { get; set; }
///// <summary>
///// 重点专科分配
///// </summary>
//public Nullable<decimal> AllocationOfKeySpecialty { get; set; }
/// <summary>
/// <summary>
/// 科室单项奖励
/// 科室单项奖励
...
...
performance/Performance.EntityModels/Entity/ag_headsource.cs
View file @
65b03bc5
...
@@ -52,14 +52,19 @@ public class ag_headsource
...
@@ -52,14 +52,19 @@ public class ag_headsource
public
Nullable
<
decimal
>
DirectorBasisPerformance
{
get
;
set
;
}
public
Nullable
<
decimal
>
DirectorBasisPerformance
{
get
;
set
;
}
/// <summary>
/// <summary>
///
科室单项奖励
///
业绩分配绩效总额
/// </summary>
/// </summary>
public
Nullable
<
decimal
>
TheTotalAllocationOfPerformanceResults
{
get
;
set
;
}
public
Nullable
<
decimal
>
TheTotalAllocationOfPerformanceResults
{
get
;
set
;
}
/// <summary>
/// <summary>
///
业绩分配绩效总额
///
科室单项奖励
/// </summary>
/// </summary>
public
Nullable
<
decimal
>
BasisPerformance
{
get
;
set
;
}
public
Nullable
<
decimal
>
TotalDeptReward
{
get
;
set
;
}
///// <summary>
///// 业绩分配绩效总额
///// </summary>
//public Nullable<decimal> BasisPerformance { get; set; }
/// <summary>
/// <summary>
/// 年资职称绩效占比
/// 年资职称绩效占比
...
...
performance/Performance.Infrastructure/Extensions/Extensions.Dictionary.cs
View file @
65b03bc5
...
@@ -18,9 +18,9 @@ public static partial class UtilExtensions
...
@@ -18,9 +18,9 @@ public static partial class UtilExtensions
/// <returns></returns>
/// <returns></returns>
public
static
T
GetValue
<
T
>(
this
Dictionary
<
string
,
object
>
keyValues
,
string
key
,
T
defaultValue
=
default
(
T
))
public
static
T
GetValue
<
T
>(
this
Dictionary
<
string
,
object
>
keyValues
,
string
key
,
T
defaultValue
=
default
(
T
))
{
{
object
value
;
var
pair
=
keyValues
.
FirstOrDefault
(
w
=>
w
.
Key
.
Equals
(
key
,
StringComparison
.
OrdinalIgnoreCase
))
;
if
(
keyValues
.
TryGetValue
(
key
,
out
value
))
if
(
!
default
(
KeyValuePair
<
string
,
object
>).
Equals
(
pair
))
return
ConvertHelper
.
To
<
T
>(
v
alue
,
defaultValue
);
return
ConvertHelper
.
To
<
T
>(
pair
.
V
alue
,
defaultValue
);
return
defaultValue
;
return
defaultValue
;
}
}
...
@@ -33,13 +33,29 @@ public static T GetValue<T>(this Dictionary<string, object> keyValues, string ke
...
@@ -33,13 +33,29 @@ public static T GetValue<T>(this Dictionary<string, object> keyValues, string ke
/// <returns></returns>
/// <returns></returns>
public
static
T
GetValue
<
T
>(
this
SortedDictionary
<
string
,
object
>
keyValues
,
string
key
,
T
defaultValue
=
default
(
T
))
public
static
T
GetValue
<
T
>(
this
SortedDictionary
<
string
,
object
>
keyValues
,
string
key
,
T
defaultValue
=
default
(
T
))
{
{
object
value
;
var
pair
=
keyValues
.
FirstOrDefault
(
w
=>
w
.
Key
.
Equals
(
key
,
StringComparison
.
OrdinalIgnoreCase
))
;
if
(
keyValues
.
TryGetValue
(
key
,
out
value
))
if
(
!
default
(
KeyValuePair
<
string
,
object
>).
Equals
(
pair
))
return
ConvertHelper
.
To
<
T
>(
v
alue
,
defaultValue
);
return
ConvertHelper
.
To
<
T
>(
pair
.
V
alue
,
defaultValue
);
return
defaultValue
;
return
defaultValue
;
}
}
/// <summary>
/// <summary>
/// 添加或修改
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="keyValues"></param>
/// <param name="key"></param>
/// <returns></returns>
public
static
void
AddOrUpdate
(
this
Dictionary
<
string
,
object
>
keyValues
,
string
key
,
object
value
)
{
var
pair
=
keyValues
.
FirstOrDefault
(
w
=>
w
.
Key
.
Equals
(
key
,
StringComparison
.
OrdinalIgnoreCase
));
if
(
default
(
KeyValuePair
<
string
,
object
>).
Equals
(
pair
))
keyValues
.
Add
(
key
,
value
);
else
keyValues
[
key
]
=
value
;
}
/// <summary>
/// form 转换 键值对
/// form 转换 键值对
/// </summary>
/// </summary>
/// <param name="pairs"></param>
/// <param name="pairs"></param>
...
...
performance/Performance.Infrastructure/Extensions/Extensions.String.cs
View file @
65b03bc5
...
@@ -26,5 +26,27 @@ public static string[] SplitRemoveEmpty(this string text, params string[] separa
...
@@ -26,5 +26,27 @@ public static string[] SplitRemoveEmpty(this string text, params string[] separa
{
{
return
text
.
Split
(
separator
,
StringSplitOptions
.
RemoveEmptyEntries
);
return
text
.
Split
(
separator
,
StringSplitOptions
.
RemoveEmptyEntries
);
}
}
/// <summary>
/// 确定此字符串实例的开头是否与指定的匹配 忽略字母的大小写
/// </summary>
/// <param name="text"></param>
/// <param name="value"></param>
/// <returns></returns>
public
static
bool
StartsWithIgnoreCase
(
this
string
text
,
string
value
)
{
return
text
.
StartsWith
(
value
,
StringComparison
.
OrdinalIgnoreCase
);
}
/// <summary>
/// 确定此字符串是否与指定的字符串对象具有相同的值 忽略字母的大小写
/// </summary>
/// <param name="text"></param>
/// <param name="value"></param>
/// <returns></returns>
public
static
bool
EqualsIgnoreCase
(
this
string
text
,
string
value
)
{
return
text
.
Equals
(
value
,
StringComparison
.
OrdinalIgnoreCase
);
}
}
}
}
}
performance/Performance.Repository/PerforPerapramounthideRepository.cs
View file @
65b03bc5
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
namespace
Performance.Repository
namespace
Performance.Repository
{
{
/// <summary>
/// <summary>
/// per_apr_amount Repository
/// per_apr_amount
_hide
Repository
/// </summary>
/// </summary>
public
partial
class
PerforPerapramounthideRepository
:
PerforRepository
<
per_apr_amount_hide
>
public
partial
class
PerforPerapramounthideRepository
:
PerforRepository
<
per_apr_amount_hide
>
{
{
...
...
performance/Performance.Services/PersonService.cs
View file @
65b03bc5
...
@@ -208,7 +208,7 @@ public PageList<per_employee> GetPersons(int allotId, int userId, PersonParamsRe
...
@@ -208,7 +208,7 @@ public PageList<per_employee> GetPersons(int allotId, int userId, PersonParamsRe
if
(
request
!=
null
&&
!
string
.
IsNullOrEmpty
(
request
.
SearchQuery
))
if
(
request
!=
null
&&
!
string
.
IsNullOrEmpty
(
request
.
SearchQuery
))
{
{
exp
=
exp
.
And
(
t
=>
true
&&
(
t
.
AccountingUnit
.
Contains
(
request
.
SearchQuery
)
||
t
.
DoctorName
.
Contains
(
request
.
SearchQuery
)
||
t
.
Department
.
Contains
(
request
.
SearchQuery
)));
exp
=
exp
.
And
(
t
=>
true
&&
(
t
.
AccountingUnit
.
Contains
(
request
.
SearchQuery
)
||
t
.
PersonnelNumber
.
Contains
(
request
.
SearchQuery
)
||
t
.
DoctorName
.
Contains
(
request
.
SearchQuery
)
||
t
.
Department
.
Contains
(
request
.
SearchQuery
)));
}
}
var
result
=
new
List
<
per_employee
>();
var
result
=
new
List
<
per_employee
>();
...
...
performance/Performance.Services/RedistributionService.cs
View file @
65b03bc5
...
@@ -6,32 +6,75 @@
...
@@ -6,32 +6,75 @@
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Linq
;
using
System.Text
;
using
System.Text
;
using
Performance.Infrastructure
;
using
Newtonsoft.Json.Linq
;
using
Newtonsoft.Json
;
using
Performance.DtoModels.Second
;
using
Microsoft.Extensions.Logging
;
namespace
Performance.Services
namespace
Performance.Services
{
{
public
class
RedistributionService
:
IAutoInjection
public
class
RedistributionService
:
IAutoInjection
{
{
#
region
构造函数
private
readonly
ILogger
<
RedistributionService
>
_logger
;
private
readonly
SecondAllotDetails
_secondAllotDetails
;
private
readonly
PerforPerallotRepository
_perallotRepository
;
private
readonly
PerforPerallotRepository
_perallotRepository
;
private
readonly
PerforPeremployeeRepository
_peremployeeRepository
;
private
readonly
PerforAgsecondallotRepository
_secondallotRepository
;
private
readonly
PerforAgsecondallotRepository
_secondallotRepository
;
private
readonly
PerforPerapramountRepository
_perapramountRepository
;
private
readonly
PerforAgothersourceRepository
_agothersourceRepository
;
private
readonly
PerforAgfixatitemRepository
_agfixatitemRepository
;
private
readonly
PerforAgheadsourceRepository
_agheadsourceRepository
;
private
readonly
PerforAgbodysourceRepository
_agbodysourceRepository
;
private
readonly
PerforAgworktypesourceRepository
_agworktypesourceRepository
;
private
readonly
PerforAgworkloadRepository
_agworkloadRepository
;
private
readonly
PerforAgworkloadRepository
_agworkloadRepository
;
private
readonly
PerforAgworkloadsourceRepository
_agworkloadsourceRepository
;
private
readonly
PerforImemployeelogisticsRepository
_imemployeelogisticsRepository
;
public
RedistributionService
(
public
RedistributionService
(
ILogger
<
RedistributionService
>
logger
,
SecondAllotDetails
secondAllotDetails
,
PerforPerallotRepository
perallotRepository
,
PerforPerallotRepository
perallotRepository
,
PerforPeremployeeRepository
peremployeeRepository
,
PerforAgsecondallotRepository
secondallotRepository
,
PerforAgsecondallotRepository
secondallotRepository
,
PerforAgworkloadRepository
agworkloadRepository
)
PerforPerapramountRepository
perapramountRepository
,
PerforAgothersourceRepository
agothersourceRepository
,
PerforAgfixatitemRepository
agfixatitemRepository
,
PerforAgheadsourceRepository
agheadsourceRepository
,
PerforAgbodysourceRepository
agbodysourceRepository
,
PerforAgworktypesourceRepository
agworktypesourceRepository
,
PerforAgworkloadRepository
agworkloadRepository
,
PerforAgworkloadsourceRepository
agworkloadsourceRepository
,
PerforImemployeelogisticsRepository
imemployeelogisticsRepository
)
{
{
_logger
=
logger
;
_secondAllotDetails
=
secondAllotDetails
;
_perallotRepository
=
perallotRepository
;
_perallotRepository
=
perallotRepository
;
_peremployeeRepository
=
peremployeeRepository
;
_secondallotRepository
=
secondallotRepository
;
_secondallotRepository
=
secondallotRepository
;
_perapramountRepository
=
perapramountRepository
;
_agothersourceRepository
=
agothersourceRepository
;
_agfixatitemRepository
=
agfixatitemRepository
;
_agheadsourceRepository
=
agheadsourceRepository
;
_agbodysourceRepository
=
agbodysourceRepository
;
_agworktypesourceRepository
=
agworktypesourceRepository
;
_agworkloadRepository
=
agworkloadRepository
;
_agworkloadRepository
=
agworkloadRepository
;
_agworkloadsourceRepository
=
agworkloadsourceRepository
;
_imemployeelogisticsRepository
=
imemployeelogisticsRepository
;
}
}
#
endregion
#
region
加载
/// <summary>
/// <summary>
///
///
加载
/// </summary>
/// </summary>
/// <param name="secondId"></param>
/// <param name="secondId"></param>
/// <param name="computeMode">计算方式:1 不计算 2 横向计算 3 纵向计算</param>
/// <param name="computeMode">计算方式:1 不计算 2 横向计算 3 纵向计算</param>
/// <param name="overrideMode">数据加载方式:0 保存,1 上次,2 字典,3 测算表</param>
/// <returns></returns>
/// <returns></returns>
public
HandsonTableBase
Load
(
int
secondId
,
int
comput
eMode
)
public
SecondDetailDto
Load
(
int
secondId
,
ComputeMode
computeMode
,
OverrideMode
overrid
eMode
)
{
{
var
second
=
_secondallotRepository
.
GetEntity
(
t
=>
t
.
Id
==
secondId
);
var
second
=
_secondallotRepository
.
GetEntity
(
t
=>
t
.
Id
==
secondId
);
if
(
second
==
null
)
throw
new
PerformanceException
(
"参数SecondId无效!"
);
if
(
second
==
null
)
throw
new
PerformanceException
(
"参数SecondId无效!"
);
...
@@ -45,17 +88,39 @@ public HandsonTableBase Load(int secondId, int computeMode)
...
@@ -45,17 +88,39 @@ public HandsonTableBase Load(int secondId, int computeMode)
HandsonTableBase
handson
=
new
HandsonTableBase
();
HandsonTableBase
handson
=
new
HandsonTableBase
();
switch
(
computeMode
)
switch
(
computeMode
)
{
{
case
1
:
case
ComputeMode
.
NotCalculate
:
handson
=
ComputeMode_Format1
(
colHeaderCustoms
,
columnCustoms
);
handson
=
ComputeMode_Format1
(
colHeaderCustoms
,
columnCustoms
);
break
;
break
;
case
2
:
case
ComputeMode
.
Horizontal
:
handson
=
ComputeMode_Format2
(
colHeaderCustoms
,
columnCustoms
);
handson
=
ComputeMode_Format2
(
colHeaderCustoms
,
columnCustoms
);
break
;
break
;
case
3
:
case
ComputeMode
.
Vertical
:
handson
=
ComputeMode_Format3
(
colHeaderCustoms
,
columnCustoms
,
loads
);
handson
=
ComputeMode_Format3
(
colHeaderCustoms
,
columnCustoms
,
loads
);
break
;
break
;
}
}
// 先占位,更加选择加载指定范围数据
// 加载方式分 保存,上次,字典,测算表
var
loadEmployees
=
LoadEmployees
(
allot
,
second
,
overrideMode
);
// 设置固定信息默认值
foreach
(
var
item
in
loadEmployees
)
{
item
.
StaffCoefficient
=
item
.
StaffCoefficient
??
1
;
// 人员系数
item
.
ActualAttendance
=
item
.
ActualAttendance
??
DateTime
.
DaysInMonth
(
allot
.
Year
,
allot
.
Month
);
// 出勤
item
.
TitleCoefficient
=
item
.
TitleCoefficient
??
1
;
// 职称系数
}
// 加载已保存工作量数据
handson
.
Data
=
LoadWorkload
(
allot
,
second
,
loadEmployees
);
// 设置工作量考核等分默认值
foreach
(
var
item
in
handson
.
Data
)
{
foreach
(
var
score
in
item
.
Where
(
w
=>
w
.
Key
.
StartsWithIgnoreCase
(
"AssessmentScore_"
)).
ToList
())
{
if
(
score
.
Value
==
null
)
item
.
AddOrUpdate
(
score
.
Key
,
100
);
}
}
#
region
结构案例
#
region
结构案例
//var colHeaders = new List<string> { "工号", "姓名", "核算单元", "主管", "人员系数", "出勤", "职称", "职称系数", "A班", "P班", "N班", "考核得分", "A班", "P班", "N班", "考核得分", "单项奖励A", "单项奖励B", "夜班绩效", };
//var colHeaders = new List<string> { "工号", "姓名", "核算单元", "主管", "人员系数", "出勤", "职称", "职称系数", "A班", "P班", "N班", "考核得分", "A班", "P班", "N班", "考核得分", "单项奖励A", "单项奖励B", "夜班绩效", };
...
@@ -116,42 +181,475 @@ public HandsonTableBase Load(int secondId, int computeMode)
...
@@ -116,42 +181,475 @@ public HandsonTableBase Load(int secondId, int computeMode)
#
endregion
#
endregion
return
handson
;
var
head
=
LoadHead
(
computeMode
,
allot
,
second
);
var
dic
=
GetTableHeaderDictionary
(
loads
);
return
new
SecondDetailDto
{
Head
=
head
,
Body
=
handson
,
Dic
=
dic
};
}
public
List
<
SecondColumnDictionary
>
GetTableHeaderDictionary
(
List
<
TitleValue
<
string
,
decimal
?>>
loads
)
{
var
maps
=
new
List
<
SecondColumnDictionary
>()
{
new
SecondColumnDictionary
(
"人员工号"
,
"worknumber"
,
true
,
100
),
new
SecondColumnDictionary
(
"姓名"
,
"name"
,
true
,
100
),
new
SecondColumnDictionary
(
"核算单元"
,
"department"
,
true
,
100
),
new
SecondColumnDictionary
(
"主管"
,
"post"
,
true
,
100
),
new
SecondColumnDictionary
(
"人员系数"
,
"staffcoefficient"
,
true
,
200
),
new
SecondColumnDictionary
(
"出勤"
,
"actualattendance"
,
true
,
201
),
new
SecondColumnDictionary
(
"职称"
,
"jobtitle"
,
true
,
202
),
new
SecondColumnDictionary
(
"职称系数"
,
"titlecoefficient"
,
true
,
203
),
new
SecondColumnDictionary
(
"职称绩效"
,
"titleperformance"
,
true
,
299
),
new
SecondColumnDictionary
(
"工作量绩效工资"
,
"workperformance"
,
true
,
399
),
new
SecondColumnDictionary
(
"单项奖励"
,
"deptreward"
,
true
,
499
),
new
SecondColumnDictionary
(
"可分配绩效"
,
"distperformance"
,
true
,
500
),
new
SecondColumnDictionary
(
"医院其他绩效"
,
"otherperformance"
,
true
,
501
),
new
SecondColumnDictionary
(
"夜班工作量绩效"
,
"nightworkperformance"
,
true
,
502
),
new
SecondColumnDictionary
(
"预留比例"
,
"reservedratio"
,
true
,
601
),
new
SecondColumnDictionary
(
"预留金额"
,
"reservedamount"
,
true
,
602
),
new
SecondColumnDictionary
(
"实发绩效工资金额"
,
"realamount"
,
true
,
700
),
};
// 工作量
int
sort
=
300
;
foreach
(
var
item
in
loads
.
Where
(
w
=>
!
w
.
Title
.
StartsWithIgnoreCase
(
"SingleAwards_"
)))
{
maps
.
Add
(
new
SecondColumnDictionary
(
item
.
Value
,
item
.
Title
,
false
,
++
sort
));
}
// 单项奖励
sort
=
400
;
foreach
(
var
item
in
loads
.
Where
(
w
=>
w
.
Title
.
StartsWithIgnoreCase
(
"SingleAwards_"
)))
{
maps
.
Add
(
new
SecondColumnDictionary
(
item
.
Value
,
item
.
Title
,
false
,
++
sort
));
}
return
maps
.
OrderBy
(
w
=>
w
.
Sort
).
ToList
();
}
/// <summary>
/// 加载已保存工作量数据,加载时区分:已提交和未提交
/// </summary>
/// <param name="allot"></param>
/// <param name="second"></param>
/// <param name="loadEmployees"></param>
/// <returns></returns>
private
List
<
Dictionary
<
string
,
object
>>
LoadWorkload
(
per_allot
allot
,
ag_secondallot
second
,
List
<
ag_bodysource
>
loadEmployees
)
{
List
<
Dictionary
<
string
,
object
>>
result
=
new
List
<
Dictionary
<
string
,
object
>>();
var
status
=
(
new
int
[]
{
(
int
)
SecondAllotStatus
.
WaitReview
,
(
int
)
SecondAllotStatus
.
PassAudit
});
// 已提交
if
(
second
.
Status
.
HasValue
&&
status
.
Contains
(
second
.
Status
.
Value
))
{
var
bodyDynamic
=
_agworkloadsourceRepository
.
GetEntities
(
t
=>
loadEmployees
.
Select
(
w
=>
w
.
Id
).
Contains
(
t
.
BodyId
));
foreach
(
var
employee
in
loadEmployees
)
{
var
dict
=
JsonHelper
.
Deserialize
<
Dictionary
<
string
,
object
>>(
JsonHelper
.
Serialize
(
employee
));
if
(
bodyDynamic
!=
null
&&
bodyDynamic
.
Any
(
t
=>
t
.
BodyId
==
employee
.
Id
))
{
foreach
(
var
col
in
bodyDynamic
.
Where
(
t
=>
t
.
BodyId
==
employee
.
Id
))
{
dict
.
Add
(
col
.
ItemId
,
col
.
Value
);
}
}
result
.
Add
(
dict
);
}
}
// 未提交
else
{
var
bodyDynamic
=
_agworkloadsourceRepository
.
GetEntities
(
t
=>
loadEmployees
.
Select
(
w
=>
w
.
Id
).
Contains
(
t
.
BodyId
));
var
workloads
=
_agworkloadRepository
.
GetEntities
(
t
=>
t
.
HospitalId
==
allot
.
HospitalId
&&
t
.
Department
==
second
.
Department
&&
t
.
UnitType
==
second
.
UnitType
);
if
(
workloads
!=
null
&&
workloads
.
Any
())
{
foreach
(
var
employee
in
loadEmployees
)
{
var
dict
=
JsonHelper
.
Deserialize
<
Dictionary
<
string
,
object
>>(
JsonHelper
.
Serialize
(
employee
));
foreach
(
var
workitem
in
workloads
)
{
var
value
=
bodyDynamic
?.
FirstOrDefault
(
w
=>
w
.
BodyId
==
employee
.
Id
&&
w
.
WorkloadId
==
workitem
.
Id
)?.
Value
;
dict
.
Add
(
workitem
.
ItemId
,
value
);
}
result
.
Add
(
dict
);
}
}
}
return
result
;
}
/// <summary>
/// 顶部信息加载
/// </summary>
/// <param name="computeMode"></param>
/// <param name="second"></param>
/// <param name="allot"></param>
/// <returns></returns>
private
Dictionary
<
string
,
object
>
LoadHead
(
ComputeMode
computeMode
,
per_allot
allot
,
ag_secondallot
second
)
{
var
head
=
new
Dictionary
<
string
,
object
>();
// 公共顶部信息
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
SecondId
),
second
.
Id
);
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
PaymentOfTheMonth
),
$"
{
allot
.
Year
}
年
{
allot
.
Month
.
ToString
().
PadLeft
(
2
,
'0'
)}
月"
);
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
TotalDistPerformance
),
second
.
RealGiveFee
??
0
);
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
NightShiftWorkPerforTotal
),
second
.
NightShiftWorkPerforFee
??
0
);
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
TotalPerformance
),
(
second
.
RealGiveFee
??
0
)
-
(
second
.
NightShiftWorkPerforFee
??
0
));
// 横向 纵向 特有顶部信息
if
(
computeMode
!=
ComputeMode
.
NotCalculate
)
{
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
DaysFullAttendance
),
DateTime
.
DaysInMonth
(
allot
.
Year
,
allot
.
Month
));
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
SeniorityTitlesAccountedPerformance
),
0.2
m
);
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
Workload_Ratio_Default
),
0.8
m
);
var
history
=
_agheadsourceRepository
.
GetEntity
(
t
=>
t
.
SecondId
==
second
.
Id
);
if
(
history
!=
null
)
{
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
SeniorityTitlesAccountedPerformance
),
history
.
SeniorityTitlesAccountedPerformance
);
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
Workload_Ratio_Default
),
history
.
Workload_Ratio_Default
);
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
DaysFullAttendance
),
history
.
DaysFullAttendance
);
}
// 多工作量加载
var
headDynamic
=
_agworktypesourceRepository
.
GetEntities
(
t
=>
t
.
SecondId
==
second
.
Id
);
if
(
headDynamic
!=
null
&&
headDynamic
.
Any
())
{
foreach
(
var
item
in
headDynamic
.
Where
(
w
=>
w
.
FieldId
.
StartsWithIgnoreCase
(
"Workload_Ratio_"
)).
OrderBy
(
t
=>
t
.
Id
))
{
head
.
AddOrUpdate
(
item
.
FieldId
,
item
.
Value
??
0
);
}
}
}
return
head
;
}
/// <summary>
/// 按指定方式加载人员数据
/// </summary>
/// <param name="secondId"></param>
/// <param name="mode"></param>
/// <returns></returns>
private
List
<
ag_bodysource
>
LoadEmployees
(
per_allot
allot
,
ag_secondallot
second
,
OverrideMode
mode
)
{
var
employees
=
_peremployeeRepository
.
GetEntities
(
w
=>
w
.
AllotId
==
second
.
AllotId
);
// 默认流程
if
(
mode
==
OverrideMode
.
Initial
)
{
var
saveDatas
=
_agbodysourceRepository
.
GetEntities
(
w
=>
w
.
SecondId
==
second
.
Id
);
// 数据带出顺序 1 已保存 2 上次 3 科室字典(或EXCEL行政工勤)
if
(
saveDatas
!=
null
)
return
saveDatas
;
List
<
string
>
numbers
=
LoadEmployees_PrevSecondAllot
(
allot
,
second
);
// 如果行政工勤科室没有保存数据,则默认从EXCEL中带出数据
if
(
UnitTypeUtil
.
IsOffice
(
second
.
UnitType
)
&&
(
numbers
==
null
||
numbers
.
Count
==
0
))
numbers
=
LoadEmployees_OfficeExcel
(
second
);
if
(
numbers
==
null
||
numbers
.
Count
==
0
)
numbers
=
LoadEmployees_EmployeeDict
(
second
,
employees
);
return
LoadEmployeeByDictionary
(
second
,
employees
,
numbers
);
}
// 用户指定加载
else
{
List
<
string
>
numbers
=
new
List
<
string
>();
if
(
mode
==
OverrideMode
.
PrevSecondAllot
)
numbers
=
LoadEmployees_PrevSecondAllot
(
allot
,
second
);
// 如果行政工勤科室则默认从EXCEL中带出数据
else
if
(
mode
==
OverrideMode
.
EmployeeDict
&&
UnitTypeUtil
.
IsOffice
(
second
.
UnitType
))
numbers
=
LoadEmployees_OfficeExcel
(
second
);
else
if
(
mode
==
OverrideMode
.
EmployeeDict
)
numbers
=
LoadEmployees_EmployeeDict
(
second
,
employees
);
if
(
numbers
==
null
||
numbers
.
Count
==
0
)
return
new
List
<
ag_bodysource
>();
return
LoadEmployeeByDictionary
(
second
,
employees
,
numbers
);
}
//var data = new List<Dictionary<string, object>>();
//foreach (var item in loadDatas)
//{
// data.Add(new Dictionary<string, object>
// {
// { nameof(ag_bodysource.SecondId), item.SecondId },
// { nameof(ag_bodysource.Department), item.Department },
// { nameof(ag_bodysource.WorkNumber), item.WorkNumber },
// { nameof(ag_bodysource.Name), item.Name },
// { nameof(ag_bodysource.JobTitle), item.JobTitle },
// { nameof(ag_bodysource.ReservedRatio), item.ReservedRatio },
// { nameof(ag_bodysource.Post), item.Post },
// // 设置默认值
// { nameof(ag_bodysource.StaffCoefficient), item.StaffCoefficient ?? 1 },
// { nameof(ag_bodysource.ActualAttendance), item.ActualAttendance ?? DateTime.DaysInMonth(allot.Year, allot.Month) },
// { nameof(ag_bodysource.TitleCoefficient), item.TitleCoefficient ?? 1 },
// });
//}
//return data;
}
List
<
ag_bodysource
>
LoadEmployeeByDictionary
(
ag_secondallot
second
,
List
<
per_employee
>
employees
,
List
<
string
>
numbers
)
{
List
<
ag_bodysource
>
loadDatas
=
new
List
<
ag_bodysource
>();
foreach
(
var
personnelNumber
in
numbers
)
{
var
existEmp
=
employees
.
FirstOrDefault
(
w
=>
w
.
PersonnelNumber
?.
Trim
()
==
personnelNumber
?.
Trim
());
if
(
existEmp
==
null
)
continue
;
loadDatas
.
Add
(
new
ag_bodysource
{
SecondId
=
second
.
Id
,
Department
=
existEmp
.
AccountingUnit
,
WorkNumber
=
existEmp
.
PersonnelNumber
,
Name
=
existEmp
.
DoctorName
,
JobTitle
=
existEmp
.
JobTitle
,
ReservedRatio
=
existEmp
.
ReservedRatio
,
Post
=
"否"
,
});
}
return
loadDatas
;
}
private
List
<
string
>
LoadEmployees_PrevSecondAllot
(
per_allot
allot
,
ag_secondallot
second
)
{
//List<ag_bodysource> bodysources = new List<ag_bodysource>();
//// 上次二次分配分三种情况,1.其他来源 2.单工作量 3.多工作量
//var prevSecondAllot = _secondAllotDetails.GetPreviousSecondAllot(allot.HospitalId, second);
//var status = new int[] { (int)SecondAllotStatus.WaitReview, (int)SecondAllotStatus.PassAudit };
//if (prevSecondAllot != null && status.Contains(prevSecondAllot.Status ?? (int)SecondAllotStatus.Uncommitted))
//{
// if (prevSecondAllot.Status == 6)
// {
// var prevDatas = _agothersourceRepository.GetEntities(w => w.SecondId == prevSecondAllot.Id);
// if (prevDatas != null)
// {
// foreach (var pre in prevDatas)
// {
// var existEmp = dicEmployees.FirstOrDefault(w => w.PersonnelNumber?.Trim() == pre.WorkNumber?.Trim());
// if (existEmp != null)
// continue;
// bodysources.Add(new ag_bodysource
// {
// SecondId = second.Id,
// Department = existEmp.AccountingUnit,
// WorkNumber = existEmp.PersonnelNumber,
// Name = existEmp.DoctorName,
// JobTitle = existEmp.JobTitle,
// ReservedRatio = existEmp.ReservedRatio,
// Post = "否",
// });
// }
// }
// }
// else if (prevSecondAllot.Status == 7 || prevSecondAllot.Status == 8)
// {
// var prevDatas = _agfixatitemRepository
// .GetEntities(w => w.SecondId == prevSecondAllot.Id && w.RowNumber.HasValue && w.RowNumber > -1 && w.Type == (int)TempColumnType.TableFixedColumns);
// if (prevDatas != null)
// {
// foreach (var row in prevDatas.GroupBy(w => w.RowNumber.Value))
// {
// var personnelNumber = row.FirstOrDefault(w => w.ItemName == "人员工号")?.ItemValue;
// if (string.IsNullOrEmpty(personnelNumber))
// continue;
// var existEmp = dicEmployees.FirstOrDefault(w => w.PersonnelNumber?.Trim() == personnelNumber?.Trim());
// if (existEmp != null)
// continue;
// bodysources.Add(new ag_bodysource
// {
// SecondId = second.Id,
// Department = existEmp.AccountingUnit,
// WorkNumber = existEmp.PersonnelNumber,
// Name = existEmp.DoctorName,
// JobTitle = existEmp.JobTitle,
// ReservedRatio = existEmp.ReservedRatio,
// Post = "否",
// });
// }
// }
// }
// else if (prevSecondAllot.Status == 9 || prevSecondAllot.Status == 10)
// {
// var prevDatas = _agbodysourceRepository.GetEntities(w => w.SecondId == prevSecondAllot.Id);
// if (prevDatas != null)
// {
// foreach (var pre in prevDatas)
// {
// var existEmp = dicEmployees.FirstOrDefault(w => w.PersonnelNumber?.Trim() == pre.WorkNumber?.Trim());
// if (existEmp != null)
// continue;
// bodysources.Add(new ag_bodysource
// {
// SecondId = second.Id,
// Department = existEmp.AccountingUnit,
// WorkNumber = existEmp.PersonnelNumber,
// Name = existEmp.DoctorName,
// JobTitle = existEmp.JobTitle,
// ReservedRatio = existEmp.ReservedRatio,
// Post = "否",
// });
// }
// }
// }
//}
//return bodysources;
List
<
string
>
numbers
=
new
List
<
string
>();
// 上次二次分配分三种情况,1.其他来源 2.单工作量 3.多工作量
var
prevSecondAllot
=
_secondAllotDetails
.
GetPreviousSecondAllot
(
allot
.
HospitalId
,
second
);
var
status
=
new
int
[]
{
(
int
)
SecondAllotStatus
.
WaitReview
,
(
int
)
SecondAllotStatus
.
PassAudit
};
if
(
prevSecondAllot
!=
null
&&
status
.
Contains
(
prevSecondAllot
.
Status
??
(
int
)
SecondAllotStatus
.
Uncommitted
))
{
if
(
prevSecondAllot
.
Status
==
6
)
{
var
prevDatas
=
_agothersourceRepository
.
GetEntities
(
w
=>
w
.
SecondId
==
prevSecondAllot
.
Id
);
numbers
=
prevDatas
?.
Where
(
pre
=>
string
.
IsNullOrEmpty
(
pre
.
WorkNumber
?.
Trim
()))
.
Select
(
pre
=>
pre
.
WorkNumber
?.
Trim
())
.
Distinct
().
ToList
()
??
new
List
<
string
>();
}
else
if
(
prevSecondAllot
.
Status
==
7
||
prevSecondAllot
.
Status
==
8
)
{
var
prevDatas
=
_agfixatitemRepository
.
GetEntities
(
w
=>
w
.
SecondId
==
prevSecondAllot
.
Id
&&
w
.
RowNumber
.
HasValue
&&
w
.
RowNumber
>
-
1
&&
w
.
Type
==
(
int
)
TempColumnType
.
TableFixedColumns
);
numbers
=
prevDatas
?.
GroupBy
(
w
=>
w
.
RowNumber
.
Value
)
.
Select
(
row
=>
row
.
FirstOrDefault
(
w
=>
w
.
ItemName
==
"人员工号"
)?.
ItemValue
)
.
Where
(
w
=>
string
.
IsNullOrEmpty
(
w
?.
Trim
()))
.
Distinct
().
ToList
()
??
new
List
<
string
>();
}
else
if
(
prevSecondAllot
.
Status
==
9
||
prevSecondAllot
.
Status
==
10
)
{
var
prevDatas
=
_agbodysourceRepository
.
GetEntities
(
w
=>
w
.
SecondId
==
prevSecondAllot
.
Id
);
numbers
=
prevDatas
?.
Where
(
pre
=>
string
.
IsNullOrEmpty
(
pre
.
WorkNumber
?.
Trim
()))
.
Select
(
pre
=>
pre
.
WorkNumber
?.
Trim
())
.
Distinct
().
ToList
()
??
new
List
<
string
>();
}
}
return
numbers
;
}
private
List
<
string
>
LoadEmployees_EmployeeDict
(
ag_secondallot
second
,
List
<
per_employee
>
dicEmployees
)
{
//if (dicEmployees == null)
// return new List<ag_bodysource>();
//var employees = dicEmployees
// .Where(w => w.UnitType == second.UnitType && w.AccountingUnit == second.Department)
// .Select(emp => new ag_bodysource
// {
// SecondId = second.Id,
// Department = emp.AccountingUnit,
// WorkNumber = emp.PersonnelNumber,
// Name = emp.DoctorName,
// JobTitle = emp.JobTitle,
// ReservedRatio = emp.ReservedRatio,
// Post = "否",
// }).ToList();
//return employees;
var
employees
=
dicEmployees
?.
Where
(
w
=>
w
.
UnitType
==
second
.
UnitType
&&
w
.
AccountingUnit
==
second
.
Department
)
.
Select
(
emp
=>
emp
.
PersonnelNumber
?.
Trim
())
.
Distinct
().
ToList
()
??
new
List
<
string
>();
return
employees
;
}
private
List
<
string
>
LoadEmployees_OfficeExcel
(
ag_secondallot
second
)
{
//List<ag_bodysource> bodysources = new List<ag_bodysource>();
//if (dicEmployees == null)
// return bodysources;
//var employees = _imemployeelogisticsRepository.GetEntities(w => w.AllotID == second.AllotId && w.AccountingUnit == second.Department);
//if (employees != null)
//{
// foreach (var emp in employees)
// {
// var existEmp = dicEmployees.FirstOrDefault(w => w.PersonnelNumber?.Trim() == emp.PersonnelNumber?.Trim());
// if (existEmp != null)
// continue;
// bodysources.Add(new ag_bodysource
// {
// SecondId = second.Id,
// Department = existEmp.AccountingUnit,
// WorkNumber = existEmp.PersonnelNumber,
// Name = existEmp.DoctorName,
// JobTitle = existEmp.JobTitle,
// ReservedRatio = existEmp.ReservedRatio,
// Post = "否",
// });
// }
//}
//return bodysources;
List
<
string
>
numbers
=
new
List
<
string
>();
var
employees
=
_imemployeelogisticsRepository
.
GetEntities
(
w
=>
w
.
AllotID
==
second
.
AllotId
&&
w
.
AccountingUnit
==
second
.
Department
);
if
(
employees
!=
null
)
numbers
=
employees
.
Select
(
w
=>
w
.
PersonnelNumber
).
ToList
();
return
numbers
;
}
private
List
<
string
>
LoadEmployees_Save
(
List
<
ag_bodysource
>
saveDatas
)
{
return
saveDatas
.
Select
(
w
=>
w
.
WorkNumber
).
ToList
();
}
}
#
region
动态生成列头信息
/// <summary>
/// <summary>
/// 动态生成列头信息
/// 动态生成列头信息
/// </summary>
/// </summary>
/// <param name="computeMode"></param>
/// <param name="computeMode"></param>
/// <param name="loads"></param>
/// <param name="loads"></param>
/// <returns></returns>
/// <returns></returns>
private
(
List
<
string
>
colHeaderCustoms
,
List
<
HandsonColumn
>
columnCustoms
)
GetCustomColumns
(
int
computeMode
,
List
<
TitleValue
<
string
,
decimal
?>>
loads
)
private
(
List
<
string
>
colHeaderCustoms
,
List
<
HandsonColumn
>
columnCustoms
)
GetCustomColumns
(
ComputeMode
computeMode
,
List
<
TitleValue
<
string
,
decimal
?>>
loads
)
{
{
var
colHeaderCustoms
=
new
List
<
string
>();
var
colHeaderCustoms
=
new
List
<
string
>();
var
columnCustoms
=
new
List
<
HandsonColumn
>();
var
columnCustoms
=
new
List
<
HandsonColumn
>();
// 工作量
// 工作量
if
(
computeMode
==
2
||
computeMode
==
3
)
if
(
computeMode
==
ComputeMode
.
Horizontal
||
computeMode
==
ComputeMode
.
Vertical
)
{
{
var
keys
=
loads
.
Where
(
w
=>
w
.
Title
.
StartsWith
(
"AssessmentScore_"
)).
Select
(
w
=>
w
.
Title
.
Replace
(
"AssessmentScore_"
,
""
)).
Distinct
();
var
keys
=
loads
.
Where
(
w
=>
w
.
Title
.
StartsWith
IgnoreCase
(
"AssessmentScore_"
)).
Select
(
w
=>
w
.
Title
.
Replace
(
"AssessmentScore_"
,
""
)).
Distinct
();
foreach
(
var
key
in
keys
)
foreach
(
var
key
in
keys
)
{
{
foreach
(
var
item
in
loads
.
Where
(
w
=>
w
.
Title
.
Equals
(
$"AssessmentScore_
{
key
}
"
)
||
w
.
Title
.
StartsWith
(
$"Workload_
{
key
}
_"
)))
if
(
loads
.
Any
(
w
=>
w
.
Title
.
StartsWithIgnoreCase
(
$"Workload_
{
key
}
_"
)))
{
foreach
(
var
item
in
loads
.
Where
(
w
=>
w
.
Title
.
EqualsIgnoreCase
(
$"AssessmentScore_
{
key
}
"
)
||
w
.
Title
.
StartsWithIgnoreCase
(
$"Workload_
{
key
}
_"
)))
{
{
colHeaderCustoms
.
Add
(
item
.
Value
);
colHeaderCustoms
.
Add
(
item
.
Value
);
columnCustoms
.
Add
(
new
HandsonColumn
(
item
.
Title
,
format
:
DataFormat
.
小数
));
columnCustoms
.
Add
(
new
HandsonColumn
(
item
.
Title
.
ToLower
(),
format
:
DataFormat
.
小数
));
}
}
}
}
}
}
}
// 单项奖励
// 单项奖励
foreach
(
var
awards
in
loads
.
Where
(
w
=>
w
.
Title
.
StartsWith
(
"SingleAwards_"
)))
foreach
(
var
awards
in
loads
.
Where
(
w
=>
w
.
Title
.
StartsWith
IgnoreCase
(
"SingleAwards_"
)))
{
{
colHeaderCustoms
.
Add
(
awards
.
Value
);
colHeaderCustoms
.
Add
(
awards
.
Value
);
columnCustoms
.
Add
(
new
HandsonColumn
(
awards
.
Title
,
format
:
DataFormat
.
小数
));
columnCustoms
.
Add
(
new
HandsonColumn
(
awards
.
Title
.
ToLower
()
,
format
:
DataFormat
.
小数
));
}
}
return
(
colHeaderCustoms
,
columnCustoms
);
return
(
colHeaderCustoms
,
columnCustoms
);
}
}
#
endregion
#
region
获取工作量及单项奖励
/// <summary>
/// <summary>
/// 获取工作量及单项奖励
/// 获取工作量及单项奖励
/// </summary>
/// </summary>
...
@@ -159,7 +657,7 @@ public HandsonTableBase Load(int secondId, int computeMode)
...
@@ -159,7 +657,7 @@ public HandsonTableBase Load(int secondId, int computeMode)
/// <param name="unitType"></param>
/// <param name="unitType"></param>
/// <param name="accountingUnit"></param>
/// <param name="accountingUnit"></param>
/// <returns></returns>
/// <returns></returns>
p
rivate
List
<
TitleValue
<
string
,
decimal
?>>
GetWorkLoads
(
int
hospitalId
,
string
unitType
,
string
accountingUnit
)
p
ublic
List
<
TitleValue
<
string
,
decimal
?>>
GetWorkLoads
(
int
hospitalId
,
string
unitType
,
string
accountingUnit
)
{
{
var
workloads
=
_agworkloadRepository
.
GetEntities
(
t
=>
t
.
HospitalId
==
hospitalId
&&
t
.
Department
==
accountingUnit
&&
t
.
UnitType
==
unitType
)
??
new
List
<
ag_workload
>();
var
workloads
=
_agworkloadRepository
.
GetEntities
(
t
=>
t
.
HospitalId
==
hospitalId
&&
t
.
Department
==
accountingUnit
&&
t
.
UnitType
==
unitType
)
??
new
List
<
ag_workload
>();
var
loads
=
workloads
var
loads
=
workloads
...
@@ -169,7 +667,9 @@ public HandsonTableBase Load(int secondId, int computeMode)
...
@@ -169,7 +667,9 @@ public HandsonTableBase Load(int secondId, int computeMode)
return
loads
;
return
loads
;
}
}
#
endregion
#
region
三种计算对应的格式
/// <summary>
/// <summary>
/// 格式生成,不计算,手动录入
/// 格式生成,不计算,手动录入
/// </summary>
/// </summary>
...
@@ -179,23 +679,22 @@ public HandsonTableBase Load(int secondId, int computeMode)
...
@@ -179,23 +679,22 @@ public HandsonTableBase Load(int secondId, int computeMode)
private
HandsonTableBase
ComputeMode_Format1
(
List
<
string
>
colHeaders
,
List
<
HandsonColumn
>
columns
)
private
HandsonTableBase
ComputeMode_Format1
(
List
<
string
>
colHeaders
,
List
<
HandsonColumn
>
columns
)
{
{
HandsonTableBase
handson
=
new
HandsonTableBase
();
HandsonTableBase
handson
=
new
HandsonTableBase
();
handson
.
ColHeaders
.
AddRange
(
new
string
[]
{
"工号"
,
"姓名"
,
"核算单元"
,
"主管"
,
"职称绩效"
,
"工作量绩效工资"
,
});
handson
.
ColHeaders
.
AddRange
(
new
string
[]
{
"工号"
,
"姓名"
,
/* "核算单元",*/
"主管"
,
"职称绩效"
,
"工作量绩效工资"
,
});
handson
.
Columns
.
AddRange
(
handson
.
Columns
.
AddRange
(
new
HandsonColumn
[]
new
HandsonColumn
[]
{
{
new
HandsonColumn
(
"WorkNumber"
),
new
HandsonColumn
(
nameof
(
ag_bodysource
.
WorkNumber
).
ToLower
()),
new
HandsonColumn
(
"Name"
),
new
HandsonColumn
(
nameof
(
ag_bodysource
.
Name
).
ToLower
()),
new
HandsonColumn
(
"Department"
),
//new HandsonColumn(nameof(ag_bodysource.Department).ToLower()),
new
HandsonColumn
(
"Post"
),
new
HandsonColumn
(
nameof
(
ag_bodysource
.
TitlePerformance
).
ToLower
(),
format
:
DataFormat
.
小数
),
new
HandsonColumn
(
"TitlePerformance"
,
format
:
DataFormat
.
小数
),
new
HandsonColumn
(
nameof
(
ag_bodysource
.
WorkPerformance
).
ToLower
(),
format
:
DataFormat
.
小数
),
new
HandsonColumn
(
"WorkPerformance"
,
format
:
DataFormat
.
小数
),
});
});
handson
.
ColHeaders
.
AddRange
(
colHeaders
);
handson
.
ColHeaders
.
AddRange
(
colHeaders
);
handson
.
Columns
.
AddRange
(
columns
);
handson
.
Columns
.
AddRange
(
columns
);
handson
.
ColHeaders
.
AddRange
(
new
string
[]
{
"夜班绩效"
,
});
handson
.
ColHeaders
.
AddRange
(
new
string
[]
{
"夜班绩效"
,
});
handson
.
Columns
.
AddRange
(
new
HandsonColumn
[]
{
new
HandsonColumn
(
"NightWorkPerformance"
,
format
:
DataFormat
.
小数
),
});
handson
.
Columns
.
AddRange
(
new
HandsonColumn
[]
{
new
HandsonColumn
(
nameof
(
ag_bodysource
.
NightWorkPerformance
).
ToLower
()
,
format
:
DataFormat
.
小数
),
});
return
handson
;
return
handson
;
}
}
...
@@ -208,25 +707,25 @@ private HandsonTableBase ComputeMode_Format1(List<string> colHeaders, List<Hands
...
@@ -208,25 +707,25 @@ private HandsonTableBase ComputeMode_Format1(List<string> colHeaders, List<Hands
private
HandsonTableBase
ComputeMode_Format2
(
List
<
string
>
colHeaders
,
List
<
HandsonColumn
>
columns
)
private
HandsonTableBase
ComputeMode_Format2
(
List
<
string
>
colHeaders
,
List
<
HandsonColumn
>
columns
)
{
{
HandsonTableBase
handson
=
new
HandsonTableBase
();
HandsonTableBase
handson
=
new
HandsonTableBase
();
handson
.
ColHeaders
.
AddRange
(
new
string
[]
{
"工号"
,
"姓名"
,
"核算单元"
,
"主管"
,
"人员系数"
,
"出勤"
,
"职称"
,
"职称系数"
,
});
handson
.
ColHeaders
.
AddRange
(
new
string
[]
{
"工号"
,
"姓名"
,
/*"核算单元",*/
"主管"
,
"人员系数"
,
"出勤"
,
"职称"
,
"职称系数"
,
});
handson
.
Columns
.
AddRange
(
handson
.
Columns
.
AddRange
(
new
HandsonColumn
[]
new
HandsonColumn
[]
{
{
new
HandsonColumn
(
"WorkNumber"
),
new
HandsonColumn
(
nameof
(
ag_bodysource
.
WorkNumber
).
ToLower
()
),
new
HandsonColumn
(
"Name"
),
new
HandsonColumn
(
nameof
(
ag_bodysource
.
Name
).
ToLower
()
),
new
HandsonColumn
(
"Department"
),
//new HandsonColumn(nameof(ag_bodysource.Department).ToLower()
),
new
HandsonColumn
(
"Post"
)
,
new
HandsonColumn
(
nameof
(
ag_bodysource
.
Post
).
ToLower
()){
Type
=
"autocomplete"
,
Strict
=
true
,
Source
=
new
string
[]
{
"是"
,
"否"
}
}
,
new
HandsonColumn
(
"StaffCoefficient"
,
format
:
DataFormat
.
小数
),
new
HandsonColumn
(
nameof
(
ag_bodysource
.
StaffCoefficient
).
ToLower
()
,
format
:
DataFormat
.
小数
),
new
HandsonColumn
(
"ActualAttendance"
,
format
:
DataFormat
.
小数
),
new
HandsonColumn
(
nameof
(
ag_bodysource
.
ActualAttendance
).
ToLower
(),
format
:
DataFormat
.
小数
1
),
new
HandsonColumn
(
"JobTitle"
),
new
HandsonColumn
(
nameof
(
ag_bodysource
.
JobTitle
).
ToLower
()
),
new
HandsonColumn
(
"TitleCoefficient"
,
format
:
DataFormat
.
小数
),
new
HandsonColumn
(
nameof
(
ag_bodysource
.
TitleCoefficient
).
ToLower
()
,
format
:
DataFormat
.
小数
),
});
});
handson
.
ColHeaders
.
AddRange
(
colHeaders
);
handson
.
ColHeaders
.
AddRange
(
colHeaders
);
handson
.
Columns
.
AddRange
(
columns
);
handson
.
Columns
.
AddRange
(
columns
);
handson
.
ColHeaders
.
AddRange
(
new
string
[]
{
"夜班绩效"
,
});
handson
.
ColHeaders
.
AddRange
(
new
string
[]
{
"夜班绩效"
,
});
handson
.
Columns
.
AddRange
(
new
HandsonColumn
[]
{
new
HandsonColumn
(
"NightWorkPerformance"
,
format
:
DataFormat
.
小数
),
});
handson
.
Columns
.
AddRange
(
new
HandsonColumn
[]
{
new
HandsonColumn
(
nameof
(
ag_bodysource
.
NightWorkPerformance
).
ToLower
()
,
format
:
DataFormat
.
小数
),
});
return
handson
;
return
handson
;
}
}
...
@@ -244,9 +743,8 @@ private HandsonTableBase ComputeMode_Format3(List<string> colHeaders, List<Hands
...
@@ -244,9 +743,8 @@ private HandsonTableBase ComputeMode_Format3(List<string> colHeaders, List<Hands
var
fs
=
handson
.
Columns
.
Select
(
col
=>
var
fs
=
handson
.
Columns
.
Select
(
col
=>
{
{
var
f
=
loads
.
FirstOrDefault
(
w
=>
w
.
Title
.
StartsWith
(
$"Workload_"
)
&&
w
.
State
.
HasValue
&&
w
.
State
!=
0
&&
w
.
Title
==
col
.
Data
);
var
f
=
loads
.
FirstOrDefault
(
w
=>
w
.
Title
.
StartsWithIgnoreCase
(
$"Workload_"
)
&&
w
.
Title
.
EqualsIgnoreCase
(
col
.
Data
));
return
f
==
null
?
""
:
(
f
.
State
??
0
).
ToString
(
"F0"
);
return
f
==
null
||
!
f
.
State
.
HasValue
?
""
:
f
.
State
.
Value
.
ToString
(
"F0"
);
});
});
handson
.
NestedHeadersArray
.
Add
(
handson
.
ColHeaders
);
handson
.
NestedHeadersArray
.
Add
(
handson
.
ColHeaders
);
...
@@ -254,5 +752,556 @@ private HandsonTableBase ComputeMode_Format3(List<string> colHeaders, List<Hands
...
@@ -254,5 +752,556 @@ private HandsonTableBase ComputeMode_Format3(List<string> colHeaders, List<Hands
return
handson
;
return
handson
;
}
}
#
endregion
#
endregion
#
region
补充医院其他绩效
/// <summary>
/// 补充医院其他绩效
/// </summary>
/// <param name="second"></param>
/// <param name="rows"></param>
public
void
SupplementOtherPerfor
(
ag_secondallot
second
,
List
<
Dictionary
<
string
,
object
>>
rows
)
{
if
(
rows
==
null
||
rows
.
Count
==
0
)
return
;
var
perapramounts
=
_perapramountRepository
.
GetFullAmount
(
t
=>
t
.
AllotId
==
second
.
AllotId
&&
t
.
Status
==
3
);
if
(
perapramounts
==
null
||
!
perapramounts
.
Any
())
return
;
foreach
(
var
row
in
rows
)
{
var
personnelNumber
=
row
.
GetValue
(
nameof
(
ag_bodysource
.
WorkNumber
),
""
);
var
amounts
=
perapramounts
.
Where
(
w
=>
w
.
PersonnelNumber
?.
Trim
()
==
personnelNumber
?.
Trim
());
row
.
AddOrUpdate
(
nameof
(
ag_bodysource
.
OtherPerformance
),
amounts
.
Sum
(
w
=>
w
.
Amount
??
0
));
}
// 补充字典中该科室不存在,但有其它绩效的人员信息
var
groupDatas
=
perapramounts
.
Where
(
t
=>
t
.
UnitType
==
second
.
UnitType
&&
t
.
AccountingUnit
==
second
.
Department
)
.
GroupBy
(
w
=>
new
{
PersonnelNumber
=
w
.
PersonnelNumber
,
DoctorName
=
w
.
DoctorName
,
AccountingUnit
=
w
.
AccountingUnit
,
UnitType
=
w
.
UnitType
,
});
foreach
(
var
item
in
groupDatas
)
{
if
(!
rows
.
Any
(
row
=>
row
.
GetValue
(
nameof
(
ag_bodysource
.
WorkNumber
),
""
)
==
item
.
Key
.
PersonnelNumber
))
{
rows
.
Add
(
new
Dictionary
<
string
,
object
>
{
{
nameof
(
ag_bodysource
.
SecondId
),
second
.
Id
},
{
nameof
(
ag_bodysource
.
WorkNumber
),
item
.
Key
.
PersonnelNumber
},
{
nameof
(
ag_bodysource
.
Name
),
item
.
Key
.
DoctorName
},
{
nameof
(
ag_bodysource
.
Department
),
item
.
Key
.
AccountingUnit
},
{
nameof
(
ag_bodysource
.
OtherPerformance
),
item
.
Sum
(
w
=>
w
.
Amount
)},
});
}
}
}
#
endregion
#
region
重算顶部医院其他绩效
/// <summary>
/// 计算顶部相关总和>>医院其他绩效(比较特殊,仅用作展示,所以需要重新计算一次)
/// </summary>
/// <param name="head"></param>
/// <param name="rows"></param>
public
void
OverviewCalculate_OtherPerformance
(
Dictionary
<
string
,
object
>
head
,
List
<
Dictionary
<
string
,
object
>>
rows
)
{
//医院其他绩效总和
var
otherPerformance
=
rows
.
Sum
(
row
=>
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
OtherPerformance
)));
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
HosOtherPerformance
),
otherPerformance
);
}
#
endregion
#
region
计算
/// <summary>
/// 分配结果结果计算
/// </summary>
/// <param name="computeMode"></param>
/// <param name="head"></param>
/// <param name="rows"></param>
/// <param name="loads"></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
)
{
var
specialPostName
=
new
string
[]
{
"科主任/护士长"
,
"主任"
,
"主管"
,
"是"
,
};
if
(
computeMode
==
ComputeMode
.
NotCalculate
)
{
// 清空无效数据
clearPerformanceWorkload
(
rows
,
workloadGroups
);
// 行内可分配绩效
distPerformanceCalculate
(
head
,
rows
,
workloadGroups
);
// 行内实发绩效
realAmountCalculate
(
head
,
rows
,
specialPostName
);
}
else
if
(
computeMode
==
ComputeMode
.
Horizontal
||
computeMode
==
ComputeMode
.
Vertical
)
{
// 行内计算单项奖励
deptRewardCalculate
(
rows
);
// 计算顶部相关总和
overviewCalculate
(
head
,
rows
);
// 计算顶部工作量
topWorkloadCalculate
(
head
,
workloadGroups
);
// 计算顶部年资系数
topSeniorityCalculate
(
head
);
// 行内主任基础绩效
basisPerformanceCalculate
(
head
,
rows
,
specialPostName
);
// 行内职称绩效计算
titleCoefficientCalculate
(
head
,
rows
,
specialPostName
);
// 行内工作量分组计算
workloadCalculate
(
head
,
rows
,
computeMode
,
loads
,
workloadGroups
,
specialPostName
);
// 行内可分配绩效
distPerformanceCalculate
(
head
,
rows
,
workloadGroups
);
// 差额从主任或第一个人身上扣除
balanceTotalDistPerformance
(
head
,
rows
,
specialPostName
);
// 行内实发绩效
realAmountCalculate
(
head
,
rows
,
specialPostName
);
}
}
/// <summary>
/// ComputeMode.NotCalculate 不计算时,清空无效数据
/// </summary>
/// <param name="rows"></param>
/// <param name="workloadGroups"></param>
private
void
clearPerformanceWorkload
(
List
<
Dictionary
<
string
,
object
>>
rows
,
List
<
SecondWorkLoadDto
>
workloadGroups
)
{
foreach
(
var
row
in
rows
)
{
foreach
(
var
workload
in
workloadGroups
)
{
row
.
Remove
(
workload
.
WorkloadScore
);
row
.
Remove
(
workload
.
AssessmentScore
);
row
.
Remove
(
workload
.
WorkPerformance
);
foreach
(
var
item
in
workload
.
Items
)
{
row
.
Remove
(
item
);
}
}
}
}
/// <summary>
/// 行内计算单项奖励
/// </summary>
/// <param name="rows"></param>
private
void
deptRewardCalculate
(
List
<
Dictionary
<
string
,
object
>>
rows
)
{
foreach
(
var
row
in
rows
)
{
decimal
total_deptReward
=
row
.
Where
(
w
=>
w
.
Key
.
StartsWithIgnoreCase
(
"SingleAwards_"
)).
Sum
(
r
=>
GetDecimal2
(
row
,
r
.
Key
));
row
.
AddOrUpdate
(
nameof
(
ag_bodysource
.
DeptReward
),
total_deptReward
);
}
}
/// <summary>
/// 计算顶部工作量
/// </summary>
/// <param name="head"></param>
/// <param name="workloadGroups"></param>
private
void
topWorkloadCalculate
(
Dictionary
<
string
,
object
>
head
,
List
<
SecondWorkLoadDto
>
workloadGroups
)
{
foreach
(
var
workload
in
workloadGroups
)
{
var
amount
=
GetDecimal2
(
head
,
nameof
(
ag_headsource
.
TheTotalAllocationOfPerformanceResults
))
*
GetDecimal2
(
head
,
$"Workload_Ratio_
{
workload
.
Name
}
"
);
head
.
AddOrUpdate
(
$"Workload_Amount_
{
workload
.
Name
}
"
,
amount
);
}
}
/// <summary>
/// 计算顶部年资系数
/// </summary>
/// <param name="head"></param>
private
void
topSeniorityCalculate
(
Dictionary
<
string
,
object
>
head
)
{
var
amount
=
GetDecimal2
(
head
,
nameof
(
ag_headsource
.
SeniorityTitlesAccountedPerformance
))
*
GetDecimal2
(
head
,
nameof
(
ag_headsource
.
TheTotalAllocationOfPerformanceResults
));
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
SeniorityTitlesPerformance
),
amount
);
}
/// <summary>
/// 计算顶部相关总和
/// </summary>
/// <param name="head"></param>
/// <param name="rows"></param>
private
void
overviewCalculate
(
Dictionary
<
string
,
object
>
head
,
List
<
Dictionary
<
string
,
object
>>
rows
)
{
// 可分配绩效(顶栏) = 科室总绩效 - 夜班绩效(顶栏)
var
totalPerformance
=
GetDecimal2
(
head
,
nameof
(
ag_headsource
.
TotalDistPerformance
))
-
GetDecimal2
(
head
,
nameof
(
ag_headsource
.
NightShiftWorkPerforTotal
));
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
TotalPerformance
),
totalPerformance
);
//夜班工作量绩效总和
var
nightShiftWorkPerforTotal
=
rows
.
Sum
(
row
=>
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
NightWorkPerformance
)));
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
NightShiftWorkPerforTotal
),
nightShiftWorkPerforTotal
);
////医院其他绩效总和
//var otherPerformance = rows.Sum(row => GetDecimal2(row, nameof(ag_bodysource.OtherPerformance)));
//head.AddOrUpdate(nameof(ag_headsource.HosOtherPerformance), otherPerformance);
//科室核算人数 = 人员系数 * 实际出勤
var
daysFullAttendance
=
GetDecimal2
(
head
,
nameof
(
ag_headsource
.
DaysFullAttendance
));
var
theNumberOfAccountingDepartment
=
daysFullAttendance
==
0
?
0
m
:
rows
.
Sum
(
row
=>
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
StaffCoefficient
))
*
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
ActualAttendance
))
/
daysFullAttendance
);
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
TheNumberOfAccountingDepartment
),
0
m
);
// 科室人均 = 可分配绩效 / 科室核算人数
var
departmentsPerCapita
=
theNumberOfAccountingDepartment
==
0
?
0
m
:
GetDecimal2
(
totalPerformance
/
theNumberOfAccountingDepartment
);
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
DepartmentsPerCapita
),
departmentsPerCapita
);
// 科室单项奖励
var
totalDeptReward
=
rows
.
Sum
(
row
=>
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
DeptReward
)));
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
TotalDeptReward
),
totalDeptReward
);
// 主任基础绩效(顶部) = 行内主任基础绩效总和
var
directorBasisPerformance
=
rows
.
Sum
(
row
=>
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
BasisPerformance
)));
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
DirectorBasisPerformance
),
directorBasisPerformance
);
// 业绩分配绩效总额 = 可分配绩效 - 科主任或护士长基础绩效 - 科室单项奖励
var
theTotalAllocationOfPerformanceResults
=
totalPerformance
-
directorBasisPerformance
-
totalDeptReward
;
head
.
AddOrUpdate
(
nameof
(
ag_headsource
.
TheTotalAllocationOfPerformanceResults
),
theTotalAllocationOfPerformanceResults
);
}
/// <summary>
/// 行内主任基础绩效
/// </summary>
/// <param name="head"></param>
/// <param name="rows"></param>
/// <param name="specialPostName"></param>
private
void
basisPerformanceCalculate
(
Dictionary
<
string
,
object
>
head
,
List
<
Dictionary
<
string
,
object
>>
rows
,
string
[]
specialPostName
)
{
foreach
(
var
row
in
rows
)
{
// 除 科主任/护士长 以外人员没有 主任基础绩效
// 当前行主任基础绩效 = 科室人均 * 当前行人员系数 * 当前行人员出勤/满勤天数
var
post
=
row
.
GetValue
(
nameof
(
ag_bodysource
.
Post
),
""
);
if
(
specialPostName
.
Contains
(
post
))
{
var
daysFullAttendance
=
GetDecimal2
(
head
,
nameof
(
ag_headsource
.
DaysFullAttendance
));
var
departmentsPerCapita
=
GetDecimal2
(
head
,
nameof
(
ag_headsource
.
DepartmentsPerCapita
));
var
staffCoefficient
=
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
StaffCoefficient
));
var
actualAttendance
=
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
ActualAttendance
));
var
basisPerformance
=
daysFullAttendance
==
0
?
0
:
departmentsPerCapita
*
staffCoefficient
*
actualAttendance
/
daysFullAttendance
;
row
.
AddOrUpdate
(
nameof
(
ag_bodysource
.
BasisPerformance
),
basisPerformance
);
}
else
{
row
.
AddOrUpdate
(
nameof
(
ag_bodysource
.
BasisPerformance
),
0
m
);
}
}
}
/// <summary>
/// 行内职称绩效计算
/// </summary>
/// <param name="head"></param>
/// <param name="rows"></param>
/// <param name="specialPostName"></param>
private
void
titleCoefficientCalculate
(
Dictionary
<
string
,
object
>
head
,
List
<
Dictionary
<
string
,
object
>>
rows
,
string
[]
specialPostName
)
{
var
total_titleCoefficient
=
0
m
;
foreach
(
var
row
in
rows
)
{
var
post
=
row
.
GetValue
(
nameof
(
ag_bodysource
.
Post
),
""
);
if
(!
specialPostName
.
Contains
(
post
))
total_titleCoefficient
+=
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
ActualAttendance
))
*
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
TitleCoefficient
));
}
var
seniorityTitlesPerformance
=
GetDecimal2
(
head
,
nameof
(
ag_headsource
.
SeniorityTitlesPerformance
));
foreach
(
var
row
in
rows
)
{
var
post
=
row
.
GetValue
(
nameof
(
ag_bodysource
.
Post
),
""
);
// 科主任/护士长 不参与职称绩效考核
if
(
specialPostName
.
Contains
(
post
))
row
.
AddOrUpdate
(
nameof
(
ag_bodysource
.
TitleCoefficient
),
0
m
);
//个人职称绩效 = ( 当前行实际出勤 * 当前行职称系数 ) / 职称系数总和* 年资职称绩效总和
var
titlePerformance
=
total_titleCoefficient
==
0
?
0
:
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
ActualAttendance
))
*
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
TitleCoefficient
))
/
total_titleCoefficient
*
seniorityTitlesPerformance
;
row
.
AddOrUpdate
(
nameof
(
ag_bodysource
.
TitlePerformance
),
GetDecimal2
(
titlePerformance
));
}
}
/// <summary>
/// 行内工作量分组计算
/// </summary>
/// <param name="head"></param>
/// <param name="rows"></param>
/// <param name="computeMode"></param>
/// <param name="loads"></param>
/// <param name="workloadGroups"></param>
/// <param name="specialPostName"></param>
private
void
workloadCalculate
(
Dictionary
<
string
,
object
>
head
,
List
<
Dictionary
<
string
,
object
>>
rows
,
ComputeMode
computeMode
,
List
<
TitleValue
<
string
,
decimal
?>>
loads
,
List
<
SecondWorkLoadDto
>
workloadGroups
,
string
[]
specialPostName
)
{
// 计算方式:1 不计算 2 横向计算 3 纵向计算
foreach
(
var
row
in
rows
)
{
foreach
(
var
gp
in
workloadGroups
)
{
var
workload_score
=
0
m
;
// 计算方式:1 不计算 2 横向计算 3 纵向计算
switch
(
computeMode
)
{
case
ComputeMode
.
Horizontal
:
workload_score
=
ComputeMode_2
(
row
,
gp
,
specialPostName
);
break
;
case
ComputeMode
.
Vertical
:
workload_score
=
ComputeMode_3
(
row
,
loads
,
gp
,
specialPostName
);
break
;
}
// 工作量得分
row
.
AddOrUpdate
(
gp
.
WorkloadScore
,
GetDecimal2
(
workload_score
));
}
}
// 工作量每分价格计算
foreach
(
var
gp
in
workloadGroups
)
{
// 汇总行内工作量总得分
var
total_score
=
rows
.
Sum
(
row
=>
GetDecimal2
(
row
,
gp
.
WorkloadScore
)
*
GetDecimal2
(
row
,
gp
.
AssessmentScore
));
// 计算每分价格
gp
.
Unit_Price
=
total_score
==
0
?
0
:
head
.
GetValue
(
$"Workload_Amount_
{
gp
.
Name
}
"
,
0
m
)
/
total_score
;
}
// 行内工作量绩效计算
foreach
(
var
row
in
rows
)
{
var
workPerformance
=
0
m
;
var
post
=
row
.
GetValue
(
nameof
(
ag_bodysource
.
Post
),
""
);
foreach
(
var
gp
in
workloadGroups
)
{
// 科主任/护士长 不参与工作量考核
if
(
specialPostName
.
Contains
(
post
))
{
row
.
AddOrUpdate
(
gp
.
WorkloadScore
,
0
m
);
row
.
AddOrUpdate
(
gp
.
AssessmentScore
,
0
m
);
}
// 工作量绩效 = 工作量得分 * 每分价格 * 考核得分
var
workload_fee
=
GetDecimal2
(
row
.
GetValue
(
gp
.
WorkloadScore
,
0
m
)
*
gp
.
Unit_Price
*
row
.
GetValue
(
gp
.
AssessmentScore
,
0
m
));
row
.
AddOrUpdate
(
gp
.
WorkPerformance
,
workload_fee
);
workPerformance
+=
workload_fee
;
}
// 行内工作量汇总到一起
row
.
AddOrUpdate
(
nameof
(
ag_bodysource
.
WorkPerformance
),
workPerformance
);
}
}
#
region
行内工作量
辅助计算
/// <summary>
/// 获取系数
/// </summary>
/// <param name="workloads"></param>
/// <param name="item"></param>
/// <returns></returns>
decimal
getFactorValue
(
List
<
TitleValue
<
string
,
decimal
?>>
workloads
,
string
item
)
=>
workloads
.
FirstOrDefault
((
w
)
=>
w
.
Title
==
item
)?.
State
??
0
m
;
/// <summary>
/// 3 纵向计算
/// </summary>
/// <param name="row"></param>
/// <param name="loads"></param>
/// <param name="gp"></param>
/// <param name="specialPostName"></param>
/// <returns></returns>
decimal
ComputeMode_3
(
Dictionary
<
string
,
object
>
row
,
List
<
TitleValue
<
string
,
decimal
?>>
loads
,
SecondWorkLoadDto
gp
,
string
[]
specialPostName
)
{
var
post
=
row
.
GetValue
(
nameof
(
ag_bodysource
.
Post
),
""
);
var
workload_score
=
gp
.
Items
.
Sum
((
item
)
=>
{
// 科主任/护士长 不参与工作量考核
if
(
specialPostName
.
Contains
(
post
))
row
.
AddOrUpdate
(
item
,
0
);
return
GetDecimal2
(
row
.
GetValue
(
item
,
0
m
)
*
getFactorValue
(
loads
,
item
));
});
return
workload_score
;
}
/// <summary>
/// 2 横向计算
/// </summary>
/// <param name="row"></param>
/// <param name="gp"></param>
/// <param name="specialPostName"></param>
/// <returns></returns>
decimal
ComputeMode_2
(
Dictionary
<
string
,
object
>
row
,
SecondWorkLoadDto
gp
,
string
[]
specialPostName
)
{
var
post
=
row
.
GetValue
(
nameof
(
ag_bodysource
.
Post
),
""
);
var
workload_score
=
0
m
;
if
(
gp
.
Items
.
Count
%
2
==
0
)
{
for
(
int
i
=
0
;
i
<
gp
.
Items
.
Count
/
2
;
i
=
i
+
2
)
{
// 科主任/护士长 不参与工作量考核
if
(
specialPostName
.
Contains
(
post
))
{
row
.
AddOrUpdate
(
gp
.
Items
[
i
],
0
m
);
row
.
AddOrUpdate
(
gp
.
Items
[
i
+
1
],
0
m
);
}
var
amount
=
row
.
GetValue
(
gp
.
Items
[
i
],
0
m
)
*
row
.
GetValue
(
gp
.
Items
[
i
+
1
],
0
m
);
workload_score
+=
GetDecimal2
(
amount
);
}
}
return
workload_score
;
}
#
endregion
/// <summary>
/// 行内可分配绩效
/// </summary>
/// <param name="head"></param>
/// <param name="rows"></param>
/// <param name="workloadGroups"></param>
private
void
distPerformanceCalculate
(
Dictionary
<
string
,
object
>
head
,
List
<
Dictionary
<
string
,
object
>>
rows
,
List
<
SecondWorkLoadDto
>
workloadGroups
)
{
foreach
(
var
row
in
rows
)
{
var
workPerformance
=
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
WorkPerformance
));
var
titlePerformance
=
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
TitlePerformance
));
var
deptReward
=
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
DeptReward
));
var
basisPerformance
=
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
BasisPerformance
));
// 可分配绩效 = 当前行职称绩效 + 工作量绩效工资 + 当前行单项奖励 + 当前行主任基础绩效 (科主任护士长)
var
distPerformance
=
titlePerformance
+
workPerformance
+
deptReward
+
basisPerformance
;
row
.
AddOrUpdate
(
nameof
(
ag_bodysource
.
DistPerformance
),
distPerformance
);
}
}
/// <summary>
/// 差额从主任或第一个人身上扣除(小于等于1元)
/// </summary>
/// <param name="head"></param>
/// <param name="rows"></param>
/// <param name="specialPostName"></param>
private
void
balanceTotalDistPerformance
(
Dictionary
<
string
,
object
>
head
,
List
<
Dictionary
<
string
,
object
>>
rows
,
string
[]
specialPostName
)
{
var
totalPerformance
=
GetDecimal2
(
head
,
nameof
(
ag_headsource
.
TotalPerformance
));
var
total_distPerformance
=
rows
.
Sum
(
row
=>
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
DistPerformance
)));
var
difference
=
total_distPerformance
-
totalPerformance
;
if
(
Math
.
Abs
(
difference
)
<=
1
)
{
var
atRow
=
rows
.
Where
(
row
=>
specialPostName
.
Contains
(
row
.
GetValue
(
nameof
(
ag_bodysource
.
Post
),
""
)));
if
(
atRow
==
null
||
atRow
.
Count
()
==
0
)
atRow
=
rows
;
if
(
atRow
!=
null
&&
atRow
.
Count
()
>
0
)
{
var
distPerformance
=
GetDecimal2
(
atRow
.
ElementAt
(
0
),
nameof
(
ag_bodysource
.
DistPerformance
));
atRow
.
ElementAt
(
0
).
AddOrUpdate
(
nameof
(
ag_bodysource
.
DistPerformance
),
distPerformance
-
difference
);
}
}
}
/// <summary>
/// 行内实发绩效
/// </summary>
/// <param name="head"></param>
/// <param name="rows"></param>
/// <param name="specialPostName"></param>
private
void
realAmountCalculate
(
Dictionary
<
string
,
object
>
head
,
List
<
Dictionary
<
string
,
object
>>
rows
,
string
[]
specialPostName
)
{
foreach
(
var
row
in
rows
)
{
// 总绩效 = 夜班工作量绩效 + 医院其他绩效
var
row_ShifaAmountOfPerformancePay
=
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
NightWorkPerformance
))
+
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
OtherPerformance
));
// ReservedAmount 年度考核发放金额 DistPerformance 可分配绩效
var
reservedAmount
=
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
DistPerformance
))
*
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
ReservedRatio
));
row
.
AddOrUpdate
(
nameof
(
ag_bodysource
.
ReservedAmount
),
reservedAmount
);
var
realAmount
=
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
DistPerformance
))
-
GetDecimal2
(
row
,
nameof
(
ag_bodysource
.
ReservedAmount
))
+
row_ShifaAmountOfPerformancePay
;
row
.
AddOrUpdate
(
nameof
(
ag_bodysource
.
RealAmount
),
realAmount
);
}
}
#
region
四射五入
辅助方式
/// <summary>
/// 从键值对中获取decimal,默认:0,保留2位小数
/// </summary>
/// <param name="pairs"></param>
/// <param name="key"></param>
/// <returns></returns>
private
decimal
GetDecimal2
(
Dictionary
<
string
,
object
>
pairs
,
string
key
)
=>
GetDecimal2
(
pairs
.
GetValue
(
key
,
0
m
));
/// <summary>
/// decimal?类型转换decimal 默认:0,保留2位小数
/// </summary>
/// <param name="pairs"></param>
/// <param name="key"></param>
/// <returns></returns>
private
decimal
GetDecimal2
(
decimal
?
value
)
=>
value
.
HasValue
?
Math
.
Round
(
value
.
Value
,
2
,
MidpointRounding
.
AwayFromZero
)
:
0
m
;
#
endregion
#
endregion
#
region
获取行内工作量分组数
/// <summary>
/// 获取行内工作量分组数
/// </summary>
/// <param name="loads"></param>
/// <returns></returns>
public
List
<
SecondWorkLoadDto
>
GetTopWorkloadBodyGroups
(
List
<
TitleValue
<
string
,
decimal
?>>
loads
)
{
List
<
SecondWorkLoadDto
>
result
=
new
List
<
SecondWorkLoadDto
>();
if
(
loads
!=
null
)
{
var
keys
=
loads
.
Where
(
w
=>
w
.
Title
.
StartsWithIgnoreCase
(
"AssessmentScore_"
))
.
Select
(
w
=>
w
.
Title
.
Replace
(
"AssessmentScore_"
,
""
))
.
Distinct
();
foreach
(
var
key
in
keys
)
{
SecondWorkLoadDto
dto
=
new
SecondWorkLoadDto
(
key
);
foreach
(
var
item
in
loads
.
Where
(
w
=>
w
.
Title
.
StartsWithIgnoreCase
(
$"Workload_
{
key
}
_"
)))
{
dto
.
AddItem
(
item
.
Title
);
}
result
.
Add
(
dto
);
}
}
return
result
;
}
#
endregion
#
region
检查工号和姓名是否匹配
/// <summary>
/// 检查工号和姓名是否匹配
/// </summary>
/// <param name="second"></param>
/// <param name="body"></param>
/// <returns></returns>
public
List
<
SecondComputeCheckResultDto
>
CheckData
(
ag_secondallot
second
,
List
<
Dictionary
<
string
,
object
>>
body
)
{
if
(
body
==
null
||
body
.
Count
==
0
)
throw
new
PerformanceException
(
"分配人员信息不存在!"
);
List
<
SecondComputeCheckResultDto
>
result
=
new
List
<
SecondComputeCheckResultDto
>();
var
employees
=
_peremployeeRepository
.
GetEntities
(
w
=>
w
.
AllotId
==
second
.
AllotId
)
.
Select
(
w
=>
new
{
w
.
PersonnelNumber
,
w
.
DoctorName
,
w
.
AccountingUnit
,
w
.
UnitType
,
w
.
ReservedRatio
});
for
(
int
i
=
0
;
i
<
body
.
Count
;
i
++)
{
var
item
=
body
[
i
];
if
(
item
.
Where
(
w
=>
w
.
Value
!=
null
&&
!
string
.
IsNullOrEmpty
(
w
.
Value
.
ToString
())).
Count
()
>
0
)
{
var
number
=
item
.
GetValue
(
nameof
(
ag_bodysource
.
WorkNumber
),
""
);
var
name
=
item
.
GetValue
(
nameof
(
ag_bodysource
.
Name
),
""
);
if
(
string
.
IsNullOrEmpty
(
number
)
||
string
.
IsNullOrEmpty
(
name
))
{
item
.
AddOrUpdate
(
nameof
(
ResponseType
),
ResponseType
.
Warning
);
result
.
Add
(
new
SecondComputeCheckResultDto
(
nameof
(
ResponseType
.
Warning
),
number
,
name
,
$"第
{(
i
+
1
)}
行,工号或姓名无效;计算式忽略。"
));
}
var
emp
=
employees
.
FirstOrDefault
(
w
=>
w
.
PersonnelNumber
==
number
&&
w
.
DoctorName
==
name
);
if
(
emp
==
null
)
{
item
.
AddOrUpdate
(
nameof
(
ResponseType
),
ResponseType
.
Error
);
result
.
Add
(
new
SecondComputeCheckResultDto
(
nameof
(
ResponseType
.
Error
),
number
,
name
,
$"第
{(
i
+
1
)}
行,工号和姓名在字典中不存在,请修复。"
));
}
else
{
item
.
AddOrUpdate
(
nameof
(
ResponseType
),
ResponseType
.
OK
);
item
.
AddOrUpdate
(
nameof
(
ag_bodysource
.
Department
),
emp
.
AccountingUnit
);
item
.
AddOrUpdate
(
nameof
(
ag_bodysource
.
ReservedRatio
),
emp
.
ReservedRatio
);
}
}
}
return
result
;
}
#
endregion
}
}
}
}
performance/Performance.Services/SecondAllot/SecondAllotDetails.cs
View file @
65b03bc5
...
@@ -923,7 +923,7 @@ private void SupplementSecondDetail(ag_secondallot second, List<per_employee> em
...
@@ -923,7 +923,7 @@ private void SupplementSecondDetail(ag_secondallot second, List<per_employee> em
/// <param name="hospitalId"></param>
/// <param name="hospitalId"></param>
/// <param name="secondAllot"></param>
/// <param name="secondAllot"></param>
/// <returns></returns>
/// <returns></returns>
p
rivate
ag_secondallot
GetPreviousSecondAllot
(
int
hospitalId
,
ag_secondallot
secondAllot
)
p
ublic
ag_secondallot
GetPreviousSecondAllot
(
int
hospitalId
,
ag_secondallot
secondAllot
)
{
{
// 历史删除绩效时,未删除对应的二次绩效记录
// 历史删除绩效时,未删除对应的二次绩效记录
var
allotList
=
perallotRepository
.
GetEntities
(
w
=>
w
.
HospitalId
==
hospitalId
)?.
OrderBy
(
s
=>
s
.
Year
).
ThenBy
(
s
=>
s
.
Month
).
ToList
();
var
allotList
=
perallotRepository
.
GetEntities
(
w
=>
w
.
HospitalId
==
hospitalId
)?.
OrderBy
(
s
=>
s
.
Year
).
ThenBy
(
s
=>
s
.
Month
).
ToList
();
...
...
performance/Performance.Services/SecondAllotService.cs
View file @
65b03bc5
...
@@ -1605,7 +1605,7 @@ bool VerifySubmissioAmount(decimal? submitDataAmount, decimal? realGiveFee)
...
@@ -1605,7 +1605,7 @@ bool VerifySubmissioAmount(decimal? submitDataAmount, decimal? realGiveFee)
if
(!
VerifySubmissioAmount
(
total
,
second
.
RealGiveFee
))
if
(!
VerifySubmissioAmount
(
total
,
second
.
RealGiveFee
))
throw
new
PerformanceException
(
$"总金额与考核后金额不一致!可分配金额:
{
second
.
RealGiveFee
}
,提交金额:
{
total
}
"
);
throw
new
PerformanceException
(
$"总金额与考核后金额不一致!可分配金额:
{
second
.
RealGiveFee
}
,提交金额:
{
total
}
"
);
}
}
else
if
(
new
int
[]
{
9
,
10
}.
Contains
(
temp
.
UseTempId
.
Value
))
else
/*if (new int[] { 9, 10 }.Contains(temp.UseTempId.Value))*/
{
{
var
data
=
agbodysourceRepository
.
GetEntities
(
t
=>
t
.
SecondId
==
second
.
Id
);
var
data
=
agbodysourceRepository
.
GetEntities
(
t
=>
t
.
SecondId
==
second
.
Id
);
if
(
data
==
null
||
!
data
.
Any
())
if
(
data
==
null
||
!
data
.
Any
())
...
@@ -1803,7 +1803,7 @@ public bool NursingDeptAudit(int userId, SecondAuditRequest request)
...
@@ -1803,7 +1803,7 @@ public bool NursingDeptAudit(int userId, SecondAuditRequest request)
/// </summary>
/// </summary>
/// <param name="secondId">二次绩效Id</param>
/// <param name="secondId">二次绩效Id</param>
/// <returns></returns>
/// <returns></returns>
public
ag_secondallot
GetSecond
a
llot
(
int
secondId
)
public
ag_secondallot
GetSecond
A
llot
(
int
secondId
)
{
{
return
agsecondallotRepository
.
GetEntity
(
t
=>
t
.
Id
==
secondId
);
return
agsecondallotRepository
.
GetEntity
(
t
=>
t
.
Id
==
secondId
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment