1.1.30 分款明细新增、修改、删除时同步进行合同回款确认功能。

dev
yinq 5 days ago
parent a291b1df68
commit 68f2cb381b

@ -77,4 +77,22 @@ public class ErpFinAccountInstallmentDetail extends BaseEntity {
@TableField(exist = false)
private String stageName;
/**
* erp_contract_info
*/
@TableField(exist = false)
private BigDecimal contractTotalPrice;
/**
* % erp_contract_payment_methodID+ID
*/
@TableField(exist = false)
private BigDecimal contractPaymentPercentage;
/**
* erp_contract_payment_method.payment_amount
*/
@TableField(exist = false)
private BigDecimal contractPaymentAmount;
}

@ -75,4 +75,19 @@ public class ErpFinAccountInstallmentDetailBo extends BaseEntity {
*/
private String installmentStatus;
/**
* erp_contract_info
*/
private BigDecimal contractTotalPrice;
/**
* % erp_contract_payment_methodID+ID
*/
private BigDecimal contractPaymentPercentage;
/**
* erp_contract_payment_method.payment_amount
*/
private BigDecimal contractPaymentAmount;
}

@ -0,0 +1,22 @@
package org.dromara.oa.erp.domain.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* selectContractCollectionStageDetail
*/
@Data
public class CollectionStageSyncTargetVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 合同订单项目IDerp_project_info.project_id */
private Long projectId;
private Long projectPlanId;
private Long planStageId;
}

@ -90,4 +90,19 @@ public class ErpFinAccountInstallmentDetailVo implements Serializable {
private String contractName;
private String stageName;
/**
* erp_contract_info
*/
private BigDecimal contractTotalPrice;
/**
* % erp_contract_payment_methodID+ID
*/
private BigDecimal contractPaymentPercentage;
/**
* erp_contract_payment_method.payment_amount
*/
private BigDecimal contractPaymentAmount;
}

@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.math.BigDecimal;
import org.apache.ibatis.annotations.Param;
import org.dromara.oa.erp.domain.ErpFinAccountInstallmentDetail;
import org.dromara.oa.erp.domain.vo.ErpFinAccountInstallmentDetailVo;
@ -37,4 +39,11 @@ public interface ErpFinAccountInstallmentDetailMapper extends BaseMapperPlus<Erp
*/
public List<ErpFinAccountInstallmentDetailVo> selectCustomErpFinAccountInstallmentDetailVoList(@Param(Constants.WRAPPER) MPJLambdaWrapper<ErpFinAccountInstallmentDetail> queryWrapper);
/**
* ++
*/
BigDecimal sumDetailAmountByContractProjectStage(@Param("contractId") Long contractId,
@Param("projectId") Long projectId,
@Param("paymentStageId") Long paymentStageId);
}

@ -11,6 +11,7 @@ import org.dromara.common.mybatis.annotation.DataColumn;
import org.dromara.common.mybatis.annotation.DataPermission;
import org.dromara.oa.erp.domain.ErpProjectPlan;
import org.dromara.oa.erp.domain.bo.ErpProjectPlanBo;
import org.dromara.oa.erp.domain.vo.CollectionStageSyncTargetVo;
import org.dromara.oa.erp.domain.vo.ContractCollectionPageVo;
import org.dromara.oa.erp.domain.vo.ContractCollectionStageDetailVo;
import org.dromara.oa.erp.domain.vo.ErpProjectPlanVo;
@ -146,4 +147,11 @@ public interface ErpProjectPlanMapper extends BaseMapperPlus<ErpProjectPlan, Erp
*/
List<ContractCollectionStageDetailVo> selectContractCollectionStageDetail(@Param("projectPlanId") Long projectPlanId);
/**
* ID
*/
List<CollectionStageSyncTargetVo> selectCollectionStageSyncTargetsByContractProjectStage(
@Param("contractId") Long contractId,
@Param("paymentStageId") Long paymentStageId);
}

