|
|
@@ -26,6 +26,7 @@ import org.springframework.http.HttpHeaders;
|
|
|
import org.springframework.http.HttpStatus;
|
|
|
import org.springframework.http.MediaType;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.web.client.RestTemplate;
|
|
|
|
|
|
import javax.servlet.ServletOutputStream;
|
|
|
@@ -62,6 +63,7 @@ public class VppContractServiceImpl implements VppContractService {
|
|
|
private final RestTemplate restTemplate = new RestTemplate();
|
|
|
|
|
|
@Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
public Boolean create(VppContractRequestVO vo) {
|
|
|
if (StringUtils.isBlank(vo.getContractNo())) {
|
|
|
throw new BusinessException("合同编号不能为空!");
|
|
|
@@ -69,11 +71,14 @@ public class VppContractServiceImpl implements VppContractService {
|
|
|
VppContractTemplate template = getTemplateById(vo.getTemplateId());
|
|
|
String contractNo = vo.getContractNo().trim();
|
|
|
checkContractNoUnique(contractNo, null);
|
|
|
+ // 关联校验必须在入库前完成,避免失败后留下脏数据导致“合同编号已存在”
|
|
|
+ validateRelatedContract(null, vo.getRelatedContractId(), template);
|
|
|
|
|
|
VppContract contract = new VppContract();
|
|
|
contract.setContractNo(contractNo);
|
|
|
contract.setCustomerId(vo.getCustomerId());
|
|
|
contract.setTemplateId(vo.getTemplateId());
|
|
|
+ contract.setRelatedContractId(vo.getRelatedContractId());
|
|
|
contract.setContractType(vo.getContractType());
|
|
|
contract.setContractName(vo.getContractName());
|
|
|
contract.setPartyA(vo.getPartyA());
|
|
|
@@ -93,13 +98,14 @@ public class VppContractServiceImpl implements VppContractService {
|
|
|
|
|
|
VppAuditHelper.fillCreate(contract);
|
|
|
int insert = vppContractMapper.insert(contract);
|
|
|
- if (insert > 0) {
|
|
|
- bindRelatedContract(contract, vo.getRelatedContractId(), template, null);
|
|
|
+ if (insert > 0 && vo.getRelatedContractId() != null) {
|
|
|
+ syncPeerRelated(contract.getId(), vo.getRelatedContractId(), null);
|
|
|
}
|
|
|
return insert > 0;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
public Boolean update(VppContractRequestVO vo) {
|
|
|
if (vo.getId() == null) {
|
|
|
throw new BusinessException("主键ID不能为空!");
|
|
|
@@ -177,11 +183,19 @@ public class VppContractServiceImpl implements VppContractService {
|
|
|
existingRecord.setContractStatus(VppContractStatusHelper.resolveForPersist(
|
|
|
requestedStatus, existingRecord.getEffectiveDate(), existingRecord.getExpireDate()));
|
|
|
|
|
|
+ // 关联变更:入库前先校验;写入 relatedContractId 后同步对端
|
|
|
+ boolean relatedChanged = vo.getRelatedContractId() != null
|
|
|
+ && !Objects.equals(vo.getRelatedContractId(), previousRelatedId);
|
|
|
+ if (relatedChanged) {
|
|
|
+ VppContractTemplate template = getTemplateById(existingRecord.getTemplateId());
|
|
|
+ validateRelatedContract(existingRecord.getId(), vo.getRelatedContractId(), template);
|
|
|
+ existingRecord.setRelatedContractId(vo.getRelatedContractId());
|
|
|
+ }
|
|
|
+
|
|
|
VppAuditHelper.fillUpdate(existingRecord);
|
|
|
int result = vppContractMapper.updateById(existingRecord);
|
|
|
- if (result > 0 && vo.getRelatedContractId() != null) {
|
|
|
- VppContractTemplate template = getTemplateById(existingRecord.getTemplateId());
|
|
|
- bindRelatedContract(existingRecord, vo.getRelatedContractId(), template, previousRelatedId);
|
|
|
+ if (result > 0 && relatedChanged) {
|
|
|
+ syncPeerRelated(existingRecord.getId(), vo.getRelatedContractId(), previousRelatedId);
|
|
|
}
|
|
|
return result > 0;
|
|
|
}
|
|
|
@@ -445,14 +459,13 @@ public class VppContractServiceImpl implements VppContractService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 居间/普通一对一双向关联
|
|
|
+ * 关联校验(入库前调用):跨类、一对一占用、不能关联自身
|
|
|
*/
|
|
|
- private void bindRelatedContract(VppContract self, Long relatedId,
|
|
|
- VppContractTemplate selfTemplate, Long previousRelatedId) {
|
|
|
+ private void validateRelatedContract(Long selfId, Long relatedId, VppContractTemplate selfTemplate) {
|
|
|
if (relatedId == null) {
|
|
|
return;
|
|
|
}
|
|
|
- if (self.getId() != null && relatedId.equals(self.getId())) {
|
|
|
+ if (selfId != null && relatedId.equals(selfId)) {
|
|
|
throw new BusinessException("不能关联合同自身!");
|
|
|
}
|
|
|
if (selfTemplate == null || selfTemplate.getTemplateKind() == null) {
|
|
|
@@ -476,29 +489,36 @@ public class VppContractServiceImpl implements VppContractService {
|
|
|
throw new BusinessException("仅允许居间合同与普通合同互相一对一关联!");
|
|
|
}
|
|
|
|
|
|
- // 目标合同已被其他合同占用
|
|
|
if (related.getRelatedContractId() != null
|
|
|
- && self.getId() != null
|
|
|
- && !related.getRelatedContractId().equals(self.getId())) {
|
|
|
+ && (selfId == null || !related.getRelatedContractId().equals(selfId))) {
|
|
|
throw new BusinessException("目标合同已被其他合同关联,请先解除原关联!");
|
|
|
}
|
|
|
Integer occupied = vppContractMapper.selectCount(new LambdaQueryWrapper<VppContract>()
|
|
|
.eq(VppContract::getRelatedContractId, relatedId)
|
|
|
.eq(VppContract::getDeleteFlag, 0)
|
|
|
- .ne(self.getId() != null, VppContract::getId, self.getId()));
|
|
|
+ .ne(selfId != null, VppContract::getId, selfId));
|
|
|
if (occupied != null && occupied > 0) {
|
|
|
throw new BusinessException("目标合同已被其他合同关联,请先解除原关联!");
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
+ /**
|
|
|
+ * 同步对端一对一关联(调用前须已完成 validateRelatedContract)
|
|
|
+ */
|
|
|
+ private void syncPeerRelated(Long selfId, Long relatedId, Long previousRelatedId) {
|
|
|
if (previousRelatedId != null && !previousRelatedId.equals(relatedId)) {
|
|
|
- clearRelatedLink(self.getId(), previousRelatedId);
|
|
|
+ clearRelatedLink(selfId, previousRelatedId);
|
|
|
}
|
|
|
-
|
|
|
- self.setRelatedContractId(relatedId);
|
|
|
- VppAuditHelper.fillUpdate(self);
|
|
|
- vppContractMapper.updateById(self);
|
|
|
-
|
|
|
- related.setRelatedContractId(self.getId());
|
|
|
+ if (relatedId == null || selfId == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ VppContract related = vppContractMapper.selectOne(new LambdaQueryWrapper<VppContract>()
|
|
|
+ .eq(VppContract::getId, relatedId)
|
|
|
+ .eq(VppContract::getDeleteFlag, 0));
|
|
|
+ if (related == null) {
|
|
|
+ throw new BusinessException("关联合同不存在或已被删除!");
|
|
|
+ }
|
|
|
+ related.setRelatedContractId(selfId);
|
|
|
VppAuditHelper.fillUpdate(related);
|
|
|
vppContractMapper.updateById(related);
|
|
|
}
|