|
|
|
|
@ -22,6 +22,7 @@ import org.dromara.common.satoken.utils.LoginHelper;
|
|
|
|
|
import org.dromara.common.tenant.helper.TenantHelper;
|
|
|
|
|
import org.dromara.oa.erp.constant.ProjectCategoryConstant;
|
|
|
|
|
import org.dromara.oa.base.domain.BasePaymentStage;
|
|
|
|
|
import org.dromara.oa.erp.domain.ErpProjectInfo;
|
|
|
|
|
import org.dromara.oa.erp.domain.ErpProjectPlan;
|
|
|
|
|
import org.dromara.oa.erp.domain.ErpProjectPlanStage;
|
|
|
|
|
import org.dromara.oa.erp.domain.bo.ErpProjectPlanBo;
|
|
|
|
|
@ -30,6 +31,7 @@ import org.dromara.oa.erp.domain.vo.ContractCollectionPageVo;
|
|
|
|
|
import org.dromara.oa.erp.domain.vo.ContractCollectionStageDetailVo;
|
|
|
|
|
import org.dromara.oa.erp.domain.vo.ErpProjectPlanStageVo;
|
|
|
|
|
import org.dromara.oa.erp.domain.vo.ErpProjectPlanVo;
|
|
|
|
|
import org.dromara.oa.erp.mapper.ErpProjectInfoMapper;
|
|
|
|
|
import org.dromara.oa.erp.mapper.ErpProjectPlanMapper;
|
|
|
|
|
import org.dromara.oa.erp.mapper.ErpProjectPlanStageMapper;
|
|
|
|
|
import org.dromara.oa.erp.service.IErpProjectPlanService;
|
|
|
|
|
@ -63,6 +65,8 @@ public class ErpProjectPlanServiceImpl implements IErpProjectPlanService {
|
|
|
|
|
|
|
|
|
|
private final ErpProjectPlanStageMapper planStageMapper;
|
|
|
|
|
|
|
|
|
|
private final ErpProjectInfoMapper projectInfoMapper;
|
|
|
|
|
|
|
|
|
|
@DubboReference(timeout = 30000)
|
|
|
|
|
private RemoteWorkflowService remoteWorkflowService;
|
|
|
|
|
|
|
|
|
|
@ -391,22 +395,21 @@ public class ErpProjectPlanServiceImpl implements IErpProjectPlanService {
|
|
|
|
|
}
|
|
|
|
|
stage.setReceivableDate(bo.getReceivableDate());
|
|
|
|
|
stage.setActualRepaymentAmount(bo.getActualRepaymentAmount());
|
|
|
|
|
stage.setActualRepaymentRate(calcActualRepaymentRate(bo.getActualRepaymentAmount(), stage.getRepaymentAmount()));
|
|
|
|
|
BigDecimal contractOrderAmount = resolveContractOrderAmount(stage.getProjectPlanId(), stage.getProjectId());
|
|
|
|
|
stage.setActualRepaymentRate(calcActualRepaymentRate(bo.getActualRepaymentAmount(), contractOrderAmount));
|
|
|
|
|
stage.setCollectionConfirmRemark(bo.getCollectionConfirmRemark());
|
|
|
|
|
stage.setCollectionConfirmUserId(LoginHelper.getUserId());
|
|
|
|
|
stage.setCollectionConfirmTime(new Date());
|
|
|
|
|
|
|
|
|
|
String confirmStatus = bo.getCollectionConfirmStatus();
|
|
|
|
|
if (StringUtils.isBlank(confirmStatus)) {
|
|
|
|
|
BigDecimal expected = stage.getRepaymentAmount() == null ? BigDecimal.ZERO : BigDecimal.valueOf(stage.getRepaymentAmount());
|
|
|
|
|
BigDecimal actual = bo.getActualRepaymentAmount() == null ? BigDecimal.ZERO : bo.getActualRepaymentAmount();
|
|
|
|
|
if (actual.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
confirmStatus = "0";
|
|
|
|
|
} else if (expected.compareTo(BigDecimal.ZERO) > 0 && actual.compareTo(expected) >= 0) {
|
|
|
|
|
confirmStatus = "2";
|
|
|
|
|
} else {
|
|
|
|
|
confirmStatus = "1";
|
|
|
|
|
}
|
|
|
|
|
String confirmStatus = "0";
|
|
|
|
|
BigDecimal expected = stage.getRepaymentAmount() == null ? BigDecimal.ZERO : stage.getRepaymentAmount();
|
|
|
|
|
BigDecimal actual = bo.getActualRepaymentAmount() == null ? BigDecimal.ZERO : bo.getActualRepaymentAmount();
|
|
|
|
|
if (actual.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
confirmStatus = "0";
|
|
|
|
|
} else if (expected.compareTo(BigDecimal.ZERO) > 0 && actual.compareTo(expected) >= 0) {
|
|
|
|
|
confirmStatus = "2";
|
|
|
|
|
} else {
|
|
|
|
|
confirmStatus = "1";
|
|
|
|
|
}
|
|
|
|
|
stage.setCollectionConfirmStatus(confirmStatus);
|
|
|
|
|
|
|
|
|
|
@ -416,23 +419,80 @@ public class ErpProjectPlanServiceImpl implements IErpProjectPlanService {
|
|
|
|
|
if (StringUtils.isNotBlank(bo.getReasonsExplanation())) {
|
|
|
|
|
stage.setReasonsExplanation(bo.getReasonsExplanation());
|
|
|
|
|
}
|
|
|
|
|
return planStageMapper.updateById(stage) > 0;
|
|
|
|
|
boolean updated = planStageMapper.updateById(stage) > 0;
|
|
|
|
|
if (updated) {
|
|
|
|
|
refreshContractOrderPaymentRate(stage.getProjectPlanId(), stage.getProjectId());
|
|
|
|
|
}
|
|
|
|
|
return updated;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 计算 实际回款比例(%) = 实际回款金额 / 预计回款金额 * 100
|
|
|
|
|
*
|
|
|
|
|
* @param actualRepaymentAmount 实际回款金额
|
|
|
|
|
* @param repaymentAmount 预计回款金额
|
|
|
|
|
* 同步合同订单回款比例:本计划下各阶段 actual_repayment_rate(%) 相加,写入 erp_project_info.order_payment_rate
|
|
|
|
|
*/
|
|
|
|
|
private BigDecimal calcActualRepaymentRate(BigDecimal actualRepaymentAmount, Long repaymentAmount) {
|
|
|
|
|
private void refreshContractOrderPaymentRate(Long projectPlanId, Long projectIdFromStage) {
|
|
|
|
|
if (projectPlanId == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
List<ErpProjectPlanStage> stages = planStageMapper.selectList(
|
|
|
|
|
Wrappers.lambdaQuery(ErpProjectPlanStage.class)
|
|
|
|
|
.eq(ErpProjectPlanStage::getProjectPlanId, projectPlanId)
|
|
|
|
|
.eq(ErpProjectPlanStage::getDelFlag, "0"));
|
|
|
|
|
BigDecimal sumRate = stages.stream()
|
|
|
|
|
.map(s -> s.getActualRepaymentRate() != null ? s.getActualRepaymentRate() : BigDecimal.ZERO)
|
|
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
|
|
.setScale(2, RoundingMode.HALF_UP);
|
|
|
|
|
|
|
|
|
|
Long projectId = projectIdFromStage;
|
|
|
|
|
if (projectId == null) {
|
|
|
|
|
ErpProjectPlan plan = baseMapper.selectById(projectPlanId);
|
|
|
|
|
if (plan == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
projectId = plan.getProjectId();
|
|
|
|
|
}
|
|
|
|
|
if (projectId == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
projectInfoMapper.update(null, Wrappers.<ErpProjectInfo>lambdaUpdate()
|
|
|
|
|
.set(ErpProjectInfo::getOrderPaymentRate, sumRate)
|
|
|
|
|
.eq(ErpProjectInfo::getProjectId, projectId));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 合同订单金额(erp_project_info.amount),作实际回款比例分母,不再查合同表
|
|
|
|
|
*/
|
|
|
|
|
private BigDecimal resolveContractOrderAmount(Long projectPlanId, Long projectIdFromStage) {
|
|
|
|
|
Long projectId = projectIdFromStage;
|
|
|
|
|
if (projectId == null && projectPlanId != null) {
|
|
|
|
|
ErpProjectPlan plan = baseMapper.selectById(projectPlanId);
|
|
|
|
|
if (plan != null) {
|
|
|
|
|
projectId = plan.getProjectId();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (projectId == null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
ErpProjectInfo project = projectInfoMapper.selectById(projectId);
|
|
|
|
|
if (project == null || project.getAmount() == null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
return project.getAmount();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 计算 实际回款比例(%) = 本阶段实际回款金额 / 合同订单金额 * 100
|
|
|
|
|
*
|
|
|
|
|
* @param actualRepaymentAmount 本阶段实际回款金额
|
|
|
|
|
* @param contractOrderAmount 合同订单金额(erp_project_info.amount)
|
|
|
|
|
*/
|
|
|
|
|
private BigDecimal calcActualRepaymentRate(BigDecimal actualRepaymentAmount, BigDecimal contractOrderAmount) {
|
|
|
|
|
BigDecimal actual = actualRepaymentAmount == null ? BigDecimal.ZERO : actualRepaymentAmount;
|
|
|
|
|
BigDecimal expected = repaymentAmount == null ? BigDecimal.ZERO : BigDecimal.valueOf(repaymentAmount);
|
|
|
|
|
if (expected.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
BigDecimal total = contractOrderAmount == null ? BigDecimal.ZERO : contractOrderAmount;
|
|
|
|
|
if (total.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
|
|
|
|
|
}
|
|
|
|
|
return actual
|
|
|
|
|
.divide(expected, 6, RoundingMode.HALF_UP)
|
|
|
|
|
.divide(total, 6, RoundingMode.HALF_UP)
|
|
|
|
|
.multiply(BigDecimal.valueOf(100))
|
|
|
|
|
.setScale(2, RoundingMode.HALF_UP);
|
|
|
|
|
}
|
|
|
|
|
|