Commit 10bb1891 authored by fangxinjiang's avatar fangxinjiang

合同续签待办-fxj

parent 1ba39a2d
......@@ -88,7 +88,7 @@ public class TAutoContractRuleInfo extends BaseEntity {
@Schema(description = "确认签署时间")
private String confirmSignDate;
/**
* 续签合同发起时间类型 0 上一份合同到期前一个月
* 续签合同发起时间类型 0 上一份合同到期前一个月 最新更新为:0 上一份合同到期前第5个工作日 1 上一份合同到期后第10个工作日
*/
@ExcelAttribute(name = "续签合同发起时间类型 ")
@ExcelProperty("续签合同发起时间类型 ")
......
......@@ -276,4 +276,6 @@ public class EmployeeContractVO extends RowIndex implements Serializable {
@Schema(description = "自动化提交人")
@TableField(exist = false)
private String reNewSubmitter;
}
......@@ -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 = "待续签合同超期一个月,需走线下签";
}
......@@ -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));
}
}
......@@ -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);
}
......@@ -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;
}
}
......@@ -399,7 +399,7 @@
a.emp_idcard empIdcard,
a.dept_no deptNo,
a.situation,
a.contract_type contractName,
a.contract_name contractName,
a.CONTRACT_SUB_NAME contractSubName,
null reason,
a.signatory contractParty,
......
......@@ -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,
......
......@@ -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());
}
/**
* 日期月份类型枚举
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment