合同复制
This commit is contained in:
@@ -118,6 +118,21 @@ public class ContractLaunchController {
|
|||||||
return R.success(contractLaunchService.updateDraft(contract));
|
return R.success(contractLaunchService.updateDraft(contract));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制合同并生成新草稿。
|
||||||
|
*
|
||||||
|
* 业务设计:
|
||||||
|
* 1. 允许从任意未删除合同复制出一份新的草稿,方便高频复用历史合同
|
||||||
|
* 2. 保留主信息、合同方、正文附件、履行计划等业务内容
|
||||||
|
* 3. 重置系统编号、合同编号、审批/签署/归档状态与相关痕迹,避免串流程数据
|
||||||
|
*
|
||||||
|
* 对应前端功能:列表页 → 复制合同
|
||||||
|
*/
|
||||||
|
@PostMapping("/{id}/copy")
|
||||||
|
public R<ContractLaunchDto> copyDraft(@PathVariable("id") Long id) {
|
||||||
|
return R.success(contractLaunchService.copyDraft(id));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提交法务审批。
|
* 提交法务审批。
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ public interface ContractLaunchService {
|
|||||||
/** 编辑合同草稿 */
|
/** 编辑合同草稿 */
|
||||||
ContractLaunchDto updateDraft(ContractLaunchDto contract);
|
ContractLaunchDto updateDraft(ContractLaunchDto contract);
|
||||||
|
|
||||||
|
/** 复制合同并生成新的草稿 */
|
||||||
|
ContractLaunchDto copyDraft(Long id);
|
||||||
|
|
||||||
/** 提交法务审批(调用结算平台 pushContract 接口) */
|
/** 提交法务审批(调用结算平台 pushContract 接口) */
|
||||||
ContractLaunchDto submitToLaw(Long id);
|
ContractLaunchDto submitToLaw(Long id);
|
||||||
|
|
||||||
|
|||||||
+210
-25
@@ -92,31 +92,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
|
|||||||
SysUserEntity currentUser = adminSecurityManage.getUser();
|
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||||
normalizeContract(contract);
|
normalizeContract(contract);
|
||||||
validateDraft(contract);
|
validateDraft(contract);
|
||||||
|
return persistDraft(contract, currentUser, false, ContractLaunchConstants.ACTION_SAVE, "保存草稿", "合同草稿创建成功");
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
contract.setId(contractLaunchMapper.selectMainSeqNextVal());
|
|
||||||
contract.setContractSysId(ContractLaunchCodeUtils.buildContractSysId());
|
|
||||||
if (contract.getContractCode() == null || contract.getContractCode().isBlank()) {
|
|
||||||
contract.setContractCode(ContractLaunchCodeUtils.buildContractCode(contract.getContractTypeCode()));
|
|
||||||
}
|
|
||||||
contract.setContractSource(contract.getContractSource() == null || contract.getContractSource().isBlank() ? "ECP" : contract.getContractSource());
|
|
||||||
contract.setStatus(ContractLaunchConstants.STATUS_DRAFT);
|
|
||||||
contract.setApproveStatus(ContractLaunchConstants.APPROVE_STATUS_PENDING);
|
|
||||||
contract.setInitiator(currentUser.getUsername());
|
|
||||||
contract.setInitiatorDept(currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getOrgName());
|
|
||||||
contract.setCompanyName(currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getOrgName());
|
|
||||||
contract.setOrgId(currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getId());
|
|
||||||
contract.setCreatorPhone(currentUser.getMobilePhone());
|
|
||||||
contract.setCreateBy(currentUser.getUsername());
|
|
||||||
contract.setCreateTime(now);
|
|
||||||
contract.setUpdateBy(currentUser.getUsername());
|
|
||||||
contract.setUpdateTime(now);
|
|
||||||
contract.setIsDeleted(ContractLaunchConstants.IS_DELETED_NO);
|
|
||||||
contract.setQueryScope("personal");
|
|
||||||
contractLaunchMapper.insertContract(contract);
|
|
||||||
saveChildren(contract, currentUser.getUsername());
|
|
||||||
insertLog(contract.getId(), ContractLaunchConstants.ACTION_SAVE, "保存草稿", ContractLaunchConstants.ACTION_STATUS_SUCCESS, "合同草稿创建成功", null, currentUser);
|
|
||||||
return getDetail(contract.getId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -163,6 +139,25 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
|
|||||||
return getDetail(contract.getId());
|
return getDetail(contract.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制合同并生成新草稿。
|
||||||
|
*
|
||||||
|
* 复制策略:
|
||||||
|
* 1. 复制主信息、合同方、正文/签订依据/其他附件、履行计划
|
||||||
|
* 2. 重置系统主键、合同系统号、合同编号、流程状态、审批信息、签署信息、归档信息
|
||||||
|
* 3. 不复制日志,也不复制 signed/archive 分类文件
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public ContractLaunchDto copyDraft(Long id) {
|
||||||
|
ContractLaunchDto source = getDetail(id);
|
||||||
|
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||||
|
ContractLaunchDto copiedContract = buildCopiedDraft(source);
|
||||||
|
normalizeContract(copiedContract);
|
||||||
|
validateDraft(copiedContract);
|
||||||
|
return persistDraft(copiedContract, currentUser, true, ContractLaunchConstants.ACTION_COPY, "复制合同", "合同复制成功,已生成新草稿");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提交法务审批。
|
* 提交法务审批。
|
||||||
*
|
*
|
||||||
@@ -505,6 +500,196 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
|
|||||||
insertLog(id, ContractLaunchConstants.ACTION_DELETE, "删除合同", ContractLaunchConstants.ACTION_STATUS_SUCCESS, "合同已逻辑删除", null, currentUser);
|
insertLog(id, ContractLaunchConstants.ACTION_DELETE, "删除合同", ContractLaunchConstants.ACTION_STATUS_SUCCESS, "合同已逻辑删除", null, currentUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ContractLaunchDto persistDraft(ContractLaunchDto contract,
|
||||||
|
SysUserEntity currentUser,
|
||||||
|
boolean forceGenerateContractCode,
|
||||||
|
String actionType,
|
||||||
|
String actionName,
|
||||||
|
String actionContent) {
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
contract.setId(contractLaunchMapper.selectMainSeqNextVal());
|
||||||
|
contract.setContractSysId(ContractLaunchCodeUtils.buildContractSysId());
|
||||||
|
if (forceGenerateContractCode || contract.getContractCode() == null || contract.getContractCode().isBlank()) {
|
||||||
|
contract.setContractCode(ContractLaunchCodeUtils.buildContractCode(contract.getContractTypeCode()));
|
||||||
|
}
|
||||||
|
contract.setContractSource(contract.getContractSource() == null || contract.getContractSource().isBlank() ? "ECP" : contract.getContractSource());
|
||||||
|
contract.setStatus(ContractLaunchConstants.STATUS_DRAFT);
|
||||||
|
contract.setApproveStatus(ContractLaunchConstants.APPROVE_STATUS_PENDING);
|
||||||
|
contract.setApproveMessage(null);
|
||||||
|
contract.setInitiator(currentUser.getUsername());
|
||||||
|
contract.setInitiatorDept(currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getOrgName());
|
||||||
|
contract.setCompanyName(currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getOrgName());
|
||||||
|
contract.setOrgId(currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getId());
|
||||||
|
contract.setCreatorPhone(currentUser.getMobilePhone());
|
||||||
|
contract.setCreateBy(currentUser.getUsername());
|
||||||
|
contract.setCreateTime(now);
|
||||||
|
contract.setUpdateBy(currentUser.getUsername());
|
||||||
|
contract.setUpdateTime(now);
|
||||||
|
contract.setIsDeleted(ContractLaunchConstants.IS_DELETED_NO);
|
||||||
|
contract.setQueryScope("personal");
|
||||||
|
contractLaunchMapper.insertContract(contract);
|
||||||
|
saveChildren(contract, currentUser.getUsername());
|
||||||
|
insertLog(contract.getId(), actionType, actionName, ContractLaunchConstants.ACTION_STATUS_SUCCESS, actionContent, null, currentUser);
|
||||||
|
return getDetail(contract.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContractLaunchDto buildCopiedDraft(ContractLaunchDto source) {
|
||||||
|
ContractLaunchDto target = new ContractLaunchDto();
|
||||||
|
target.setContractName(buildCopiedContractName(source.getContractName()));
|
||||||
|
target.setContractType(source.getContractType());
|
||||||
|
target.setContractTypeCode(source.getContractTypeCode());
|
||||||
|
target.setContractSource(source.getContractSource());
|
||||||
|
target.setCreationMode(source.getCreationMode());
|
||||||
|
target.setTemplateId(source.getTemplateId());
|
||||||
|
target.setTemplateCode(source.getTemplateCode());
|
||||||
|
target.setTemplateName(source.getTemplateName());
|
||||||
|
target.setContractAmount(source.getContractAmount());
|
||||||
|
target.setCurrencyName(source.getCurrencyName());
|
||||||
|
target.setContractPeriodType(source.getContractPeriodType());
|
||||||
|
target.setPeriodExplain(source.getPeriodExplain());
|
||||||
|
target.setEffectiveStart(source.getEffectiveStart());
|
||||||
|
target.setEffectiveEnd(source.getEffectiveEnd());
|
||||||
|
target.setPaymentMethod(source.getPaymentMethod());
|
||||||
|
target.setPrimaryContent(source.getPrimaryContent());
|
||||||
|
target.setAmountExplain(source.getAmountExplain());
|
||||||
|
target.setValuationMode(source.getValuationMode());
|
||||||
|
target.setSealType(source.getSealType());
|
||||||
|
target.setTextSource(source.getTextSource());
|
||||||
|
target.setMandateType(source.getMandateType());
|
||||||
|
target.setCargoType(source.getCargoType());
|
||||||
|
target.setAssistDepartmentName(source.getAssistDepartmentName());
|
||||||
|
target.setExecutorAccount(source.getExecutorAccount());
|
||||||
|
target.setSelfCode(source.getSelfCode());
|
||||||
|
target.setMainContractCode(source.getMainContractCode());
|
||||||
|
target.setSigningSubjectCode(source.getSigningSubjectCode());
|
||||||
|
target.setDateType(source.getDateType());
|
||||||
|
target.setIsAddit(source.getIsAddit());
|
||||||
|
target.setIsElectron(source.getIsElectron());
|
||||||
|
target.setPaymentDirection(source.getPaymentDirection());
|
||||||
|
target.setPushUrl(source.getPushUrl());
|
||||||
|
target.setIsMajorContract(source.getIsMajorContract());
|
||||||
|
target.setIsOpenBidding(source.getIsOpenBidding());
|
||||||
|
target.setIsYearBudget(source.getIsYearBudget());
|
||||||
|
target.setIsShare(source.getIsShare());
|
||||||
|
target.setContractNature(source.getContractNature());
|
||||||
|
target.setIsSgat(source.getIsSgat());
|
||||||
|
target.setIsNormal(source.getIsNormal());
|
||||||
|
target.setIsTerminated(null);
|
||||||
|
target.setIsSingleAgreement(source.getIsSingleAgreement());
|
||||||
|
target.setBiddingNo(source.getBiddingNo());
|
||||||
|
target.setOpenBiddingRemark(source.getOpenBiddingRemark());
|
||||||
|
target.setContractGistRemark(source.getContractGistRemark());
|
||||||
|
target.setEwAmountType(source.getEwAmountType());
|
||||||
|
target.setDjAmount(source.getDjAmount());
|
||||||
|
target.setYjAmount(source.getYjAmount());
|
||||||
|
target.setYfkAmount(source.getYfkAmount());
|
||||||
|
target.setBzjAmount(source.getBzjAmount());
|
||||||
|
target.setBodySummary(source.getBodySummary());
|
||||||
|
target.setTemplateFieldValuesJson(source.getTemplateFieldValuesJson());
|
||||||
|
target.setContractTextFileName(source.getContractTextFileName());
|
||||||
|
target.setContractTextFilePath(source.getContractTextFilePath());
|
||||||
|
target.setContractTextFileType(source.getContractTextFileType());
|
||||||
|
target.setContractTextFileSize(source.getContractTextFileSize());
|
||||||
|
target.setSignDate(source.getSignDate());
|
||||||
|
target.setActiveDate(source.getActiveDate());
|
||||||
|
target.setInvoiceDate(source.getInvoiceDate());
|
||||||
|
target.setReceiveDate(source.getReceiveDate());
|
||||||
|
target.setRemindDays(source.getRemindDays());
|
||||||
|
target.setRemark(source.getRemark());
|
||||||
|
target.setPartyList(copyPartyList(source.getPartyList()));
|
||||||
|
target.setFileList(copyFileList(source.getFileList()));
|
||||||
|
target.setPerformancePlans(copyPlanList(source.getPerformancePlans()));
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildCopiedContractName(String sourceName) {
|
||||||
|
String baseName = trim(sourceName);
|
||||||
|
if (baseName == null || baseName.isBlank()) {
|
||||||
|
return "复制合同";
|
||||||
|
}
|
||||||
|
if (baseName.endsWith("-副本")) {
|
||||||
|
return baseName;
|
||||||
|
}
|
||||||
|
return baseName + "-副本";
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ContractLaunchPartyDto> copyPartyList(List<ContractLaunchPartyDto> sourceList) {
|
||||||
|
if (sourceList == null || sourceList.isEmpty()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
List<ContractLaunchPartyDto> targetList = new ArrayList<>();
|
||||||
|
for (ContractLaunchPartyDto source : sourceList) {
|
||||||
|
ContractLaunchPartyDto target = new ContractLaunchPartyDto();
|
||||||
|
target.setRoleCode(source.getRoleCode());
|
||||||
|
target.setRoleName(source.getRoleName());
|
||||||
|
target.setPartnerId(source.getPartnerId());
|
||||||
|
target.setOppositeId(source.getOppositeId());
|
||||||
|
target.setCompanyName(source.getCompanyName());
|
||||||
|
target.setCompanyType(source.getCompanyType());
|
||||||
|
target.setOppositeCharacter(source.getOppositeCharacter());
|
||||||
|
target.setContactName(source.getContactName());
|
||||||
|
target.setContactPhone(source.getContactPhone());
|
||||||
|
target.setContactEmail(source.getContactEmail());
|
||||||
|
target.setContactAddress(source.getContactAddress());
|
||||||
|
target.setRegisteredAddress(source.getRegisteredAddress());
|
||||||
|
target.setLegalRepresentative(source.getLegalRepresentative());
|
||||||
|
target.setCreditCode(source.getCreditCode());
|
||||||
|
target.setBankName(source.getBankName());
|
||||||
|
target.setBankAccount(source.getBankAccount());
|
||||||
|
target.setNaturalPersonIdType(source.getNaturalPersonIdType());
|
||||||
|
target.setNaturalPersonIdNumber(source.getNaturalPersonIdNumber());
|
||||||
|
target.setIsGroupInternal(source.getIsGroupInternal());
|
||||||
|
target.setIsHongKongMacaoTaiwan(source.getIsHongKongMacaoTaiwan());
|
||||||
|
target.setRemark(source.getRemark());
|
||||||
|
targetList.add(target);
|
||||||
|
}
|
||||||
|
return targetList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ContractLaunchFileDto> copyFileList(List<ContractLaunchFileDto> sourceList) {
|
||||||
|
if (sourceList == null || sourceList.isEmpty()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
List<ContractLaunchFileDto> targetList = new ArrayList<>();
|
||||||
|
for (ContractLaunchFileDto source : sourceList) {
|
||||||
|
if (ContractLaunchConstants.FILE_CATEGORY_SIGNED.equals(source.getFileCategory())
|
||||||
|
|| ContractLaunchConstants.FILE_CATEGORY_ARCHIVE.equals(source.getFileCategory())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ContractLaunchFileDto target = new ContractLaunchFileDto();
|
||||||
|
target.setFileCategory(source.getFileCategory());
|
||||||
|
target.setFileName(source.getFileName());
|
||||||
|
target.setFilePath(source.getFilePath());
|
||||||
|
target.setFileType(source.getFileType());
|
||||||
|
target.setFileSize(source.getFileSize());
|
||||||
|
target.setRemark(source.getRemark());
|
||||||
|
targetList.add(target);
|
||||||
|
}
|
||||||
|
return targetList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ContractLaunchPlanDto> copyPlanList(List<ContractLaunchPlanDto> sourceList) {
|
||||||
|
if (sourceList == null || sourceList.isEmpty()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
List<ContractLaunchPlanDto> targetList = new ArrayList<>();
|
||||||
|
for (ContractLaunchPlanDto source : sourceList) {
|
||||||
|
ContractLaunchPlanDto target = new ContractLaunchPlanDto();
|
||||||
|
target.setPlanMatter(source.getPlanMatter());
|
||||||
|
target.setPlanWhere(source.getPlanWhere());
|
||||||
|
target.setPlanTime(source.getPlanTime());
|
||||||
|
target.setPlanDay(source.getPlanDay());
|
||||||
|
target.setPlanMoney(source.getPlanMoney());
|
||||||
|
target.setPlanSubjectCode(source.getPlanSubjectCode());
|
||||||
|
target.setPlanSubjectName(source.getPlanSubjectName());
|
||||||
|
target.setPlanDetail(source.getPlanDetail());
|
||||||
|
target.setPlanStatus("0");
|
||||||
|
target.setRemark(source.getRemark());
|
||||||
|
targetList.add(target);
|
||||||
|
}
|
||||||
|
return targetList;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量填充子表数据(合同方/文件/履行计划/日志)。
|
* 批量填充子表数据(合同方/文件/履行计划/日志)。
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ public final class ContractLaunchConstants {
|
|||||||
public static final String ACTION_COLLECT = "collect";
|
public static final String ACTION_COLLECT = "collect";
|
||||||
public static final String ACTION_ARCHIVE = "archive";
|
public static final String ACTION_ARCHIVE = "archive";
|
||||||
public static final String ACTION_DELETE = "delete";
|
public static final String ACTION_DELETE = "delete";
|
||||||
|
public static final String ACTION_COPY = "copy";
|
||||||
|
|
||||||
public static final String ACTION_STATUS_SUCCESS = "success";
|
public static final String ACTION_STATUS_SUCCESS = "success";
|
||||||
public static final String ACTION_STATUS_FAILED = "failed";
|
public static final String ACTION_STATUS_FAILED = "failed";
|
||||||
|
|||||||
Reference in New Issue
Block a user