Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
Y
yifu-mvp
Project
Project
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
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fangxinjiang
yifu-mvp
Commits
10bb1891
Commit
10bb1891
authored
Feb 27, 2026
by
fangxinjiang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
合同续签待办-fxj
parent
1ba39a2d
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
248 additions
and
32 deletions
+248
-32
TAutoContractRuleInfo.java
...d/plus/v1/yifu/archives/entity/TAutoContractRuleInfo.java
+1
-1
EmployeeContractVO.java
...fu/cloud/plus/v1/yifu/archives/vo/EmployeeContractVO.java
+2
-0
EmployeeConstants.java
...ud/plus/v1/yifu/archives/constants/EmployeeConstants.java
+1
-0
TEmployeeContractPreNewController.java
...rchives/controller/TEmployeeContractPreNewController.java
+24
-0
TEmployeeContractPreNewService.java
...yifu/archives/service/TEmployeeContractPreNewService.java
+4
-0
TEmployeeContractPreNewServiceImpl.java
...ives/service/impl/TEmployeeContractPreNewServiceImpl.java
+199
-28
TEmployeeContractPreMapper.xml
.../src/main/resources/mapper/TEmployeeContractPreMapper.xml
+1
-1
TEmployeeContractPreNewMapper.xml
...c/main/resources/mapper/TEmployeeContractPreNewMapper.xml
+1
-2
DateUtil.java
...om/yifu/cloud/plus/v1/yifu/common/core/util/DateUtil.java
+15
-0
No files found.
yifu-archives/yifu-archives-api/src/main/java/com/yifu/cloud/plus/v1/yifu/archives/entity/TAutoContractRuleInfo.java
View file @
10bb1891
...
...
@@ -88,7 +88,7 @@ public class TAutoContractRuleInfo extends BaseEntity {
@Schema
(
description
=
"确认签署时间"
)
private
String
confirmSignDate
;
/**
* 续签合同发起时间类型 0 上一份合同到期前一个月
* 续签合同发起时间类型 0 上一份合同到期前一个月
最新更新为:0 上一份合同到期前第5个工作日 1 上一份合同到期后第10个工作日
*/
@ExcelAttribute
(
name
=
"续签合同发起时间类型 "
)
@ExcelProperty
(
"续签合同发起时间类型 "
)
...
...
yifu-archives/yifu-archives-api/src/main/java/com/yifu/cloud/plus/v1/yifu/archives/vo/EmployeeContractVO.java
View file @
10bb1891
...
...
@@ -276,4 +276,6 @@ public class EmployeeContractVO extends RowIndex implements Serializable {
@Schema
(
description
=
"自动化提交人"
)
@TableField
(
exist
=
false
)
private
String
reNewSubmitter
;
}
yifu-archives/yifu-archives-biz/src/main/java/com/yifu/cloud/plus/v1/yifu/archives/constants/EmployeeConstants.java
View file @
10bb1891
...
...
@@ -106,4 +106,5 @@ public class EmployeeConstants {
public
static
final
String
DATA_CONTRACT_CANCEL_MUST_OFFLINE_SIGN
=
"系统自动撤销签署必须走线下签!"
;
public
static
final
String
DATA_CONTRACT_EXPECTED_SIGN_TIME_ERROR
=
"待续签合同超期一个月,需走线下签"
;
}
yifu-archives/yifu-archives-biz/src/main/java/com/yifu/cloud/plus/v1/yifu/archives/controller/TEmployeeContractPreNewController.java
View file @
10bb1891
...
...
@@ -23,6 +23,8 @@ import com.yifu.cloud.plus.v1.yifu.archives.entity.TEmployeeContractInfo;
import
com.yifu.cloud.plus.v1.yifu.archives.entity.TEmployeeContractPreNew
;
import
com.yifu.cloud.plus.v1.yifu.archives.service.TEmployeeContractPreNewService
;
import
com.yifu.cloud.plus.v1.yifu.archives.vo.*
;
import
com.yifu.cloud.plus.v1.yifu.common.core.util.Common
;
import
com.yifu.cloud.plus.v1.yifu.common.core.util.DateUtil
;
import
com.yifu.cloud.plus.v1.yifu.common.core.util.R
;
import
com.yifu.cloud.plus.v1.yifu.common.log.annotation.SysLog
;
import
com.yifu.cloud.plus.v1.yifu.common.security.annotation.Inner
;
...
...
@@ -33,6 +35,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletResponse
;
import
java.text.ParseException
;
import
java.util.Date
;
import
java.util.List
;
...
...
@@ -320,4 +324,24 @@ public class TEmployeeContractPreNewController {
public
R
getContractTerm
(
@RequestParam
String
startDate
,
@RequestParam
String
endDate
)
{
return
tEmployeeContractPreNewService
.
getContractTerm
(
startDate
,
endDate
);
}
/**
* @Author fxj
* @Description 通过配置找到合同预计发起时间
* @Date 19:19 2026/2/10
**/
@Operation
(
description
=
"通过配置找到合同预计发起时间"
)
@GetMapping
(
"/getPreDateByConfigId"
)
public
R
getPreDateByConfigId
(
@RequestParam
String
configId
,
@RequestParam
String
endDate
)
{
if
(!
Common
.
isNotNull
(
configId
)
||
!
Common
.
isNotNull
(
endDate
)){
return
R
.
failed
();
}
Date
temp
=
null
;
try
{
temp
=
DateUtil
.
parseDate
(
endDate
,
DateUtil
.
ISO_EXPANDED_DATE_FORMAT
);
}
catch
(
ParseException
e
)
{
return
R
.
failed
();
}
return
R
.
ok
(
tEmployeeContractPreNewService
.
getPreDateByConfigId
(
configId
,
temp
));
}
}
yifu-archives/yifu-archives-biz/src/main/java/com/yifu/cloud/plus/v1/yifu/archives/service/TEmployeeContractPreNewService.java
View file @
10bb1891
...
...
@@ -29,6 +29,8 @@ import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.InputStream
;
import
java.time.LocalDate
;
import
java.util.Date
;
import
java.util.List
;
/**
...
...
@@ -79,4 +81,6 @@ public interface TEmployeeContractPreNewService extends IService<TEmployeeContra
R
<
Integer
>
getDetailListCount
(
ContractAlertSearchVo
tEmployeeContractPreNew
);
R
getContractTerm
(
String
startDate
,
String
endDate
);
LocalDate
getPreDateByConfigId
(
String
configId
,
Date
contractEnd
);
}
yifu-archives/yifu-archives-biz/src/main/java/com/yifu/cloud/plus/v1/yifu/archives/service/impl/TEmployeeContractPreNewServiceImpl.java
View file @
10bb1891
...
...
@@ -59,7 +59,6 @@ import javax.servlet.ServletOutputStream;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.net.URLEncoder
;
import
java.text.ParseException
;
import
java.time.LocalDate
;
import
java.time.ZoneId
;
import
java.util.*
;
...
...
@@ -236,6 +235,17 @@ public class TEmployeeContractPreNewServiceImpl extends ServiceImpl<TEmployeeCon
if
(
contract
==
null
){
return
R
.
failed
(
EmployeeConstants
.
DATA_CAN_NOT_FOUND
);
}
//电子签判断预计发起时间是否为当前时间的一个月前
if
(
Common
.
isNotNull
(
preVo
.
getExpectedCollectionTime
())
&&
CommonConstants
.
ZERO_STRING
.
equals
(
preVo
.
getSignType
())
&&
null
!=
preVo
.
getContractStart
()){
LocalDate
reminderDate
=
LocalDateUtil
.
parseLocalDate
(
DateUtil
.
dateToString
(
preVo
.
getExpectedCollectionTime
(),
DateUtil
.
ISO_EXPANDED_DATE_FORMAT
));
LocalDate
contractStartDateNew
=
parseContractEndDate
(
preVo
.
getContractStart
());
if
(
null
!=
contractStartDateNew
&&
reminderDate
.
isAfter
(
contractStartDateNew
.
minusMonths
(
1
))){
return
R
.
failed
(
EmployeeConstants
.
DATA_CONTRACT_EXPECTED_SIGN_TIME_ERROR
);
}
}
////如果电子签是系统自动撤销对应的签署方式必须更新为 线下签
TEmployeeContractPreNew
preNew
=
null
;
if
(
Common
.
isNotNull
(
preVo
.
getId
())
&&
CommonConstants
.
ZERO_STRING
.
equals
(
preVo
.
getSignType
())){
...
...
@@ -317,9 +327,11 @@ public class TEmployeeContractPreNewServiceImpl extends ServiceImpl<TEmployeeCon
TEmployeeContractDateVo
vo
=
null
;
TEmployeeContractPreNew
preNew
=
null
;
String
innitError
=
null
;
int
i
=
0
;
for
(
TEmployeeContractInfo
contract
:
contractList
){
i
++;
alert
=
alertMap
.
get
(
contract
.
getId
());
if
(
null
==
alert
){
if
(
null
==
alert
||
i
>
1
){
checkVo
=
new
TEmployeeAutoRegistCheckVo
();
checkVo
.
setEmployeeName
(
contract
.
getEmpName
());
checkVo
.
setEmpIdcard
(
contract
.
getEmpIdcard
());
...
...
@@ -372,7 +384,64 @@ public class TEmployeeContractPreNewServiceImpl extends ServiceImpl<TEmployeeCon
continue
;
}
}
//初始化岗位名称
TAutoContractScheme
scheme
=
contractSchemeMapper
.
selectById
(
pre
.
getConfigId
());
if
(
Common
.
isNotNull
(
pre
.
getConfigId
())
&&
"固定岗位"
.
equals
(
preVo
.
getPost
())
&&
null
!=
scheme
){
pre
.
setPost
(
scheme
.
getPost
());
}
//处理预计发起时间
TAutoContractRuleInfo
rule
=
null
;
if
(
null
!=
scheme
){
rule
=
contractRuleInfoMapper
.
selectOne
(
Wrappers
.<
TAutoContractRuleInfo
>
query
().
lambda
()
.
eq
(
TAutoContractRuleInfo:
:
getDeptNo
,
scheme
.
getDeptNo
())
.
last
(
CommonConstants
.
LAST_ONE_SQL
));
}
if
(
null
!=
rule
&&
null
!=
contract
.
getContractEnd
()){
//上一份合同到期前第5个工作日: 20251229(含)前第5个工作日_25年12月23日,若是已过去的时间,则按照当前日期(含)往后继续找工作日,若超过一个月后了,
// 则也呈现,但是只能是线下签
// 计算往前3个工作日
if
(
null
!=
rule
&&
null
!=
contract
.
getContractEnd
())
{
// 解析合同结束日期
LocalDate
contractEndDate
=
parseContractEndDate
(
contract
.
getContractEnd
());
if
(
null
==
contractEndDate
)
{
checkVo
=
buildErrorCheckVo
(
contract
,
preVo
,
"合同结束日期解析失败"
);
errorList
.
add
(
checkVo
);
continue
;
}
// 计算预计发起日期
LocalDate
reminderDate
=
calculateReminderDate
(
rule
.
getRenewalDateType
(),
contractEndDate
);
if
(
null
==
reminderDate
)
{
checkVo
=
buildErrorCheckVo
(
contract
,
preVo
,
"预计发起时间初始化失败"
);
errorList
.
add
(
checkVo
);
continue
;
}
// 检查电子签是否超期(和续签的合同开始日期进行比较)
if
(
null
!=
preVo
.
getContractStart
()
&&
CommonConstants
.
ZERO_STRING
.
equals
(
preVo
.
getSignType
())){
LocalDate
contractStartDateNew
=
parseContractEndDate
(
preVo
.
getContractStart
());
if
(
null
==
contractEndDate
)
{
checkVo
=
buildErrorCheckVo
(
contract
,
preVo
,
"续签合同开始日期解析失败"
);
errorList
.
add
(
checkVo
);
continue
;
}
if
(
reminderDate
.
isAfter
(
contractStartDateNew
.
minusMonths
(
1
)))
{
checkVo
=
buildErrorCheckVo
(
contract
,
preVo
,
EmployeeConstants
.
DATA_CONTRACT_EXPECTED_SIGN_TIME_ERROR
);
errorList
.
add
(
checkVo
);
continue
;
}
}
// 调整提醒日期为最近工作日 (0 上一份合同到期前第5个工作日的场景才调整)
if
(
CommonConstants
.
ZERO_STRING
.
equals
(
rule
.
getRenewalDateType
())){
reminderDate
=
adjustToNearestWorkday
(
reminderDate
);
}
// 设置预计发起时间
pre
.
setExpectedCollectionTime
(
DateUtil
.
getDateByLocalDate
(
reminderDate
));
}
}
pre
=
new
TEmployeeContractPreNew
();
BeanCopyUtils
.
copyProperties
(
preVo
,
pre
);
pre
.
setContractId
(
contract
.
getId
());
...
...
@@ -392,31 +461,7 @@ public class TEmployeeContractPreNewServiceImpl extends ServiceImpl<TEmployeeCon
pre
.
setOverFlag
(
CommonConstants
.
ONE_STRING
);
pre
.
setSignFlag
(
CommonConstants
.
ONE_STRING
);
}
//初始化岗位名称
TAutoContractScheme
scheme
=
contractSchemeMapper
.
selectById
(
pre
.
getConfigId
());
if
(
Common
.
isNotNull
(
pre
.
getConfigId
())
&&
"固定岗位"
.
equals
(
preVo
.
getPost
())
&&
null
!=
scheme
){
pre
.
setPost
(
scheme
.
getPost
());
}
//处理预计发起时间
TAutoContractRuleInfo
rule
=
null
;
if
(
null
!=
scheme
){
rule
=
contractRuleInfoMapper
.
selectOne
(
Wrappers
.<
TAutoContractRuleInfo
>
query
().
lambda
()
.
eq
(
TAutoContractRuleInfo:
:
getDeptNo
,
scheme
.
getDeptNo
())
.
last
(
CommonConstants
.
LAST_ONE_SQL
));
}
//续签合同发起时间类型 :0 上一份合同到期前一个月
if
(
null
!=
rule
&&
CommonConstants
.
ZERO_STRING
.
equals
(
rule
.
getRenewalDateType
())
&&
null
!=
contract
.
getContractEnd
()){
Date
dateTemp
=
null
;
try
{
dateTemp
=
DateUtil
.
parseDate
(
DateUtil
.
dateToString
(
contract
.
getContractEnd
(),
DateUtil
.
ISO_EXPANDED_DATE_FORMAT
)
+
" 15:20"
,
DateUtil
.
DATETIME_PATTERN_MINUTE
);
}
catch
(
ParseException
e
)
{
dateTemp
=
new
Date
();
}
if
(
null
!=
dateTemp
){
pre
.
setExpectedCollectionTime
(
DateUtil
.
addDayByDate
(
DateUtil
.
addMonthByDate
(
dateTemp
,-
1
),-
1
));
}
}
preList
.
add
(
pre
);
}
boolean
res
=
false
;
...
...
@@ -435,6 +480,57 @@ public class TEmployeeContractPreNewServiceImpl extends ServiceImpl<TEmployeeCon
return
R
.
failed
(
CommonConstants
.
RESULT_DATA_FAIL
);
}
}
/**
* 解析合同结束日期
*/
private
LocalDate
parseContractEndDate
(
Date
contractEnd
)
{
try
{
return
LocalDateUtil
.
parseLocalDate
(
DateUtil
.
dateToString
(
contractEnd
,
DateUtil
.
ISO_EXPANDED_DATE_FORMAT
)
+
" 15:20"
);
}
catch
(
Exception
e
)
{
return
null
;
}
}
/**
* 根据规则类型计算提醒日期
*/
private
LocalDate
calculateReminderDate
(
String
renewalDateType
,
LocalDate
contractEndDate
)
{
if
(
CommonConstants
.
ZERO_STRING
.
equals
(
renewalDateType
))
{
return
calculateReminderWorkDaysBefore
(
contractEndDate
,
5
,
0
);
}
else
if
(
CommonConstants
.
ONE_STRING
.
equals
(
renewalDateType
))
{
return
calculateReminderWorkDaysBefore
(
contractEndDate
,
10
,
1
);
}
return
null
;
}
/**
* 判断是否强制走线下签
*/
private
boolean
shouldEnforceOfflineSign
(
LocalDate
reminderDate
,
String
signType
)
{
return
reminderDate
.
isBefore
(
LocalDate
.
now
().
plusMonths
(
1
).
minusDays
(
1
))
&&
CommonConstants
.
ZERO_STRING
.
equals
(
signType
);
}
/**
* 构建错误检查对象
*/
private
TEmployeeAutoRegistCheckVo
buildErrorCheckVo
(
TEmployeeContractInfo
contract
,
TEmployeeContractPreNewVo
preVo
,
String
errorMsg
)
{
TEmployeeAutoRegistCheckVo
checkVo
=
new
TEmployeeAutoRegistCheckVo
();
checkVo
.
setEmployeeName
(
contract
.
getEmpName
());
checkVo
.
setEmpIdcard
(
contract
.
getEmpIdcard
());
checkVo
.
setDeptName
(
preVo
.
getDeptName
());
checkVo
.
setDeptNo
(
preVo
.
getDeptNo
());
checkVo
.
setType
(
"合同"
);
// 可配置化处理
checkVo
.
setErrorMsg
(
errorMsg
);
return
checkVo
;
}
/**
* 调整日期为最近工作日
*/
private
LocalDate
adjustToNearestWorkday
(
LocalDate
date
)
{
return
date
.
isBefore
(
LocalDate
.
now
())
?
calculateReminderWorkDaysBefore
(
date
,
1
,
0
)
:
date
;
}
private
String
initDateInfo
(
TEmployeeContractPreNewVo
preVo
,
TEmployeeContractInfo
contract
)
{
TEmployeeContractDateVo
vo
;
...
...
@@ -1057,6 +1153,7 @@ public class TEmployeeContractPreNewServiceImpl extends ServiceImpl<TEmployeeCon
contractInfo
=
contractInfoService
.
getOne
(
Wrappers
.<
TEmployeeContractInfo
>
query
()
.
lambda
().
eq
(
TEmployeeContractInfo:
:
getPreNewId
,
pre
.
getId
())
.
eq
(
TEmployeeContractInfo:
:
getDeleteFlag
,
CommonConstants
.
ZERO_INT
)
.
eq
(
TEmployeeContractInfo:
:
getAuditStatus
,
CommonConstants
.
ONE_INT
)
.
last
(
CommonConstants
.
LAST_ONE_SQL
));
if
(
Common
.
isNotNull
(
contractInfo
))
{
contractInfo
.
setAuditStatus
(
CommonConstants
.
FIVE_INT
);
...
...
@@ -1463,7 +1560,30 @@ public class TEmployeeContractPreNewServiceImpl extends ServiceImpl<TEmployeeCon
Collections
.
reverse
(
reminderDates
);
return
reminderDates
;
}
/**
* @Author fxj
* @Description 往前找指定个工作日 含当前日期
* @param type 0 往前 1 往后
* @Date 19:24 2026/2/26
* @return
**/
private
LocalDate
calculateReminderWorkDaysBefore
(
LocalDate
lastDay
,
int
count
,
int
type
)
{
LocalDate
currentDate
=
lastDay
;
int
workDayCount
=
0
;
// 往前找3个工作日
while
(
workDayCount
<
count
)
{
// 检查当前日期是否为工作日
if
(
isWorkDay
(
currentDate
))
{
workDayCount
++;
}
if
(
workDayCount
==
count
){
return
currentDate
;
}
// 往前一天
currentDate
=
currentDate
.
minusDays
(
0
==
type
?
1
:-
1
);
}
return
currentDate
;
}
/**
* 判断指定日期是否为工作日
* @param date 要检查的日期
...
...
@@ -1730,4 +1850,55 @@ public class TEmployeeContractPreNewServiceImpl extends ServiceImpl<TEmployeeCon
}
}
}
/**
* @Author fxj
* @Description 按配置返回对应的预计发起时间
* @Date 10:30 2026/2/27
* @Param
* @return
**/
@Override
public
LocalDate
getPreDateByConfigId
(
String
configId
,
Date
contractEnd
){
if
(!
Common
.
isNotNull
(
configId
)){
return
null
;
}
TAutoContractScheme
scheme
=
contractSchemeMapper
.
selectById
(
configId
);
if
(
null
==
scheme
){
return
null
;
}
//处理预计发起时间
TAutoContractRuleInfo
rule
=
null
;
if
(
null
!=
scheme
){
rule
=
contractRuleInfoMapper
.
selectOne
(
Wrappers
.<
TAutoContractRuleInfo
>
query
().
lambda
()
.
eq
(
TAutoContractRuleInfo:
:
getDeptNo
,
scheme
.
getDeptNo
())
.
last
(
CommonConstants
.
LAST_ONE_SQL
));
}
if
(
null
==
rule
){
return
null
;
}
if
(
null
!=
rule
&&
null
!=
contractEnd
){
//上一份合同到期前第5个工作日: 20251229(含)前第5个工作日_25年12月23日,若是已过去的时间,则按照当前日期(含)往后继续找工作日,若超过一个月后了,
// 则也呈现,但是只能是线下签
// 计算往前3个工作日
if
(
null
!=
rule
&&
null
!=
contractEnd
)
{
// 解析合同结束日期
LocalDate
contractEndDate
=
parseContractEndDate
(
contractEnd
);
if
(
null
==
contractEndDate
)
{
return
null
;
}
// 计算预计发起日期
LocalDate
reminderDate
=
calculateReminderDate
(
rule
.
getRenewalDateType
(),
contractEndDate
);
if
(
null
==
reminderDate
)
{
return
null
;
}
// 调整提醒日期为最近工作日 (0 上一份合同到期前第5个工作日的场景才调整)
if
(
CommonConstants
.
ZERO_STRING
.
equals
(
rule
.
getRenewalDateType
())){
reminderDate
=
adjustToNearestWorkday
(
reminderDate
);
}
return
reminderDate
;
}
}
return
null
;
}
}
yifu-archives/yifu-archives-biz/src/main/resources/mapper/TEmployeeContractPreMapper.xml
View file @
10bb1891
...
...
@@ -399,7 +399,7 @@
a.emp_idcard empIdcard,
a.dept_no deptNo,
a.situation,
a.contract_
typ
e contractName,
a.contract_
nam
e contractName,
a.CONTRACT_SUB_NAME contractSubName,
null reason,
a.signatory contractParty,
...
...
yifu-archives/yifu-archives-biz/src/main/resources/mapper/TEmployeeContractPreNewMapper.xml
View file @
10bb1891
...
...
@@ -658,8 +658,7 @@
a.emp_idcard empIdcard,
a.dept_no deptNo,
a.situation,
a.contract_type contractName,
a.contract_term contractType,
a.contract_name contractName,
a.CONTRACT_SUB_NAME contractSubName,
null reason,
a.signatory contractParty,
...
...
yifu-common/yifu-common-core/src/main/java/com/yifu/cloud/plus/v1/yifu/common/core/util/DateUtil.java
View file @
10bb1891
...
...
@@ -1997,6 +1997,21 @@ public class DateUtil {
return
false
;
}
/**
* @Author fxj
* @Description LocalDate 转 Date 类型
* @Date 19:42 2026/2/26
* @Param
* @return
**/
public
static
Date
getDateByLocalDate
(
LocalDate
date
)
{
if
(
date
==
null
)
{
return
null
;
// 输入为空时直接返回 null
}
// 使用系统默认时区将 LocalDate 转换为 Date
return
Date
.
from
(
date
.
atStartOfDay
(
ZoneId
.
systemDefault
()).
toInstant
());
}
/**
* 日期月份类型枚举
*/
...
...
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