调整收付款问题
This commit is contained in:
+5
@@ -30,12 +30,15 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import org.springblade.transport.pojo.entity.KingdeeReceiptFlow;
|
import org.springblade.transport.pojo.entity.KingdeeReceiptFlow;
|
||||||
|
import org.springblade.transport.pojo.entity.ReceiptFlowRecord;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 收款流水视图实体类
|
* 收款流水视图实体类
|
||||||
@@ -70,4 +73,6 @@ public class ReceiptFlowVO extends KingdeeReceiptFlow {
|
|||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime transactionEndTime;
|
private LocalDateTime transactionEndTime;
|
||||||
|
@TableField(exist = false)
|
||||||
|
private List<ReceiptFlowRecord> claimRecords = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-26
@@ -73,7 +73,6 @@ import java.time.format.DateTimeFormatter;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
/** 付款申请服务实现。 @author Chill */
|
/** 付款申请服务实现。 @author Chill */
|
||||||
@Service
|
@Service
|
||||||
@@ -114,6 +113,7 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
|
|||||||
.orderByDesc(PaymentApplication::getCreateTime);
|
.orderByDesc(PaymentApplication::getCreateTime);
|
||||||
return page(page, wrapper).convert(item -> {
|
return page(page, wrapper).convert(item -> {
|
||||||
PaymentApplicationVO vo = PaymentApplicationWrapper.build().entityVO(item);
|
PaymentApplicationVO vo = PaymentApplicationWrapper.build().entityVO(item);
|
||||||
|
if (!APPROVED.equals(item.getApprovalStatus())) vo.setPaidAmount(BigDecimal.ZERO);
|
||||||
return vo;
|
return vo;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -471,15 +471,14 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void validateQuota(PaymentApplication entity) {
|
private void validateQuota(PaymentApplication entity) {
|
||||||
|
if (!"project_advance".equals(entity.getPaymentType())) return;
|
||||||
|
BigDecimal appliedAmount = money(entity.getAppliedAmount());
|
||||||
ProjectApply project = entity.getProjectId() == null ? null : projectApplyMapper.selectOne(
|
ProjectApply project = entity.getProjectId() == null ? null : projectApplyMapper.selectOne(
|
||||||
Wrappers.<ProjectApply>lambdaQuery().eq(ProjectApply::getId, entity.getProjectId()).last("FOR UPDATE"));
|
Wrappers.<ProjectApply>lambdaQuery().eq(ProjectApply::getId, entity.getProjectId()).last("FOR UPDATE"));
|
||||||
if (project != null && project.getFundLimit() != null) {
|
if (project != null && project.getFundLimit() != null) {
|
||||||
BigDecimal projectLimit = projectFundLimit(project);
|
BigDecimal projectLimit = projectFundLimit(project);
|
||||||
BigDecimal projectOccupiedAmount = quotaOccupiedAmount(Wrappers.<PaymentApplication>lambdaQuery()
|
if (appliedAmount.compareTo(projectLimit) > 0) {
|
||||||
.eq(PaymentApplication::getProjectId, entity.getProjectId())
|
throw new ServiceException("申请付款金额不能超过项目额度");
|
||||||
.ne(entity.getId() != null, PaymentApplication::getId, entity.getId()), entity);
|
|
||||||
if (projectOccupiedAmount.compareTo(projectLimit) > 0) {
|
|
||||||
throw new ServiceException("申请付款金额超过项目剩余资金使用额度(已扣减收票金额并包含在途申请)");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Func.isNotEmpty(entity.getPayeeName())) {
|
if (Func.isNotEmpty(entity.getPayeeName())) {
|
||||||
@@ -488,13 +487,8 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
|
|||||||
.eq(CustomerArchive::getIsDeleted, 0).last("limit 1 FOR UPDATE"));
|
.eq(CustomerArchive::getIsDeleted, 0).last("limit 1 FOR UPDATE"));
|
||||||
if (customer != null && customer.getMaxCreditLimit() != null) {
|
if (customer != null && customer.getMaxCreditLimit() != null) {
|
||||||
BigDecimal customerLimit = customer.getMaxCreditLimit().multiply(BigDecimal.valueOf(10000));
|
BigDecimal customerLimit = customer.getMaxCreditLimit().multiply(BigDecimal.valueOf(10000));
|
||||||
List<String> customerNames = Stream.of(customer.getFullName(), customer.getShortName())
|
if (appliedAmount.compareTo(customerLimit) > 0) {
|
||||||
.filter(Func::isNotEmpty).map(String::trim).distinct().toList();
|
throw new ServiceException("申请付款金额不能超过客户额度");
|
||||||
BigDecimal customerOccupiedAmount = quotaOccupiedAmount(Wrappers.<PaymentApplication>lambdaQuery()
|
|
||||||
.in(PaymentApplication::getPayeeName, customerNames)
|
|
||||||
.ne(entity.getId() != null, PaymentApplication::getId, entity.getId()), entity);
|
|
||||||
if (customerOccupiedAmount.compareTo(customerLimit) > 0) {
|
|
||||||
throw new ServiceException("申请付款金额超过客户剩余资金使用额度(已扣减收票金额并包含在途申请)");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -512,19 +506,6 @@ public class PaymentApplicationServiceImpl extends BaseServiceImpl<PaymentApplic
|
|||||||
return money(project.getFundLimit()).add(temporaryLimit).multiply(BigDecimal.valueOf(10000));
|
return money(project.getFundLimit()).add(temporaryLimit).multiply(BigDecimal.valueOf(10000));
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal quotaOccupiedAmount(LambdaQueryWrapper<PaymentApplication> wrapper,
|
|
||||||
PaymentApplication currentApplication) {
|
|
||||||
List<PaymentApplication> applications = list(wrapper.ne(PaymentApplication::getApprovalStatus, VOIDED)
|
|
||||||
.last("FOR UPDATE"));
|
|
||||||
BigDecimal appliedAmount = applications.stream().map(PaymentApplication::getAppliedAmount)
|
|
||||||
.map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
||||||
.add(money(currentApplication.getAppliedAmount()));
|
|
||||||
BigDecimal receivedInvoiceAmount = applications.stream().map(PaymentApplication::getMatchedInvoiceAmount)
|
|
||||||
.map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
||||||
.add(money(currentApplication.getMatchedInvoiceAmount()));
|
|
||||||
return appliedAmount.subtract(receivedInvoiceAmount).max(BigDecimal.ZERO);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BigDecimal sumApplied(LambdaQueryWrapper<PaymentApplication> wrapper) {
|
private BigDecimal sumApplied(LambdaQueryWrapper<PaymentApplication> wrapper) {
|
||||||
return list(wrapper.ne(PaymentApplication::getApprovalStatus, VOIDED)).stream()
|
return list(wrapper.ne(PaymentApplication::getApprovalStatus, VOIDED)).stream()
|
||||||
.map(PaymentApplication::getAppliedAmount).map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add);
|
.map(PaymentApplication::getAppliedAmount).map(this::money).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
|
|||||||
+33
-1
@@ -42,6 +42,7 @@ import org.springblade.transport.mapper.PreSettlementDetailFeeMapper;
|
|||||||
import org.springblade.transport.mapper.PreSettlementDetailMapper;
|
import org.springblade.transport.mapper.PreSettlementDetailMapper;
|
||||||
import org.springblade.transport.mapper.PreSettlementMapper;
|
import org.springblade.transport.mapper.PreSettlementMapper;
|
||||||
import org.springblade.transport.mapper.PreSettlementSummaryFeeMapper;
|
import org.springblade.transport.mapper.PreSettlementSummaryFeeMapper;
|
||||||
|
import org.springblade.transport.mapper.PaymentApplicationMapper;
|
||||||
import org.springblade.transport.mapper.ReceivablePayableCargoFeeMapper;
|
import org.springblade.transport.mapper.ReceivablePayableCargoFeeMapper;
|
||||||
import org.springblade.transport.mapper.ReceivablePayableDetailMapper;
|
import org.springblade.transport.mapper.ReceivablePayableDetailMapper;
|
||||||
import org.springblade.transport.pojo.dto.PreSettlementAdvanceRequest;
|
import org.springblade.transport.pojo.dto.PreSettlementAdvanceRequest;
|
||||||
@@ -56,6 +57,7 @@ import org.springblade.transport.pojo.entity.PreSettlementChangeRecord;
|
|||||||
import org.springblade.transport.pojo.entity.PreSettlementDetail;
|
import org.springblade.transport.pojo.entity.PreSettlementDetail;
|
||||||
import org.springblade.transport.pojo.entity.PreSettlementDetailFee;
|
import org.springblade.transport.pojo.entity.PreSettlementDetailFee;
|
||||||
import org.springblade.transport.pojo.entity.PreSettlementSummaryFee;
|
import org.springblade.transport.pojo.entity.PreSettlementSummaryFee;
|
||||||
|
import org.springblade.transport.pojo.entity.PaymentApplication;
|
||||||
import org.springblade.transport.pojo.entity.ProjectApply;
|
import org.springblade.transport.pojo.entity.ProjectApply;
|
||||||
import org.springblade.transport.pojo.entity.ReceivablePayableCargoFee;
|
import org.springblade.transport.pojo.entity.ReceivablePayableCargoFee;
|
||||||
import org.springblade.transport.pojo.entity.ReceivablePayableDetail;
|
import org.springblade.transport.pojo.entity.ReceivablePayableDetail;
|
||||||
@@ -113,6 +115,7 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
|
|||||||
private final PreSettlementDetailFeeMapper detailFeeMapper;
|
private final PreSettlementDetailFeeMapper detailFeeMapper;
|
||||||
private final PreSettlementSummaryFeeMapper summaryFeeMapper;
|
private final PreSettlementSummaryFeeMapper summaryFeeMapper;
|
||||||
private final PreSettlementAdvanceMapper advanceMapper;
|
private final PreSettlementAdvanceMapper advanceMapper;
|
||||||
|
private final PaymentApplicationMapper paymentApplicationMapper;
|
||||||
private final PreSettlementChangeRecordMapper changeRecordMapper;
|
private final PreSettlementChangeRecordMapper changeRecordMapper;
|
||||||
private final ReceivablePayableDetailMapper sourceDetailMapper;
|
private final ReceivablePayableDetailMapper sourceDetailMapper;
|
||||||
private final ReceivablePayableCargoFeeMapper sourceFeeMapper;
|
private final ReceivablePayableCargoFeeMapper sourceFeeMapper;
|
||||||
@@ -124,7 +127,36 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPage<PreSettlementVO> selectPage(IPage<PreSettlement> page, PreSettlementVO query) {
|
public IPage<PreSettlementVO> selectPage(IPage<PreSettlement> page, PreSettlementVO query) {
|
||||||
return PreSettlementWrapper.build().pageVO(page(page, buildQuery(query)));
|
IPage<PreSettlementVO> result = PreSettlementWrapper.build().pageVO(page(page, buildQuery(query)));
|
||||||
|
fillPaymentApplicationAmounts(result.getRecords());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillPaymentApplicationAmounts(List<PreSettlementVO> records) {
|
||||||
|
if (Func.isEmpty(records)) return;
|
||||||
|
Set<Long> preSettlementIds = records.stream().map(PreSettlementVO::getId)
|
||||||
|
.filter(Objects::nonNull).collect(Collectors.toSet());
|
||||||
|
if (preSettlementIds.isEmpty()) return;
|
||||||
|
List<PaymentApplication> applications = paymentApplicationMapper.selectList(
|
||||||
|
Wrappers.<PaymentApplication>lambdaQuery()
|
||||||
|
.select(PaymentApplication::getPreSettlementId, PaymentApplication::getAppliedAmount,
|
||||||
|
PaymentApplication::getPaidAmount, PaymentApplication::getApprovalStatus)
|
||||||
|
.eq(PaymentApplication::getPaymentType, "progress_advance")
|
||||||
|
.in(PaymentApplication::getPreSettlementId, preSettlementIds)
|
||||||
|
.in(PaymentApplication::getApprovalStatus, STATUS_REVIEWING, STATUS_APPROVED)
|
||||||
|
.eq(PaymentApplication::getIsDeleted, 0));
|
||||||
|
Map<Long, BigDecimal> reviewingAmounts = new HashMap<>();
|
||||||
|
Map<Long, BigDecimal> approvedAmounts = new HashMap<>();
|
||||||
|
applications.forEach(application -> {
|
||||||
|
boolean reviewing = STATUS_REVIEWING.equals(application.getApprovalStatus());
|
||||||
|
Map<Long, BigDecimal> amounts = reviewing ? reviewingAmounts : approvedAmounts;
|
||||||
|
BigDecimal amount = reviewing ? application.getAppliedAmount() : application.getPaidAmount();
|
||||||
|
amounts.merge(application.getPreSettlementId(), money(amount), BigDecimal::add);
|
||||||
|
});
|
||||||
|
records.forEach(record -> {
|
||||||
|
record.setAdvanceAppliedAmount(money(reviewingAmounts.get(record.getId())));
|
||||||
|
record.setAdvancePaidAmount(money(approvedAmounts.get(record.getId())));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+25
-2
@@ -54,7 +54,9 @@ import java.math.RoundingMode;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,14 +96,35 @@ public class ReceiptClaimRecordServiceImpl extends BaseServiceImpl<ReceiptClaimM
|
|||||||
if (record == null) {
|
if (record == null) {
|
||||||
throw new ServiceException("认领记录不存在或无权查看");
|
throw new ServiceException("认领记录不存在或无权查看");
|
||||||
}
|
}
|
||||||
record.setSettlements(claimSettlementMapper.selectList(
|
List<ReceiptClaimSettlement> settlements = claimSettlementMapper.selectList(
|
||||||
Wrappers.<ReceiptClaimSettlement>lambdaQuery()
|
Wrappers.<ReceiptClaimSettlement>lambdaQuery()
|
||||||
.eq(ReceiptClaimSettlement::getReceiptClaimId, id)
|
.eq(ReceiptClaimSettlement::getReceiptClaimId, id)
|
||||||
.orderByAsc(ReceiptClaimSettlement::getCreateTime)));
|
.orderByAsc(ReceiptClaimSettlement::getCreateTime));
|
||||||
|
fillSettlementClaimedAmounts(settlements);
|
||||||
|
record.setSettlements(settlements);
|
||||||
fillStatusNames(record);
|
fillStatusNames(record);
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fillSettlementClaimedAmounts(List<ReceiptClaimSettlement> settlements) {
|
||||||
|
List<Long> settlementIds = settlements.stream()
|
||||||
|
.map(ReceiptClaimSettlement::getFormalSettlementId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.distinct()
|
||||||
|
.toList();
|
||||||
|
if (settlementIds.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Long, BigDecimal> claimedAmountMap = new HashMap<>();
|
||||||
|
claimSettlementMapper.selectList(Wrappers.<ReceiptClaimSettlement>lambdaQuery()
|
||||||
|
.in(ReceiptClaimSettlement::getFormalSettlementId, settlementIds)
|
||||||
|
.eq(ReceiptClaimSettlement::getStatus, 1))
|
||||||
|
.forEach(relation -> claimedAmountMap.merge(relation.getFormalSettlementId(),
|
||||||
|
money(relation.getAllocatedReceiptAmount()), BigDecimal::add));
|
||||||
|
settlements.forEach(settlement -> settlement.setClaimedReceiptAmount(
|
||||||
|
money(claimedAmountMap.get(settlement.getFormalSettlementId()))));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updateAttachments(ReceiptClaimAttachmentsRequest request) {
|
public void updateAttachments(ReceiptClaimAttachmentsRequest request) {
|
||||||
|
|||||||
+5
@@ -111,6 +111,7 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
|
|||||||
.le(query.getTransactionEndTime() != null, KingdeeReceiptFlow::getTransactionTime,
|
.le(query.getTransactionEndTime() != null, KingdeeReceiptFlow::getTransactionTime,
|
||||||
query.getTransactionEndTime())
|
query.getTransactionEndTime())
|
||||||
.eq(KingdeeReceiptFlow::getStatus, 1)
|
.eq(KingdeeReceiptFlow::getStatus, 1)
|
||||||
|
.orderByDesc(KingdeeReceiptFlow::getTransactionTime)
|
||||||
.orderByDesc(KingdeeReceiptFlow::getCreateTime);
|
.orderByDesc(KingdeeReceiptFlow::getCreateTime);
|
||||||
return page(page, wrapper).convert(ReceiptFlowWrapper.build()::entityVO);
|
return page(page, wrapper).convert(ReceiptFlowWrapper.build()::entityVO);
|
||||||
}
|
}
|
||||||
@@ -123,6 +124,10 @@ public class ReceiptFlowServiceImpl extends BaseServiceImpl<KingdeeReceiptFlowMa
|
|||||||
Dept dept = deptId == null ? null : SysCache.getDept(deptId);
|
Dept dept = deptId == null ? null : SysCache.getDept(deptId);
|
||||||
vo.setClaimerDeptName(dept == null ? null : dept.getDeptName());
|
vo.setClaimerDeptName(dept == null ? null : dept.getDeptName());
|
||||||
vo.setClaimDate(LocalDate.now());
|
vo.setClaimDate(LocalDate.now());
|
||||||
|
vo.setClaimRecords(recordMapper.selectList(Wrappers.<ReceiptFlowRecord>lambdaQuery()
|
||||||
|
.eq(ReceiptFlowRecord::getReceiptFlowId, id)
|
||||||
|
.eq(ReceiptFlowRecord::getActionType, "claim")
|
||||||
|
.orderByDesc(ReceiptFlowRecord::getCreateTime)));
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user