|
|
|
|
@ -1,8 +1,11 @@
|
|
|
|
|
package org.dromara.oa.erp.service.impl;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.convert.Convert;
|
|
|
|
|
import cn.hutool.core.map.MapUtil;
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.dromara.common.core.enums.BusinessStatusEnum;
|
|
|
|
|
import org.dromara.common.core.enums.OAStatusEnum;
|
|
|
|
|
import org.dromara.common.tenant.helper.TenantHelper;
|
|
|
|
|
import org.dromara.oa.erp.domain.bo.ErpContractChangeMaterialBo;
|
|
|
|
|
import org.dromara.oa.erp.domain.bo.ErpContractChangePaymentMethodBo;
|
|
|
|
|
@ -25,24 +28,34 @@ import org.dromara.oa.erp.domain.vo.*;
|
|
|
|
|
import org.dromara.oa.erp.mapper.*;
|
|
|
|
|
import org.dromara.oa.erp.service.IErpContractChangeService;
|
|
|
|
|
import org.dromara.system.api.RemoteCodeRuleService;
|
|
|
|
|
import org.dromara.workflow.api.RemoteWorkflowService;
|
|
|
|
|
import org.dromara.workflow.api.domain.RemoteStartProcess;
|
|
|
|
|
import org.dromara.common.core.exception.ServiceException;
|
|
|
|
|
import org.apache.seata.spring.annotation.GlobalTransactional;
|
|
|
|
|
|
|
|
|
|
import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
|
|
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Objects;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 合同变更Service业务层处理
|
|
|
|
|
* 合同变更 Service 业务层实现。
|
|
|
|
|
* <p>
|
|
|
|
|
* 职责:合同变更主表及子表(变更信息快照、物料快照、付款方式快照)的增删改查、
|
|
|
|
|
* 保存/提交并发起审批流程、审批通过后回写原合同及流程状态同步。
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* 删除说明:本类中所有删除均为逻辑删除。依赖实体上的 {@code @TableLogic},Mapper 的 delete 会转换为 UPDATE del_flag,不物理删行。
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @author Yinq
|
|
|
|
|
* @date 2026-03-07
|
|
|
|
|
*/
|
|
|
|
|
@RequiredArgsConstructor
|
|
|
|
|
@Service
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
|
|
|
|
|
// ---------- 主表及子表 Mapper ----------
|
|
|
|
|
private final ErpContractChangeMapper baseMapper;
|
|
|
|
|
private final ErpContractChangeInfoMapper changeInfoMapper;
|
|
|
|
|
private final ErpContractChangeMaterialMapper changeMaterialMapper;
|
|
|
|
|
@ -54,50 +67,55 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
@DubboReference
|
|
|
|
|
private RemoteCodeRuleService remoteCodeRuleService;
|
|
|
|
|
|
|
|
|
|
/** 合同变更流程编码 */
|
|
|
|
|
@DubboReference(timeout = 30000)
|
|
|
|
|
private RemoteWorkflowService remoteWorkflowService;
|
|
|
|
|
|
|
|
|
|
/** 合同变更流程定义编码(与流程引擎中 flowCode 一致) */
|
|
|
|
|
public static final String FLOW_CODE_CONTRACT_CHANGE = "HTBG";
|
|
|
|
|
/** 变更编号编码规则 */
|
|
|
|
|
/** 变更单编号规则编码(调用编码规则服务生成变更编号) */
|
|
|
|
|
private static final String CONTRACT_CHANGE_CODE_RULE = "1021";
|
|
|
|
|
|
|
|
|
|
/** 变更类型:1内容变更 2解除合同 */
|
|
|
|
|
/** 变更类型:1-内容变更(需维护变更后信息/物料/付款方式快照) */
|
|
|
|
|
private static final String CHANGE_TYPE_CONTENT = "1";
|
|
|
|
|
/** 变更类型:2-解除合同(仅更新原合同激活标识) */
|
|
|
|
|
private static final String CHANGE_TYPE_TERMINATE = "2";
|
|
|
|
|
/** 未回写 */
|
|
|
|
|
/** 回写标识:0-未回写 */
|
|
|
|
|
private static final String WRITE_BACK_NO = "0";
|
|
|
|
|
/** 已回写/可用 */
|
|
|
|
|
/** 回写标识:1-已回写(审批通过并已写回原合同后不再允许修改回写相关字段) */
|
|
|
|
|
private static final String WRITE_BACK_YES = "1";
|
|
|
|
|
/** 变更状态:3-可用(审批完成且已回写后的终态) */
|
|
|
|
|
private static final String CHANGE_STATUS_AVAILABLE = "3";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 查询合同变更
|
|
|
|
|
* 根据主键查询合同变更(仅主表)
|
|
|
|
|
*
|
|
|
|
|
* @param contractChangeId 主键
|
|
|
|
|
* @return 合同变更
|
|
|
|
|
* @return 合同变更 VO,不存在则 null
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ErpContractChangeVo queryById(Long contractChangeId){
|
|
|
|
|
public ErpContractChangeVo queryById(Long contractChangeId) {
|
|
|
|
|
return baseMapper.selectVoById(contractChangeId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 分页查询合同变更列表
|
|
|
|
|
*
|
|
|
|
|
* @param bo 查询条件
|
|
|
|
|
* @param pageQuery 分页参数
|
|
|
|
|
* @return 合同变更分页列表
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public TableDataInfo<ErpContractChangeVo> queryPageList(ErpContractChangeBo bo, PageQuery pageQuery) {
|
|
|
|
|
MPJLambdaWrapper<ErpContractChange> lqw = buildQueryWrapper(bo);
|
|
|
|
|
Page<ErpContractChangeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
|
|
|
|
return TableDataInfo.build(result);
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 分页查询合同变更列表(条件同 queryList,带分页)
|
|
|
|
|
*
|
|
|
|
|
* @param bo 查询条件
|
|
|
|
|
* @param pageQuery 分页参数
|
|
|
|
|
* @return 分页结果
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public TableDataInfo<ErpContractChangeVo> queryPageList(ErpContractChangeBo bo, PageQuery pageQuery) {
|
|
|
|
|
MPJLambdaWrapper<ErpContractChange> lqw = buildQueryWrapper(bo);
|
|
|
|
|
Page<ErpContractChangeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
|
|
|
|
return TableDataInfo.build(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 查询符合条件的合同变更列表
|
|
|
|
|
* 根据条件查询合同变更列表(不分页,用于下拉等)
|
|
|
|
|
*
|
|
|
|
|
* @param bo 查询条件
|
|
|
|
|
* @return 合同变更列表
|
|
|
|
|
* @return 列表,未逻辑删除的数据
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public List<ErpContractChangeVo> queryList(ErpContractChangeBo bo) {
|
|
|
|
|
@ -105,38 +123,43 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
return baseMapper.selectVoList(lqw);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构建列表/分页查询条件:仅查未删除,其余条件按 bo 非空字段等值/模糊匹配
|
|
|
|
|
*/
|
|
|
|
|
private MPJLambdaWrapper<ErpContractChange> buildQueryWrapper(ErpContractChangeBo bo) {
|
|
|
|
|
return JoinWrappers.lambda(ErpContractChange.class)
|
|
|
|
|
.selectAll(ErpContractChange.class)
|
|
|
|
|
.eq(ErpContractChange::getDelFlag, "0")
|
|
|
|
|
.eq(bo.getContractId() != null, ErpContractChange::getContractId, bo.getContractId())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getChangeCode()), ErpContractChange::getChangeCode, bo.getChangeCode())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getChangeType()), ErpContractChange::getChangeType, bo.getChangeType())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getChangeContractCode()), ErpContractChange::getChangeContractCode, bo.getChangeContractCode())
|
|
|
|
|
.like(StringUtils.isNotBlank(bo.getChangeContractName()), ErpContractChange::getChangeContractName, bo.getChangeContractName())
|
|
|
|
|
.like(StringUtils.isNotBlank(bo.getCustomerName()), ErpContractChange::getCustomerName, bo.getCustomerName())
|
|
|
|
|
.eq(bo.getChangeContractAmount() != null, ErpContractChange::getChangeContractAmount, bo.getChangeContractAmount())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getContractCode()), ErpContractChange::getContractCode, bo.getContractCode())
|
|
|
|
|
.like(StringUtils.isNotBlank(bo.getContractName()), ErpContractChange::getContractName, bo.getContractName())
|
|
|
|
|
.like(StringUtils.isNotBlank(bo.getOriginalCustomerName()), ErpContractChange::getOriginalCustomerName, bo.getOriginalCustomerName())
|
|
|
|
|
.eq(bo.getOriginalContractAmount() != null, ErpContractChange::getOriginalContractAmount, bo.getOriginalContractAmount())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getChangeReason()), ErpContractChange::getChangeReason, bo.getChangeReason())
|
|
|
|
|
.eq(bo.getApplyTime() != null, ErpContractChange::getApplyTime, bo.getApplyTime())
|
|
|
|
|
.eq(bo.getUndertakeDeptId() != null, ErpContractChange::getUndertakeDeptId, bo.getUndertakeDeptId())
|
|
|
|
|
.eq(bo.getUndertakeBy() != null, ErpContractChange::getUndertakeBy, bo.getUndertakeBy())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getIndustryRegion()), ErpContractChange::getIndustryRegion, bo.getIndustryRegion())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getSealLegalEntity()), ErpContractChange::getSealLegalEntity, bo.getSealLegalEntity())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getChangeStatus()), ErpContractChange::getChangeStatus, bo.getChangeStatus())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpContractChange::getFlowStatus, bo.getFlowStatus())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getWriteBackFlag()), ErpContractChange::getWriteBackFlag, bo.getWriteBackFlag())
|
|
|
|
|
.eq(bo.getWriteBackTime() != null, ErpContractChange::getWriteBackTime, bo.getWriteBackTime())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpContractChange::getActiveFlag, bo.getActiveFlag());
|
|
|
|
|
.selectAll(ErpContractChange.class)
|
|
|
|
|
.eq(ErpContractChange::getDelFlag, "0")
|
|
|
|
|
.eq(bo.getContractId() != null, ErpContractChange::getContractId, bo.getContractId())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getChangeCode()), ErpContractChange::getChangeCode, bo.getChangeCode())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getChangeType()), ErpContractChange::getChangeType, bo.getChangeType())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getChangeContractCode()), ErpContractChange::getChangeContractCode, bo.getChangeContractCode())
|
|
|
|
|
.like(StringUtils.isNotBlank(bo.getChangeContractName()), ErpContractChange::getChangeContractName, bo.getChangeContractName())
|
|
|
|
|
.like(StringUtils.isNotBlank(bo.getCustomerName()), ErpContractChange::getCustomerName, bo.getCustomerName())
|
|
|
|
|
.eq(bo.getChangeContractAmount() != null, ErpContractChange::getChangeContractAmount, bo.getChangeContractAmount())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getContractCode()), ErpContractChange::getContractCode, bo.getContractCode())
|
|
|
|
|
.like(StringUtils.isNotBlank(bo.getContractName()), ErpContractChange::getContractName, bo.getContractName())
|
|
|
|
|
.like(StringUtils.isNotBlank(bo.getOriginalCustomerName()), ErpContractChange::getOriginalCustomerName, bo.getOriginalCustomerName())
|
|
|
|
|
.eq(bo.getOriginalContractAmount() != null, ErpContractChange::getOriginalContractAmount, bo.getOriginalContractAmount())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getChangeReason()), ErpContractChange::getChangeReason, bo.getChangeReason())
|
|
|
|
|
.eq(bo.getApplyTime() != null, ErpContractChange::getApplyTime, bo.getApplyTime())
|
|
|
|
|
.eq(bo.getUndertakeDeptId() != null, ErpContractChange::getUndertakeDeptId, bo.getUndertakeDeptId())
|
|
|
|
|
.eq(bo.getUndertakeBy() != null, ErpContractChange::getUndertakeBy, bo.getUndertakeBy())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getIndustryRegion()), ErpContractChange::getIndustryRegion, bo.getIndustryRegion())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getSealLegalEntity()), ErpContractChange::getSealLegalEntity, bo.getSealLegalEntity())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getChangeStatus()), ErpContractChange::getChangeStatus, bo.getChangeStatus())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getFlowStatus()), ErpContractChange::getFlowStatus, bo.getFlowStatus())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getWriteBackFlag()), ErpContractChange::getWriteBackFlag, bo.getWriteBackFlag())
|
|
|
|
|
.eq(bo.getWriteBackTime() != null, ErpContractChange::getWriteBackTime, bo.getWriteBackTime())
|
|
|
|
|
.eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpContractChange::getActiveFlag, bo.getActiveFlag());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ======================= 主表增删改(单表) =======================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 新增合同变更
|
|
|
|
|
* 新增合同变更(仅主表,不包含子表快照)
|
|
|
|
|
*
|
|
|
|
|
* @param bo 合同变更
|
|
|
|
|
* @param bo 合同变更 BO,成功后回写主键到 bo
|
|
|
|
|
* @return 是否新增成功
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
@ -151,9 +174,9 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 修改合同变更
|
|
|
|
|
* 修改合同变更(仅主表)
|
|
|
|
|
*
|
|
|
|
|
* @param bo 合同变更
|
|
|
|
|
* @param bo 合同变更 BO
|
|
|
|
|
* @return 是否修改成功
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
@ -164,7 +187,7 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 保存前的数据校验
|
|
|
|
|
* 保存前校验:原合同ID、变更类型必填(主表与保存接口共用)
|
|
|
|
|
*/
|
|
|
|
|
private void validEntityBeforeSave(ErpContractChange entity) {
|
|
|
|
|
if (entity.getContractId() == null) {
|
|
|
|
|
@ -176,20 +199,34 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 校验并批量删除合同变更信息
|
|
|
|
|
* 按主键批量逻辑删除合同变更(依赖 ErpContractChange 的 @TableLogic,实际执行 UPDATE del_flag)。
|
|
|
|
|
* isValid 为 true 时预留业务校验扩展点。
|
|
|
|
|
*
|
|
|
|
|
* @param ids 待删除的主键集合
|
|
|
|
|
* @param isValid 是否进行有效性校验
|
|
|
|
|
* @param ids 主键集合
|
|
|
|
|
* @param isValid 是否执行有效性校验(当前为预留)
|
|
|
|
|
* @return 是否删除成功
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
|
|
|
|
if(isValid){
|
|
|
|
|
//TODO 做一些业务上的校验,判断是否需要校验
|
|
|
|
|
if (isValid) {
|
|
|
|
|
// TODO 按业务需要补充:如已回写、审批中等不允许删除等
|
|
|
|
|
}
|
|
|
|
|
return baseMapper.deleteByIds(ids) > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ======================= 保存与提交流程 =======================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 保存合同变更(主表 + 内容变更时的信息/物料/付款方式快照),新增与修改统一入口。
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>修改且为「内容变更」时:先物理删除原子表再按 bo 重新插入(保证与前端提交一致)</li>
|
|
|
|
|
* <li>已回写的记录:回写标识与回写时间不允许被覆盖</li>
|
|
|
|
|
* <li>新增时:若未传变更编号则通过编码规则生成</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
*
|
|
|
|
|
* @param bo 主表字段 + changeInfo / changeMaterialList / changePaymentMethodList(内容变更时)
|
|
|
|
|
* @return 合同变更主表主键
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public Long saveContractChange(ErpContractChangeSaveBo bo) {
|
|
|
|
|
@ -198,12 +235,14 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
validEntityBeforeSave(main);
|
|
|
|
|
|
|
|
|
|
if (isUpdate) {
|
|
|
|
|
// 已回写的数据不允许覆盖回写相关字段
|
|
|
|
|
ErpContractChange existing = baseMapper.selectById(main.getContractChangeId());
|
|
|
|
|
if (existing != null && StringUtils.isNotBlank(existing.getWriteBackFlag()) && WRITE_BACK_YES.equals(existing.getWriteBackFlag())) {
|
|
|
|
|
main.setWriteBackFlag(existing.getWriteBackFlag());
|
|
|
|
|
main.setWriteBackTime(existing.getWriteBackTime());
|
|
|
|
|
}
|
|
|
|
|
baseMapper.updateById(main);
|
|
|
|
|
// 内容变更时子表采用「先逻辑删除后新增」,保证与前端提交一致(子表实体带 @TableLogic)
|
|
|
|
|
if (CHANGE_TYPE_CONTENT.equals(bo.getChangeType())) {
|
|
|
|
|
deleteChangeSubByChangeId(main.getContractChangeId());
|
|
|
|
|
}
|
|
|
|
|
@ -217,6 +256,7 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
bo.setChangeCode(main.getChangeCode());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 内容变更时写入/更新:变更信息快照、物料快照、付款方式快照(子表主键置空表示新增)
|
|
|
|
|
if (CHANGE_TYPE_CONTENT.equals(bo.getChangeType())) {
|
|
|
|
|
Long changeId = main.getContractChangeId();
|
|
|
|
|
if (bo.getChangeInfo() != null) {
|
|
|
|
|
@ -245,6 +285,36 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
return main.getContractChangeId();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 提交合同变更并后端发起审批流程(与合同 contractSubmitAndFlowStart 一致)。
|
|
|
|
|
* 先保存再调用流程「启动并完成首节点」,不打开前端提交校验弹窗。
|
|
|
|
|
*
|
|
|
|
|
* @param bo 保存数据 + flowCode、variables、bizExt(流程所需)
|
|
|
|
|
* @return 保存并发起流程后的合同变更主表 VO
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
@GlobalTransactional(rollbackFor = Exception.class)
|
|
|
|
|
public ErpContractChangeVo contractChangeSubmitAndFlowStart(ErpContractChangeSaveBo bo) {
|
|
|
|
|
Long changeId = saveContractChange(bo);
|
|
|
|
|
bo.setContractChangeId(changeId);
|
|
|
|
|
// 后端发起时忽略权限校验
|
|
|
|
|
bo.getVariables().put("ignore", true);
|
|
|
|
|
RemoteStartProcess startProcess = new RemoteStartProcess();
|
|
|
|
|
startProcess.setBusinessId(changeId.toString());
|
|
|
|
|
startProcess.setFlowCode(bo.getFlowCode());
|
|
|
|
|
startProcess.setVariables(bo.getVariables());
|
|
|
|
|
startProcess.setBizExt(bo.getBizExt());
|
|
|
|
|
bo.getBizExt().setBusinessId(startProcess.getBusinessId());
|
|
|
|
|
boolean flag = remoteWorkflowService.startCompleteTask(startProcess);
|
|
|
|
|
if (!flag) {
|
|
|
|
|
throw new ServiceException("流程发起异常");
|
|
|
|
|
}
|
|
|
|
|
return baseMapper.selectVoById(changeId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从 SaveBo 组装主表实体(不包含子表),新增时默认未回写、变更状态 1、激活 1
|
|
|
|
|
*/
|
|
|
|
|
private ErpContractChange buildMainEntity(ErpContractChangeSaveBo bo) {
|
|
|
|
|
ErpContractChange e = new ErpContractChange();
|
|
|
|
|
e.setContractChangeId(bo.getContractChangeId());
|
|
|
|
|
@ -275,15 +345,27 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 按合同变更ID逻辑删除子表:变更信息、变更物料、变更付款方式(保存时「先删后增」用)。
|
|
|
|
|
* 各实体带 @TableLogic,Mapper.delete 实际为 UPDATE del_flag,不物理删行。
|
|
|
|
|
*/
|
|
|
|
|
private void deleteChangeSubByChangeId(Long contractChangeId) {
|
|
|
|
|
changeInfoMapper.delete(new LambdaQueryWrapper<ErpContractChangeInfo>()
|
|
|
|
|
.eq(ErpContractChangeInfo::getContractChangeId, contractChangeId));
|
|
|
|
|
.eq(ErpContractChangeInfo::getContractChangeId, contractChangeId));
|
|
|
|
|
changeMaterialMapper.delete(new LambdaQueryWrapper<ErpContractChangeMaterial>()
|
|
|
|
|
.eq(ErpContractChangeMaterial::getContractChangeId, contractChangeId));
|
|
|
|
|
.eq(ErpContractChangeMaterial::getContractChangeId, contractChangeId));
|
|
|
|
|
changePaymentMethodMapper.delete(new LambdaQueryWrapper<ErpContractChangePaymentMethod>()
|
|
|
|
|
.eq(ErpContractChangePaymentMethod::getContractChangeId, contractChangeId));
|
|
|
|
|
.eq(ErpContractChangePaymentMethod::getContractChangeId, contractChangeId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ======================= 详情与回写 =======================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 查询合同变更详情:主表 + 变更信息快照(单条)+ 物料快照列表 + 付款方式快照列表
|
|
|
|
|
*
|
|
|
|
|
* @param contractChangeId 合同变更主键
|
|
|
|
|
* @return 详情 VO,主表不存在时 main 为 null
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ContractChangeDetailVo queryDetailById(Long contractChangeId) {
|
|
|
|
|
ContractChangeDetailVo vo = new ContractChangeDetailVo();
|
|
|
|
|
@ -292,19 +374,24 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
return vo;
|
|
|
|
|
}
|
|
|
|
|
List<ErpContractChangeInfoVo> infoList = changeInfoMapper.selectVoList(
|
|
|
|
|
new LambdaQueryWrapper<ErpContractChangeInfo>().eq(ErpContractChangeInfo::getContractChangeId, contractChangeId));
|
|
|
|
|
new LambdaQueryWrapper<ErpContractChangeInfo>().eq(ErpContractChangeInfo::getContractChangeId, contractChangeId));
|
|
|
|
|
vo.setChangeInfo(infoList.isEmpty() ? null : infoList.get(0));
|
|
|
|
|
vo.setChangeMaterialList(changeMaterialMapper.selectVoList(
|
|
|
|
|
new LambdaQueryWrapper<ErpContractChangeMaterial>().eq(ErpContractChangeMaterial::getContractChangeId, contractChangeId)));
|
|
|
|
|
new LambdaQueryWrapper<ErpContractChangeMaterial>().eq(ErpContractChangeMaterial::getContractChangeId, contractChangeId)));
|
|
|
|
|
vo.setChangePaymentMethodList(changePaymentMethodMapper.selectVoList(
|
|
|
|
|
new LambdaQueryWrapper<ErpContractChangePaymentMethod>().eq(ErpContractChangePaymentMethod::getContractChangeId, contractChangeId)));
|
|
|
|
|
new LambdaQueryWrapper<ErpContractChangePaymentMethod>().eq(ErpContractChangePaymentMethod::getContractChangeId, contractChangeId)));
|
|
|
|
|
return vo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 审批通过后将变更结果回写至原合同(仅未回写记录执行一次)。
|
|
|
|
|
* 解除合同:将原合同激活标识置为 0;内容变更:用变更快照覆盖原合同信息/物料/付款方式,并更新本变更单状态与回写标识。
|
|
|
|
|
*
|
|
|
|
|
* @param change 合同变更主表实体(需已查库,含 contractId、changeType 等)
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public void writeBackToContract(Long contractChangeId) {
|
|
|
|
|
ErpContractChange change = baseMapper.selectById(contractChangeId);
|
|
|
|
|
public void writeBackToContract(ErpContractChange change) {
|
|
|
|
|
if (change == null || !WRITE_BACK_NO.equals(change.getWriteBackFlag())) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@ -312,7 +399,7 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
if (CHANGE_TYPE_TERMINATE.equals(change.getChangeType())) {
|
|
|
|
|
doWriteBackTerminate(contractId);
|
|
|
|
|
} else {
|
|
|
|
|
doWriteBackContent(contractChangeId, contractId);
|
|
|
|
|
doWriteBackContent(change.getContractChangeId(), contractId);
|
|
|
|
|
}
|
|
|
|
|
change.setChangeStatus(CHANGE_STATUS_AVAILABLE);
|
|
|
|
|
change.setFlowStatus(BusinessStatusEnum.FINISH.getStatus());
|
|
|
|
|
@ -321,6 +408,7 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
baseMapper.updateById(change);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 解除合同回写:将原合同激活标识置为 0 */
|
|
|
|
|
private void doWriteBackTerminate(Long contractId) {
|
|
|
|
|
ErpContractInfo info = contractInfoMapper.selectById(contractId);
|
|
|
|
|
if (info != null) {
|
|
|
|
|
@ -329,9 +417,12 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 内容变更回写:用变更信息快照更新原合同主表;原合同物料/付款方式先逻辑删除后按变更快照插入(逻辑删除,实体带 @TableLogic)。
|
|
|
|
|
*/
|
|
|
|
|
private void doWriteBackContent(Long contractChangeId, Long contractId) {
|
|
|
|
|
List<ErpContractChangeInfoVo> infoList = changeInfoMapper.selectVoList(
|
|
|
|
|
new LambdaQueryWrapper<ErpContractChangeInfo>().eq(ErpContractChangeInfo::getContractChangeId, contractChangeId));
|
|
|
|
|
new LambdaQueryWrapper<ErpContractChangeInfo>().eq(ErpContractChangeInfo::getContractChangeId, contractChangeId));
|
|
|
|
|
if (!infoList.isEmpty()) {
|
|
|
|
|
ErpContractInfo contractInfo = contractInfoMapper.selectById(contractId);
|
|
|
|
|
if (contractInfo != null) {
|
|
|
|
|
@ -339,35 +430,67 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
contractInfoMapper.updateById(contractInfo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 逻辑删除原合同下物料(@TableLogic)
|
|
|
|
|
LambdaQueryWrapper<ErpContractMaterial> materialDel = new LambdaQueryWrapper<ErpContractMaterial>().eq(ErpContractMaterial::getContractId, contractId);
|
|
|
|
|
contractMaterialMapper.delete(materialDel);
|
|
|
|
|
List<ErpContractChangeMaterial> materials = changeMaterialMapper.selectList(
|
|
|
|
|
new LambdaQueryWrapper<ErpContractChangeMaterial>().eq(ErpContractChangeMaterial::getContractChangeId, contractChangeId));
|
|
|
|
|
new LambdaQueryWrapper<ErpContractChangeMaterial>().eq(ErpContractChangeMaterial::getContractChangeId, contractChangeId));
|
|
|
|
|
for (ErpContractChangeMaterial m : materials) {
|
|
|
|
|
contractMaterialMapper.insert(copyChangeMaterialToContract(m, contractId));
|
|
|
|
|
}
|
|
|
|
|
// 逻辑删除原合同下付款方式(@TableLogic)
|
|
|
|
|
LambdaQueryWrapper<ErpContractPaymentMethod> paymentDel = new LambdaQueryWrapper<ErpContractPaymentMethod>().eq(ErpContractPaymentMethod::getContractId, contractId);
|
|
|
|
|
contractPaymentMethodMapper.delete(paymentDel);
|
|
|
|
|
List<ErpContractChangePaymentMethod> payments = changePaymentMethodMapper.selectList(
|
|
|
|
|
new LambdaQueryWrapper<ErpContractChangePaymentMethod>().eq(ErpContractChangePaymentMethod::getContractChangeId, contractChangeId));
|
|
|
|
|
new LambdaQueryWrapper<ErpContractChangePaymentMethod>().eq(ErpContractChangePaymentMethod::getContractChangeId, contractChangeId));
|
|
|
|
|
for (ErpContractChangePaymentMethod p : payments) {
|
|
|
|
|
contractPaymentMethodMapper.insert(copyChangePaymentToContract(p, contractId));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ======================= 流程监听 =======================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 合同变更流程监听:审批通过后回写合同表
|
|
|
|
|
* 合同变更流程事件监听(flowCode=HTBG):根据流程状态同步变更单 flowStatus/changeStatus,审批完成时触发回写。
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li>WAITING -> 审批中</li>
|
|
|
|
|
* <li>FINISH -> 已完成,并执行 writeBackToContract</li>
|
|
|
|
|
* <li>INVALID/TERMINATION -> 无效</li>
|
|
|
|
|
* <li>BACK/CANCEL -> 草稿</li>
|
|
|
|
|
* </ul>
|
|
|
|
|
*/
|
|
|
|
|
@EventListener(condition = "#processEvent.flowCode == T(org.dromara.oa.erp.service.impl.ErpContractChangeServiceImpl).FLOW_CODE_CONTRACT_CHANGE")
|
|
|
|
|
@EventListener(condition = "#processEvent.flowCode =='HTBG'")
|
|
|
|
|
public void processHandler(ProcessEvent processEvent) {
|
|
|
|
|
TenantHelper.dynamic(processEvent.getTenantId(), () -> {
|
|
|
|
|
if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) {
|
|
|
|
|
Long contractChangeId = Convert.toLong(processEvent.getBusinessId());
|
|
|
|
|
writeBackToContract(contractChangeId);
|
|
|
|
|
log.info("当前任务执行了{}", processEvent.toString());
|
|
|
|
|
ErpContractChange contractChange = baseMapper.selectById(Convert.toLong(processEvent.getBusinessId()));
|
|
|
|
|
contractChange.setFlowStatus(processEvent.getStatus());
|
|
|
|
|
Map<String, Object> params = processEvent.getParams();
|
|
|
|
|
if (MapUtil.isNotEmpty(params)) {
|
|
|
|
|
// 预留:办理人等信息可按需从 params 取用
|
|
|
|
|
String handler = Convert.toStr(params.get("handler"));
|
|
|
|
|
}
|
|
|
|
|
if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.WAITING.getStatus())) {
|
|
|
|
|
contractChange.setChangeStatus(OAStatusEnum.APPROVING.getStatus());
|
|
|
|
|
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) {
|
|
|
|
|
contractChange.setChangeStatus(OAStatusEnum.COMPLETED.getStatus());
|
|
|
|
|
writeBackToContract(contractChange);
|
|
|
|
|
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.INVALID.getStatus())
|
|
|
|
|
|| Objects.equals(processEvent.getStatus(), BusinessStatusEnum.TERMINATION.getStatus())) {
|
|
|
|
|
contractChange.setChangeStatus(OAStatusEnum.INVALID.getStatus());
|
|
|
|
|
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.BACK.getStatus())
|
|
|
|
|
|| Objects.equals(processEvent.getStatus(), BusinessStatusEnum.CANCEL.getStatus())) {
|
|
|
|
|
contractChange.setChangeStatus(OAStatusEnum.DRAFT.getStatus());
|
|
|
|
|
}
|
|
|
|
|
baseMapper.updateById(contractChange);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ======================= 回写时的数据拷贝 =======================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 将变更信息快照字段拷贝到原合同主表(回写内容变更时用)
|
|
|
|
|
*/
|
|
|
|
|
private void copyChangeInfoToContract(ErpContractChangeInfoVo snap, ErpContractInfo contract) {
|
|
|
|
|
contract.setContractFlag(snap.getContractFlag());
|
|
|
|
|
contract.setCustomerContractCode(snap.getCustomerContractCode());
|
|
|
|
|
@ -408,7 +531,9 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
contract.setRemark(snap.getRemark());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 变更物料快照转合同物料(回写)*/
|
|
|
|
|
/**
|
|
|
|
|
* 将单条变更物料快照转为原合同下的合同物料实体(回写时插入 erp_contract_material)
|
|
|
|
|
*/
|
|
|
|
|
private ErpContractMaterial copyChangeMaterialToContract(ErpContractChangeMaterial m, Long contractId) {
|
|
|
|
|
ErpContractMaterial cm = new ErpContractMaterial();
|
|
|
|
|
cm.setContractId(contractId);
|
|
|
|
|
@ -429,7 +554,9 @@ public class ErpContractChangeServiceImpl implements IErpContractChangeService {
|
|
|
|
|
return cm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 变更付款方式快照转合同付款方式(回写) */
|
|
|
|
|
/**
|
|
|
|
|
* 将单条变更付款方式快照转为原合同下的合同付款方式实体(回写时插入 erp_contract_payment_method)
|
|
|
|
|
*/
|
|
|
|
|
private ErpContractPaymentMethod copyChangePaymentToContract(ErpContractChangePaymentMethod p, Long contractId) {
|
|
|
|
|
ErpContractPaymentMethod cpm = new ErpContractPaymentMethod();
|
|
|
|
|
cpm.setContractId(contractId);
|
|
|
|
|
|