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
46924e28
Commit
46924e28
authored
Mar 17, 2022
by
ruyun.zhang@suvalue.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'release/v22.2.14-Beta-lintao' into release/v22.2.10-Beta-ninghai
parents
1e88dc9b
7835241b
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
70 additions
and
68 deletions
+70
-68
performance/Performance.Api/Controllers/SecondAllotController.cs
+3
-0
performance/Performance.Api/wwwroot/Performance.Api.xml
+0
-35
performance/Performance.DtoModels/Enum.cs
+10
-0
performance/Performance.Repository/PerforAgsecondallotRepository.cs
+7
-0
performance/Performance.Services/ExtractExcelService/DictionaryService.cs
+10
-3
performance/Performance.Services/ExtractExcelService/ExtractHelper/WriteDataHelper.cs
+1
-1
performance/Performance.Services/ExtractExcelService/ExtractService.cs
+3
-0
performance/Performance.Services/ExtractExcelService/QueryService.cs
+10
-2
performance/Performance.Services/SecondAllotService.cs
+26
-27
No files found.
performance/Performance.Api/Controllers/SecondAllotController.cs
View file @
46924e28
...
@@ -745,6 +745,9 @@ public ApiResponse RedistributionSave([FromBody] SecondComputeDto request)
...
@@ -745,6 +745,9 @@ public ApiResponse RedistributionSave([FromBody] SecondComputeDto request)
var
second
=
secondAllotService
.
GetSecondAllot
(
request
.
SecondId
);
var
second
=
secondAllotService
.
GetSecondAllot
(
request
.
SecondId
);
if
(
second
==
null
)
throw
new
PerformanceException
(
"参数SecondId无效!"
);
if
(
second
==
null
)
throw
new
PerformanceException
(
"参数SecondId无效!"
);
if
(
second
.
Status
==
(
int
)
SecondAllot
.
Status
.
等待审核
||
second
.
Status
==
(
int
)
SecondAllot
.
Status
.
审核通过
)
throw
new
PerformanceException
(
"保存失败,当前二次分配已提交!"
);
var
allot
=
_allotService
.
GetAllot
(
second
.
AllotId
.
Value
);
var
allot
=
_allotService
.
GetAllot
(
second
.
AllotId
.
Value
);
if
(
allot
==
null
)
if
(
allot
==
null
)
throw
new
PerformanceException
(
"绩效记录不存在!"
);
throw
new
PerformanceException
(
"绩效记录不存在!"
);
...
...
performance/Performance.Api/wwwroot/Performance.Api.xml
View file @
46924e28
...
@@ -2286,41 +2286,6 @@
...
@@ -2286,41 +2286,6 @@
<param
name=
"query"
></param>
<param
name=
"query"
></param>
<returns></returns>
<returns></returns>
</member>
</member>
<member
name=
"M:Performance.Api.BackgroundJob.Execute_Allot_Generate(Performance.Services.TaskService,Performance.EntityModels.bg_task)"
>
<summary>
生成测算表
</summary>
<param
name=
"service"
></param>
<param
name=
"task"
></param>
</member>
<member
name=
"M:Performance.Api.BackgroundJob.Execute_Allot_Generate_Report(Performance.Services.TaskService,Performance.EntityModels.bg_task)"
>
<summary>
生成报表
</summary>
<param
name=
"service"
></param>
<param
name=
"task"
></param>
</member>
<member
name=
"M:Performance.Api.BackgroundJob.Execute_Allot_CustomExtract(Performance.Services.TaskService,Performance.EntityModels.bg_task)"
>
<summary>
提取绩效数据
</summary>
<param
name=
"service"
></param>
<param
name=
"task"
></param>
</member>
<member
name=
"M:Performance.Api.BackgroundJob.Timeout(Performance.Services.TaskService,System.Collections.Generic.List{Performance.EntityModels.bg_task})"
>
<summary>
超时关闭
</summary>
<param
name=
"service"
></param>
<param
name=
"tasks"
></param>
</member>
<member
name=
"M:Performance.Api.BackgroundJob.Repeat(Performance.Services.TaskService,System.Collections.Generic.List{Performance.EntityModels.bg_task})"
>
<summary>
重复任务仅执行最后异常
</summary>
<param
name=
"service"
></param>
<param
name=
"tasks"
></param>
</member>
<member
name=
"T:Performance.Api.ClearLoggerJob"
>
<member
name=
"T:Performance.Api.ClearLoggerJob"
>
<summary>
<summary>
删除历史日志
删除历史日志
...
...
performance/Performance.DtoModels/Enum.cs
View file @
46924e28
...
@@ -155,4 +155,14 @@ public enum Status
...
@@ -155,4 +155,14 @@ public enum Status
超时
=
99
,
超时
=
99
,
}
}
}
}
public
class
SecondAllot
{
public
enum
Status
{
未提交
=
1
,
等待审核
=
2
,
审核通过
=
3
,
驳回
=
4
,
}
}
}
}
performance/Performance.Repository/PerforAgsecondallotRepository.cs
View file @
46924e28
using
Performance.EntityModels
;
using
Performance.EntityModels
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Linq
;
...
@@ -42,5 +43,11 @@ public List<view_second_compute_collect> GetComputeBySecond(int secondId)
...
@@ -42,5 +43,11 @@ public List<view_second_compute_collect> GetComputeBySecond(int secondId)
return
new
List
<
view_second_compute_collect
>();
return
new
List
<
view_second_compute_collect
>();
}
}
public
int
Submit
(
int
secondId
,
int
tempId
,
decimal
realGiveFee
,
int
submitType
,
string
remark
=
""
)
{
string
sql
=
"UPDATE ag_secondallot SET UseTempId = @tempId,NursingDeptStatus = @status, Status = @status, SubmitType = @submitType,SubmitTime = @date, Remark = @remark WHERE Id = @secondId AND RealGiveFee = @fee"
;
return
Execute
(
sql
,
new
{
secondId
,
tempId
,
status
=
2
,
date
=
DateTime
.
Now
,
fee
=
realGiveFee
,
submitType
,
remark
});
}
}
}
}
}
performance/Performance.Services/ExtractExcelService/DictionaryService.cs
View file @
46924e28
...
@@ -91,13 +91,16 @@ public void Handler(int hospitalId, per_allot allot, string groupName, bool isSi
...
@@ -91,13 +91,16 @@ public void Handler(int hospitalId, per_allot allot, string groupName, bool isSi
}
}
}
}
logService
.
ReturnTheLog
(
allot
.
ID
,
groupName
,
2
,
"提取数据"
,
$"开始提取HIS数据"
,
isSingle
:
isSingle
);
var
hisScrips
=
hisscriptRepository
.
GetEntities
(
t
=>
t
.
HospitalId
==
hospitalId
);
var
hisScrips
=
hisscriptRepository
.
GetEntities
(
t
=>
t
.
HospitalId
==
hospitalId
);
if
(
hisScrips
==
null
||
!
hisScrips
.
Any
())
return
;
if
(
hisScrips
==
null
||
!
hisScrips
.
Any
())
return
;
foreach
(
var
item
in
hisScrips
)
foreach
(
var
item
in
hisScrips
)
{
{
logService
.
ReturnTheLog
(
allot
.
ID
,
groupName
,
2
,
"提取数据"
,
$"提取
{
item
.
SourceType
}
-
{
item
.
Category
}
数据"
,
isSingle
:
isSingle
);
HisData
(
allot
,
configs
.
FirstOrDefault
(
t
=>
t
.
Id
==
item
.
ConfigId
),
item
,
groupName
,
isSingle
);
HisData
(
allot
,
configs
.
FirstOrDefault
(
t
=>
t
.
Id
==
item
.
ConfigId
),
item
,
isSingle
);
}
}
logService
.
ReturnTheLog
(
allot
.
ID
,
groupName
,
2
,
"提取数据"
,
$"提取HIS数据完成"
,
isSingle
:
isSingle
);
}
}
catch
(
Exception
)
catch
(
Exception
)
{
{
...
@@ -227,10 +230,12 @@ private void JudgeDataEqual(List<string> columns, List<per_employee> emps, List<
...
@@ -227,10 +230,12 @@ private void JudgeDataEqual(List<string> columns, List<per_employee> emps, List<
}
}
}
}
private
void
HisData
(
per_allot
allot
,
sys_hospitalconfig
config
,
his_script
script
,
bool
isSingle
)
private
void
HisData
(
per_allot
allot
,
sys_hospitalconfig
config
,
his_script
script
,
string
groupName
,
bool
isSingle
)
{
{
try
try
{
{
logService
.
ReturnTheLog
(
allot
.
ID
,
groupName
,
2
,
"提取数据"
,
$"提取“
{
script
.
SourceType
}
-
{
script
.
Category
}
”数据"
,
isSingle
:
isSingle
);
if
(
config
==
null
||
string
.
IsNullOrEmpty
(
script
.
ExecScript
))
return
;
if
(
config
==
null
||
string
.
IsNullOrEmpty
(
script
.
ExecScript
))
return
;
var
data
=
queryService
.
QueryData
<
HisData
>(
config
,
script
.
ExecScript
,
allot
,
isSingle
);
var
data
=
queryService
.
QueryData
<
HisData
>(
config
,
script
.
ExecScript
,
allot
,
isSingle
);
...
@@ -259,10 +264,12 @@ private void HisData(per_allot allot, sys_hospitalconfig config, his_script scri
...
@@ -259,10 +264,12 @@ private void HisData(per_allot allot, sys_hospitalconfig config, his_script scri
CreateTime
=
DateTime
.
Now
,
CreateTime
=
DateTime
.
Now
,
});
});
hisdataRepository
.
AddRange
(
insertData
.
ToArray
());
hisdataRepository
.
AddRange
(
insertData
.
ToArray
());
logService
.
ReturnTheLog
(
allot
.
ID
,
groupName
,
2
,
"提取数据"
,
$"提取“
{
script
.
SourceType
}
-
{
script
.
Category
}
”完成"
,
isSingle
:
isSingle
);
}
}
catch
(
Exception
ex
)
catch
(
Exception
ex
)
{
{
logger
.
LogError
(
"获取his_data时发生异常:"
+
ex
.
ToString
());
logger
.
LogError
(
"获取his_data时发生异常:"
+
ex
.
ToString
());
logService
.
ReturnTheLog
(
allot
.
ID
,
allot
.
ID
.
ToString
(),
2
,
"SQL错误"
,
$"获取HIS数据“
{
script
.
SourceType
}
-
{
script
.
Category
}
”时发生异常"
,
3
,
isSingle
);
}
}
}
}
...
...
performance/Performance.Services/ExtractExcelService/ExtractHelper/WriteDataHelper.cs
View file @
46924e28
...
@@ -159,7 +159,7 @@ public static void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType s
...
@@ -159,7 +159,7 @@ public static void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType s
string
department
=
row
.
GetOrCreate
(
dataFirstCellNum
-
1
).
GetDecodeEscapes
();
string
department
=
row
.
GetOrCreate
(
dataFirstCellNum
-
1
).
GetDecodeEscapes
();
if
(
string
.
IsNullOrEmpty
(
department
))
continue
;
if
(
string
.
IsNullOrEmpty
(
department
))
continue
;
if
(
rowIndex
>
dataFirstRowNum
)
dataFirstRowNum
=
rowIndex
+
1
;
if
(
rowIndex
>
=
dataFirstRowNum
)
dataFirstRowNum
=
rowIndex
+
1
;
var
deptData
=
data
.
Where
(
t
=>
t
.
Department
.
NoBlank
()
==
department
);
var
deptData
=
data
.
Where
(
t
=>
t
.
Department
.
NoBlank
()
==
department
);
if
(
deptData
==
null
||
!
deptData
.
Any
(
t
=>
t
.
Value
.
HasValue
&&
t
.
Value
!=
0
))
continue
;
if
(
deptData
==
null
||
!
deptData
.
Any
(
t
=>
t
.
Value
.
HasValue
&&
t
.
Value
!=
0
))
continue
;
...
...
performance/Performance.Services/ExtractExcelService/ExtractService.cs
View file @
46924e28
...
@@ -106,10 +106,13 @@ public string Main(int allotId, int hospitalId, string email, string groupName,
...
@@ -106,10 +106,13 @@ public string Main(int allotId, int hospitalId, string email, string groupName,
var
data
=
exresultRepository
.
GetEntities
(
t
=>
t
.
AllotId
==
allotId
);
var
data
=
exresultRepository
.
GetEntities
(
t
=>
t
.
AllotId
==
allotId
);
data
.
AddRange
(
queryService
.
Handler
(
hospitalId
,
allot
,
groupName
,
isSingle
,
ref
dict
));
data
.
AddRange
(
queryService
.
Handler
(
hospitalId
,
allot
,
groupName
,
isSingle
,
ref
dict
));
logService
.
ReturnTheLog
(
allotId
,
groupName
,
2
,
"提取数据"
,
$"开始格式化数据"
,
1
,
isSingle
);
var
standData
=
StandDataFormat
(
hospitalId
,
data
);
var
standData
=
StandDataFormat
(
hospitalId
,
data
);
logService
.
ReturnTheLog
(
allotId
,
groupName
,
2
,
"提取数据"
,
$"格式化完成"
,
1
,
isSingle
);
dictionaryService
.
Handler
(
hospitalId
,
allot
,
groupName
,
isSingle
);
dictionaryService
.
Handler
(
hospitalId
,
allot
,
groupName
,
isSingle
);
logService
.
ReturnTheLog
(
allotId
,
groupName
,
2
,
"准备写入"
,
$"数据提取结束准备写入"
,
1
,
isSingle
);
var
statesArray
=
new
int
[]
{
(
int
)
AllotStates
.
GenerateSucceed
,
(
int
)
AllotStates
.
Archive
};
var
statesArray
=
new
int
[]
{
(
int
)
AllotStates
.
GenerateSucceed
,
(
int
)
AllotStates
.
Archive
};
var
templateFilePath
=
ExtractHelper
.
GetExtractFile
(
hospitalId
,
allot
,
ref
extractFilePath
,
filePath
);
var
templateFilePath
=
ExtractHelper
.
GetExtractFile
(
hospitalId
,
allot
,
ref
extractFilePath
,
filePath
);
...
...
performance/Performance.Services/ExtractExcelService/QueryService.cs
View file @
46924e28
...
@@ -435,12 +435,20 @@ public IEnumerable<T> QueryData<T>(sys_hospitalconfig config, string execsql, pe
...
@@ -435,12 +435,20 @@ public IEnumerable<T> QueryData<T>(sys_hospitalconfig config, string execsql, pe
logService
.
ReturnTheLog
(
allot
.
ID
,
allot
.
ID
.
ToString
(),
2
,
"数据库连接"
,
$"数据库“
{
config
.
DbName
}
”连接失败"
,
3
,
isSingle
);
logService
.
ReturnTheLog
(
allot
.
ID
,
allot
.
ID
.
ToString
(),
2
,
"数据库连接"
,
$"数据库“
{
config
.
DbName
}
”连接失败"
,
3
,
isSingle
);
}
}
try
{
logger
.
LogInformation
(
$"提取绩效数据SQL脚本
{
execsql
}
"
);
logger
.
LogInformation
(
$"提取绩效数据SQL脚本
{
execsql
}
"
);
var
result
=
connection
.
Query
<
T
>(
execsql
,
commandTimeout
:
20000
);
var
result
=
connection
.
Query
<
T
>(
execsql
,
commandTimeout
:
60
*
60
*
5
);
logger
.
LogInformation
(
$"提取绩效数据执行脚本获取数据
{
result
?.
Count
()
??
0
}
条记录"
);
logger
.
LogInformation
(
$"提取绩效数据执行脚本获取数据
{
result
?.
Count
()
??
0
}
条记录"
);
return
result
;
return
result
;
}
}
catch
(
Exception
ex
)
{
logger
.
LogError
(
$"SQL发生异常:
{
execsql
}
;
{
ex
}
"
);
throw
;
}
}
/// <summary>
/// <summary>
/// 获取参数
/// 获取参数
...
...
performance/Performance.Services/SecondAllotService.cs
View file @
46924e28
...
@@ -1621,14 +1621,11 @@ bool VerifySubmissioAmount(decimal? leftAmount, decimal? rightAmount)
...
@@ -1621,14 +1621,11 @@ bool VerifySubmissioAmount(decimal? leftAmount, decimal? rightAmount)
if
(!
VerifySubmissioAmount
(
total
,
second
.
RealGiveFee
))
if
(!
VerifySubmissioAmount
(
total
,
second
.
RealGiveFee
))
throw
new
PerformanceException
(
$"总金额与考核后金额不一致!可分配金额:
{
second
.
RealGiveFee
}
,提交金额:
{
total
}
"
);
throw
new
PerformanceException
(
$"总金额与考核后金额不一致!可分配金额:
{
second
.
RealGiveFee
}
,提交金额:
{
total
}
"
);
logger
.
LogCritical
(
"程序虽然抛出异常但是还是执行了后续代码"
);
var
submitType
=
temp
.
UseTempId
==
6
?
2
:
1
;
second
.
UseTempId
=
temp
.
UseTempId
;
var
res
=
agsecondallotRepository
.
Submit
(
second
.
Id
,
temp
.
UseTempId
??
0
,
total
,
submitType
);
second
.
Status
=
2
;
if
(
res
==
0
)
second
.
NursingDeptStatus
=
2
;
throw
new
PerformanceException
(
$"提交失败,当前绩效分配可能发生改变!"
);
second
.
SubmitType
=
temp
.
UseTempId
==
6
?
2
:
1
;
return
true
;
second
.
SubmitTime
=
DateTime
.
Now
;
//second.Remark = "已提交审核,等待审核中";
return
agsecondallotRepository
.
Update
(
second
);
}
}
else
if
(
new
int
[]
{
7
,
8
}.
Contains
(
temp
.
UseTempId
.
Value
))
else
if
(
new
int
[]
{
7
,
8
}.
Contains
(
temp
.
UseTempId
.
Value
))
{
{
...
@@ -1641,14 +1638,11 @@ bool VerifySubmissioAmount(decimal? leftAmount, decimal? rightAmount)
...
@@ -1641,14 +1638,11 @@ bool VerifySubmissioAmount(decimal? leftAmount, decimal? rightAmount)
if
(!
VerifySubmissioAmount
(
total
,
second
.
RealGiveFee
))
if
(!
VerifySubmissioAmount
(
total
,
second
.
RealGiveFee
))
throw
new
PerformanceException
(
$"总金额与考核后金额不一致!可分配金额:
{
second
.
RealGiveFee
}
,提交金额:
{
total
}
"
);
throw
new
PerformanceException
(
$"总金额与考核后金额不一致!可分配金额:
{
second
.
RealGiveFee
}
,提交金额:
{
total
}
"
);
logger
.
LogCritical
(
"程序虽然抛出异常但是还是执行了后续代码"
);
var
submitType
=
temp
.
UseTempId
==
6
?
2
:
1
;
second
.
UseTempId
=
temp
.
UseTempId
;
var
res
=
agsecondallotRepository
.
Submit
(
second
.
Id
,
temp
.
UseTempId
??
0
,
total
,
submitType
);
second
.
Status
=
2
;
if
(
res
==
0
)
second
.
NursingDeptStatus
=
2
;
throw
new
PerformanceException
(
$"提交失败,当前绩效分配可能发生改变请刷新后重试!"
);
second
.
SubmitType
=
temp
.
UseTempId
==
6
?
2
:
1
;
return
true
;
second
.
SubmitTime
=
DateTime
.
Now
;
//second.Remark = "已提交审核,等待审核中";
return
agsecondallotRepository
.
Update
(
second
);
}
}
else
/*if (new int[] { 9, 10 }.Contains(temp.UseTempId.Value))*/
else
/*if (new int[] { 9, 10 }.Contains(temp.UseTempId.Value))*/
{
{
...
@@ -1657,26 +1651,31 @@ bool VerifySubmissioAmount(decimal? leftAmount, decimal? rightAmount)
...
@@ -1657,26 +1651,31 @@ bool VerifySubmissioAmount(decimal? leftAmount, decimal? rightAmount)
throw
new
PerformanceException
(
"提交时未检测到数据!"
);
throw
new
PerformanceException
(
"提交时未检测到数据!"
);
else
else
{
{
var
nightShiftWorkPerforFee
=
data
?
.
Sum
(
w
=>
w
.
NightWorkPerformance
??
0
);
var
nightShiftWorkPerforFee
=
data
.
Sum
(
w
=>
w
.
NightWorkPerformance
??
0
);
var
total
=
data
?
.
Sum
(
t
=>
(
t
.
DistPerformance
??
0
)
+
(
t
.
NightWorkPerformance
??
0
));
var
total
=
data
.
Sum
(
t
=>
(
t
.
DistPerformance
??
0
)
+
(
t
.
NightWorkPerformance
??
0
));
if
(!
VerifySubmissioAmount
(
nightShiftWorkPerforFee
,
second
.
NightShiftWorkPerforFee
))
if
(!
VerifySubmissioAmount
(
nightShiftWorkPerforFee
,
second
.
NightShiftWorkPerforFee
))
throw
new
PerformanceException
(
$"夜班绩效金额不一致!夜班绩效金额:
{
second
.
NightShiftWorkPerforFee
??
0
:
0.
####
}
,提交金额:
{
nightShiftWorkPerforFee
:
0.
####
}
"
);
throw
new
PerformanceException
(
$"夜班绩效金额不一致!夜班绩效金额:
{
second
.
NightShiftWorkPerforFee
??
0
:
0.
####
}
,提交金额:
{
nightShiftWorkPerforFee
:
0.
####
}
"
);
else
if
(!
VerifySubmissioAmount
(
total
,
second
.
RealGiveFee
))
else
if
(!
VerifySubmissioAmount
(
total
,
second
.
RealGiveFee
))
throw
new
PerformanceException
(
$"总金额与考核后金额不一致!可分配金额:
{
second
.
RealGiveFee
:
0.
####
}
,提交金额:
{
total
:
0.
####
}
"
);
throw
new
PerformanceException
(
$"总金额与考核后金额不一致!可分配金额:
{
second
.
RealGiveFee
:
0.
####
}
,提交金额:
{
total
:
0.
####
}
"
);
else
else
{
{
// 这段逻辑是为了监测 验证失败后继续修改状态而特意加入的
var
submitType
=
temp
.
UseTempId
==
6
?
2
:
1
;
second
.
UseTempId
=
temp
.
UseTempId
;
var
res
=
agsecondallotRepository
.
Submit
(
second
.
Id
,
temp
.
UseTempId
??
0
,
total
,
submitType
);
second
.
Status
=
2
;
if
(
res
==
0
)
second
.
NursingDeptStatus
=
2
;
throw
new
PerformanceException
(
$"提交失败,当前绩效分配可能发生改变,请刷新后重试!"
);
second
.
SubmitType
=
temp
.
UseTempId
==
6
?
2
:
1
;
return
true
;
second
.
SubmitTime
=
DateTime
.
Now
;
//second.Remark = "已提交审核,等待审核中";
return
agsecondallotRepository
.
Update
(
second
);
}
}
}
}
}
}
logger
.
LogCritical
(
"程序虽然抛出异常但是还是执行了后续代码"
);
//logger.LogCritical("程序虽然抛出异常但是还是执行了后续代码");
//second.UseTempId = temp.UseTempId;
//second.Status = 2;
//second.NursingDeptStatus = 2;
//second.SubmitType = temp.UseTempId == 6 ? 2 : 1;
//second.SubmitTime = DateTime.Now;
//second.Remark = "已提交审核,等待审核中";
//return agsecondallotRepository.Update(second);
}
}
/// <summary>
/// <summary>
...
...
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