@ -11,6 +11,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.oa.erp.domain.vo.ErpProjectPlanStageVo;
import java.util.Collection;
import java.util.Date;
import java.util.List;
/**
@ -97,4 +98,18 @@ public interface IErpProjectPlanService {
*
*/
List<ContractCollectionStageDetailVo> queryContractCollectionStageDetail(Long projectPlanId);
/**
* ID++
* {@link ErpProjectPlanStageBo} {@link #confirmCollectionStage}
*
* {@code projectId} {@code receivableDate}
*
* @param contractId ID
* @param projectId ID {@code receivableDate}
* @param paymentStageId ID
* @param receivableDate payment_date null receivable_date
*/
void syncCollectionStageFromInstallmentDetail(Long contractId, Long projectId, Long paymentStageId,
Date receivableDate);
}

@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.oa.base.domain.BasePaymentStage;
import org.dromara.oa.erp.domain.ErpContractInfo;
import org.dromara.oa.erp.domain.ErpContractPaymentMethod;
import org.dromara.oa.erp.domain.ErpFinAccountInstallment;
import org.dromara.oa.erp.mapper.ErpFinAccountInstallmentMapper;
import org.springframework.stereotype.Service;
@ -19,11 +20,15 @@ import org.dromara.oa.erp.domain.vo.ErpFinAccountInstallmentDetailVo;
import org.dromara.oa.erp.domain.ErpFinAccountInstallmentDetail;
import org.dromara.oa.erp.mapper.ErpFinAccountInstallmentDetailMapper;
import org.dromara.oa.erp.service.IErpFinAccountInstallmentDetailService;
import org.dromara.oa.erp.service.IErpProjectPlanService;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.Set;
/**
* Service
@ -39,6 +44,32 @@ public class ErpFinAccountInstallmentDetailServiceImpl implements IErpFinAccount
private final ErpFinAccountInstallmentMapper finAccountInstallmentMapper;
private final IErpProjectPlanService erpProjectPlanService;
/**
*
*/
private void syncContractCollectionStage(Long contractId, Long projectId, Long paymentStageId) {
erpProjectPlanService.syncCollectionStageFromInstallmentDetail(contractId, projectId, paymentStageId, null);
}
/**
* / ErpProjectPlanStageBo
* {@link IErpProjectPlanService#confirmCollectionStage} payment_date
*/
private void syncContractCollectionStage(Long contractId, Long projectId, Long paymentStageId,
Long accountInstallmentId) {
Date receivableDate = null;
if (accountInstallmentId != null) {
ErpFinAccountInstallment inst = finAccountInstallmentMapper.selectById(accountInstallmentId);
if (inst != null) {
receivableDate = inst.getPaymentDate();
}
}
erpProjectPlanService.syncCollectionStageFromInstallmentDetail(
contractId, projectId, paymentStageId, receivableDate);
}
/**
*
*
@ -79,14 +110,14 @@ public class ErpFinAccountInstallmentDetailServiceImpl implements IErpFinAccount
private MPJLambdaWrapper<ErpFinAccountInstallmentDetail> buildQueryWrapper(ErpFinAccountInstallmentDetailBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<ErpFinAccountInstallmentDetail> lqw = JoinWrappers.lambda(ErpFinAccountInstallmentDetail.class)
.selectAll(ErpFinAccountInstallmentDetail.class)
.eq(bo.getAccountInstallmentId() != null, ErpFinAccountInstallmentDetail::getAccountInstallmentId, bo.getAccountInstallmentId())
.eq(bo.getProjectId() != null, ErpFinAccountInstallmentDetail::getProjectId, bo.getProjectId())
.eq(StringUtils.isNotBlank(bo.getProjectCode()), ErpFinAccountInstallmentDetail::getProjectCode, bo.getProjectCode())
.like(StringUtils.isNotBlank(bo.getProjectName()), ErpFinAccountInstallmentDetail::getProjectName, bo.getProjectName())
.eq(bo.getContractId() != null, ErpFinAccountInstallmentDetail::getContractId, bo.getContractId())
.eq(bo.getPaymentStageId() != null, ErpFinAccountInstallmentDetail::getPaymentStageId, bo.getPaymentStageId())
.eq(bo.getDetailAmount() != null, ErpFinAccountInstallmentDetail::getDetailAmount, bo.getDetailAmount());
.selectAll(ErpFinAccountInstallmentDetail.class)
.eq(bo.getAccountInstallmentId() != null, ErpFinAccountInstallmentDetail::getAccountInstallmentId, bo.getAccountInstallmentId())
.eq(bo.getProjectId() != null, ErpFinAccountInstallmentDetail::getProjectId, bo.getProjectId())
.eq(StringUtils.isNotBlank(bo.getProjectCode()), ErpFinAccountInstallmentDetail::getProjectCode, bo.getProjectCode())
.like(StringUtils.isNotBlank(bo.getProjectName()), ErpFinAccountInstallmentDetail::getProjectName, bo.getProjectName())
.eq(bo.getContractId() != null, ErpFinAccountInstallmentDetail::getContractId, bo.getContractId())
.eq(bo.getPaymentStageId() != null, ErpFinAccountInstallmentDetail::getPaymentStageId, bo.getPaymentStageId())
.eq(bo.getDetailAmount() != null, ErpFinAccountInstallmentDetail::getDetailAmount, bo.getDetailAmount());
return lqw;
}
@ -106,19 +137,26 @@ public class ErpFinAccountInstallmentDetailServiceImpl implements IErpFinAccount
private MPJLambdaWrapper<ErpFinAccountInstallmentDetail> buildJoinQueryWrapper(ErpFinAccountInstallmentDetailBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<ErpFinAccountInstallmentDetail> lqw = JoinWrappers.lambda(ErpFinAccountInstallmentDetail.class)
.selectAll(ErpFinAccountInstallmentDetail.class)
.select(ErpContractInfo::getContractCode)
.select(ErpContractInfo::getContractName)
.select(BasePaymentStage::getStageName)
.leftJoin(ErpContractInfo.class, ErpContractInfo::getContractId, ErpFinAccountInstallmentDetail::getContractId)
.leftJoin(BasePaymentStage.class, BasePaymentStage::getPaymentStageId, ErpFinAccountInstallmentDetail::getPaymentStageId)
.eq(bo.getAccountInstallmentId() != null, ErpFinAccountInstallmentDetail::getAccountInstallmentId, bo.getAccountInstallmentId())
.eq(bo.getProjectId() != null, ErpFinAccountInstallmentDetail::getProjectId, bo.getProjectId())
.eq(StringUtils.isNotBlank(bo.getProjectCode()), ErpFinAccountInstallmentDetail::getProjectCode, bo.getProjectCode())
.like(StringUtils.isNotBlank(bo.getProjectName()), ErpFinAccountInstallmentDetail::getProjectName, bo.getProjectName())
.eq(bo.getContractId() != null, ErpFinAccountInstallmentDetail::getContractId, bo.getContractId())
.eq(bo.getPaymentStageId() != null, ErpFinAccountInstallmentDetail::getPaymentStageId, bo.getPaymentStageId())
.eq(bo.getDetailAmount() != null, ErpFinAccountInstallmentDetail::getDetailAmount, bo.getDetailAmount());
.selectAll(ErpFinAccountInstallmentDetail.class)
.select(ErpContractInfo::getContractCode)
.select(ErpContractInfo::getContractName)
.selectAs(ErpContractInfo::getTotalPrice, ErpFinAccountInstallmentDetailVo::getContractTotalPrice)
.select(BasePaymentStage::getStageName)
.selectAs(ErpContractPaymentMethod::getPaymentPercentage, ErpFinAccountInstallmentDetailVo::getContractPaymentPercentage)
.selectAs(ErpContractPaymentMethod::getPaymentAmount, ErpFinAccountInstallmentDetailVo::getContractPaymentAmount)
.leftJoin(ErpContractInfo.class, ErpContractInfo::getContractId, ErpFinAccountInstallmentDetail::getContractId)
.leftJoin(BasePaymentStage.class, BasePaymentStage::getPaymentStageId, ErpFinAccountInstallmentDetail::getPaymentStageId)
.leftJoin(ErpContractPaymentMethod.class, on -> on
.eq(ErpContractPaymentMethod::getContractId, ErpFinAccountInstallmentDetail::getContractId)
.eq(ErpContractPaymentMethod::getPaymentStageId, ErpFinAccountInstallmentDetail::getPaymentStageId)
.eq(ErpContractPaymentMethod::getDelFlag, "0"))
.eq(bo.getAccountInstallmentId() != null, ErpFinAccountInstallmentDetail::getAccountInstallmentId, bo.getAccountInstallmentId())
.eq(bo.getProjectId() != null, ErpFinAccountInstallmentDetail::getProjectId, bo.getProjectId())
.eq(StringUtils.isNotBlank(bo.getProjectCode()), ErpFinAccountInstallmentDetail::getProjectCode, bo.getProjectCode())
.like(StringUtils.isNotBlank(bo.getProjectName()), ErpFinAccountInstallmentDetail::getProjectName, bo.getProjectName())
.eq(bo.getContractId() != null, ErpFinAccountInstallmentDetail::getContractId, bo.getContractId())
.eq(bo.getPaymentStageId() != null, ErpFinAccountInstallmentDetail::getPaymentStageId, bo.getPaymentStageId())
.eq(bo.getDetailAmount() != null, ErpFinAccountInstallmentDetail::getDetailAmount, bo.getDetailAmount());
return lqw;
}
@ -140,7 +178,10 @@ public class ErpFinAccountInstallmentDetailServiceImpl implements IErpFinAccount
ErpFinAccountInstallment erpFinAccountInstallment = finAccountInstallmentMapper.selectById(bo.getAccountInstallmentId());
erpFinAccountInstallment.setInstallmentStatus(bo.getInstallmentStatus());
finAccountInstallmentMapper.updateById(erpFinAccountInstallment);
if (flag) {
syncContractCollectionStage(bo.getContractId(), bo.getProjectId(), bo.getPaymentStageId(),
bo.getAccountInstallmentId());
}
return flag;
}
@ -153,12 +194,22 @@ public class ErpFinAccountInstallmentDetailServiceImpl implements IErpFinAccount
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateByBo(ErpFinAccountInstallmentDetailBo bo) {
ErpFinAccountInstallmentDetail old = baseMapper.selectById(bo.getInstallmentDetailId());
ErpFinAccountInstallmentDetail update = MapstructUtils.convert(bo, ErpFinAccountInstallmentDetail.class);
validEntityBeforeSave(update);
ErpFinAccountInstallment erpFinAccountInstallment = finAccountInstallmentMapper.selectById(bo.getAccountInstallmentId());
erpFinAccountInstallment.setInstallmentStatus(bo.getInstallmentStatus());
finAccountInstallmentMapper.updateById(erpFinAccountInstallment);
return baseMapper.updateById(update) > 0;
boolean ok = baseMapper.updateById(update) > 0;
if (ok) {
if (old != null) {
syncContractCollectionStage(old.getContractId(), old.getProjectId(), old.getPaymentStageId(),
bo.getAccountInstallmentId());
}
syncContractCollectionStage(bo.getContractId(), bo.getProjectId(), bo.getPaymentStageId(),
bo.getAccountInstallmentId());
}
return ok;
}
/**
@ -180,23 +231,47 @@ public class ErpFinAccountInstallmentDetailServiceImpl implements IErpFinAccount
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
if (ids == null || ids.isEmpty()) {
return true;
}
List<ErpFinAccountInstallmentDetail> rows = baseMapper.selectList(
Wrappers.lambdaQuery(ErpFinAccountInstallmentDetail.class)
.in(ErpFinAccountInstallmentDetail::getInstallmentDetailId, ids));
boolean ok = baseMapper.deleteByIds(ids) > 0;
if (ok && !rows.isEmpty()) {
Set<String> seen = new HashSet<>();
for (ErpFinAccountInstallmentDetail r : rows) {
if (r.getContractId() == null || r.getProjectId() == null || r.getPaymentStageId() == null) {
continue;
}
String key = r.getContractId() + "_" + r.getProjectId() + "_" + r.getPaymentStageId();
if (seen.add(key)) {
syncContractCollectionStage(r.getContractId(), r.getProjectId(), r.getPaymentStageId());
}
}
}
return ok;
}
/**
*
*
* @param bo
* @return
*/
@Override
public Boolean deleteAccountInstallmentDetail(ErpFinAccountInstallmentDetailBo bo) {
ErpFinAccountInstallmentDetail row = bo.getInstallmentDetailId() == null ? null : baseMapper.selectById(bo.getInstallmentDetailId());
ErpFinAccountInstallment erpFinAccountInstallment = new ErpFinAccountInstallment();
erpFinAccountInstallment.setAccountInstallmentId(bo.getAccountInstallmentId());
erpFinAccountInstallment.setInstallmentStatus(bo.getInstallmentStatus());
finAccountInstallmentMapper.updateById(erpFinAccountInstallment);
return baseMapper.deleteById(bo.getInstallmentDetailId()) > 0;
boolean ok = baseMapper.deleteById(bo.getInstallmentDetailId()) > 0;
if (ok && row != null) {
syncContractCollectionStage(row.getContractId(), row.getProjectId(), row.getPaymentStageId());
}
return ok;
}
}

@ -27,10 +27,12 @@ import org.dromara.oa.erp.domain.ErpProjectPlan;
import org.dromara.oa.erp.domain.ErpProjectPlanStage;
import org.dromara.oa.erp.domain.bo.ErpProjectPlanBo;
import org.dromara.oa.erp.domain.bo.ErpProjectPlanStageBo;
import org.dromara.oa.erp.domain.vo.CollectionStageSyncTargetVo;
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.ErpFinAccountInstallmentDetailMapper;
import org.dromara.oa.erp.mapper.ErpProjectInfoMapper;
import org.dromara.oa.erp.mapper.ErpProjectPlanMapper;
import org.dromara.oa.erp.mapper.ErpProjectPlanStageMapper;
@ -67,6 +69,8 @@ public class ErpProjectPlanServiceImpl implements IErpProjectPlanService {
private final ErpProjectInfoMapper projectInfoMapper;
private final ErpFinAccountInstallmentDetailMapper finAccountInstallmentDetailMapper;
@DubboReference(timeout = 30000)
private RemoteWorkflowService remoteWorkflowService;
@ -393,25 +397,16 @@ public class ErpProjectPlanServiceImpl implements IErpProjectPlanService {
if (stage == null) {
throw new ServiceException("项目计划阶段不存在");
}
stage.setReceivableDate(bo.getReceivableDate());
stage.setActualRepaymentAmount(bo.getActualRepaymentAmount());
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());
stage.setCollectionConfirmTime(bo.getCollectionConfirmTime());
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);
stage.setCollectionConfirmStatus(resolveCollectionConfirmStatus(actual, expected));
if (bo.getDelayDay() != null) {
stage.setDelayDay(bo.getDelayDay());
@ -508,6 +503,57 @@ public class ErpProjectPlanServiceImpl implements IErpProjectPlanService {
return baseMapper.selectContractCollectionStageDetail(projectPlanId);
}
@Override
public void syncCollectionStageFromInstallmentDetail(Long contractId, Long projectId, Long paymentStageId,
Date receivableDate) {
if (contractId == null || paymentStageId == null) {
return;
}
// 合同ID → 项目表(该合同下全部合同订单) → 项目计划 → 计划阶段
List<CollectionStageSyncTargetVo> targets =
baseMapper.selectCollectionStageSyncTargetsByContractProjectStage(contractId, paymentStageId);
if (targets == null || targets.isEmpty()) {
return;
}
for (CollectionStageSyncTargetVo row : targets) {
if (row.getPlanStageId() == null || row.getProjectPlanId() == null || row.getProjectId() == null) {
continue;
}
ErpProjectPlanStage stage = planStageMapper.selectById(row.getPlanStageId());
if (stage == null) {
continue;
}
BigDecimal sum = finAccountInstallmentDetailMapper.sumDetailAmountByContractProjectStage(
contractId, projectId, paymentStageId);
if (sum == null) {
sum = BigDecimal.ZERO;
}
ErpProjectPlanStageBo bo = new ErpProjectPlanStageBo();
bo.setPlanStageId(row.getPlanStageId());
bo.setActualRepaymentAmount(sum);
bo.setReceivableDate(receivableDate);
bo.setCollectionConfirmRemark(stage.getCollectionConfirmRemark());
this.confirmCollectionStage(bo);
}
}
/**
* {@link #confirmCollectionStage} 0 / 1 / 2 repayment_amount
*/
private static String resolveCollectionConfirmStatus(BigDecimal actualAmount, BigDecimal expectedAmount) {
BigDecimal actual = actualAmount == null ? BigDecimal.ZERO : actualAmount;
BigDecimal expected = expectedAmount == null ? BigDecimal.ZERO : expectedAmount;
if (actual.compareTo(BigDecimal.ZERO) <= 0) {
return "0";
}
if (expected.compareTo(BigDecimal.ZERO) > 0 && actual.compareTo(expected) >= 0) {
return "2";
}
return "1";
}
/**
* (: 稿退)
*

@ -1,14 +1,36 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.oa.erp.mapper.ErpFinAccountInstallmentDetailMapper">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpFinAccountInstallmentDetailVo" id="ErpFinAccountInstallmentDetailResult">
<resultMap type="org.dromara.oa.erp.domain.vo.ErpFinAccountInstallmentDetailVo"
id="ErpFinAccountInstallmentDetailResult">
</resultMap>
<select id="selectCustomErpFinAccountInstallmentDetailVoList" resultMap="ErpFinAccountInstallmentDetailResult">
select installment_detail_id, account_installment_id, project_id, project_code, project_name, contract_id, payment_stage_id, detail_amount, remark, create_dept, create_by, create_time, update_by, update_time from erp_fin_account_installment_detail t
select installment_detail_id,
account_installment_id,
project_id,
project_code,
project_name,
contract_id,
payment_stage_id,
detail_amount,
remark,
create_dept,
create_by,
create_time,
update_by,
update_time
from erp_fin_account_installment_detail t
${ew.getCustomSqlSegment}
</select>
<select id="sumDetailAmountByContractProjectStage" resultType="java.math.BigDecimal">
SELECT COALESCE(SUM(d.detail_amount), 0)
FROM erp_fin_account_installment_detail d
WHERE d.contract_id = #{contractId}
AND d.project_id = #{projectId}
AND d.payment_stage_id = #{paymentStageId}
</select>
</mapper>

@ -448,4 +448,33 @@
order by pm.sort_order asc
</select>
<!--
分款同步合同回款阶段:
1) 仅合同ID 查 erp_project_info该合同下全部合同订单project_category='9'
2) 各 project_id 关联 erp_project_plan
3) 合同付款节点 + 项目计划阶段(与 selectContractCollectionStageDetail 的 pm/ps 关联一致)。
-->
<select id="selectCollectionStageSyncTargetsByContractProjectStage"
resultType="org.dromara.oa.erp.domain.vo.CollectionStageSyncTargetVo">
select pi.project_id as projectId,
pp.project_plan_id as projectPlanId,
ps.plan_stage_id as planStageId
from erp_project_info pi
inner join erp_project_plan pp
on pp.project_id = pi.project_id
and pp.del_flag = '0'
inner join erp_contract_payment_method pm
on pm.contract_id = pi.contract_id
and pm.del_flag = '0'
and pm.payment_stage_id = #{paymentStageId}
inner join erp_project_plan_stage ps
on ps.project_plan_id = pp.project_plan_id
and ps.del_flag = '0'
and ps.payment_stage_id is not null
and ps.payment_stage_id = pm.payment_stage_id
where pi.del_flag = '0'
and pi.project_category = '9'
and pi.contract_id = #{contractId}
</select>
</mapper>

Loading…
Cancel
Save