完善首付款管理模块
This commit is contained in:
+23
@@ -0,0 +1,23 @@
|
||||
package org.springblade.transport.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/** 正式结算批量付款申请请求。 @author Chill */
|
||||
@Data
|
||||
public class FormalSettlementBatchPaymentRequest implements Serializable {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
private List<Item> items;
|
||||
private String remark;
|
||||
|
||||
@Data
|
||||
public static class Item implements Serializable {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
private Long id;
|
||||
private BigDecimal appliedAmount;
|
||||
}
|
||||
}
|
||||
+8
@@ -20,6 +20,7 @@ import org.springblade.core.secure.annotation.PreAuth;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementBatchPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementStatusRequest;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementDetailAdjustRequest;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementDetailFee;
|
||||
@@ -158,4 +159,11 @@ public class FormalSettlementController extends BladeController {
|
||||
public R<String> applyPayment(@RequestBody FormalSettlementPaymentRequest request) {
|
||||
return R.data(formalSettlementService.applyPayment(request));
|
||||
}
|
||||
|
||||
@PostMapping("/apply-payments")
|
||||
@ApiOperationSupport(order = 18)
|
||||
@Operation(summary = "批量发起尾款付款申请")
|
||||
public R<List<String>> applyPayments(@RequestBody FormalSettlementBatchPaymentRequest request) {
|
||||
return R.data(formalSettlementService.applyPayments(request));
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -20,6 +20,7 @@ import org.springblade.transport.pojo.dto.PreSettlementDetailAdjustRequest;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlementDetailFee;
|
||||
import java.util.List;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementBatchPaymentRequest;
|
||||
|
||||
/**
|
||||
* 正式结算单服务
|
||||
@@ -41,4 +42,5 @@ public interface IFormalSettlementService extends BaseService<FormalSettlement>
|
||||
List<FormalSettlementDetailFee> detailFees(Long detailId);
|
||||
void adjustDetail(PreSettlementDetailAdjustRequest request);
|
||||
String applyPayment(FormalSettlementPaymentRequest request);
|
||||
List<String> applyPayments(FormalSettlementBatchPaymentRequest request);
|
||||
}
|
||||
|
||||
-2
@@ -86,14 +86,12 @@ public class BillLedgerServiceImpl extends BaseServiceImpl<BillLedgerMapper, Bil
|
||||
|
||||
@Override
|
||||
public List<BillLedgerVO> availableOptions(String keyword, Long deptId, Long selectedId) {
|
||||
LocalDate today = LocalDate.now();
|
||||
return list(Wrappers.<BillLedger>lambdaQuery()
|
||||
.and(Func.isNotEmpty(keyword), wrapper -> wrapper.like(BillLedger::getBillNo, keyword)
|
||||
.or().like(BillLedger::getIssuerName, keyword)
|
||||
.or().like(BillLedger::getReceiverName, keyword))
|
||||
.and(wrapper -> wrapper
|
||||
.gt(BillLedger::getAvailableBalance, BigDecimal.ZERO)
|
||||
.ge(BillLedger::getMaturityDate, today)
|
||||
.or(selectedId != null, child -> child.eq(BillLedger::getId, selectedId)))
|
||||
.orderByAsc(BillLedger::getMaturityDate)
|
||||
.orderByDesc(BillLedger::getCreateTime)
|
||||
|
||||
-3
@@ -255,9 +255,6 @@ public class BillPaymentServiceImpl extends BaseServiceImpl<BillPaymentMapper, B
|
||||
}
|
||||
|
||||
private void validateLedgerAmount(BillLedger ledger, BigDecimal usedAmount, Long deptId) {
|
||||
if (ledger.getMaturityDate() != null && ledger.getMaturityDate().isBefore(LocalDate.now())) {
|
||||
throw new ServiceException("所选汇票已到期");
|
||||
}
|
||||
if (usedAmount == null || usedAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
throw new ServiceException("本次使用必须大于0");
|
||||
}
|
||||
|
||||
+38
-4
@@ -35,6 +35,7 @@ import org.springblade.transport.mapper.ReceivablePayableCargoFeeMapper;
|
||||
import org.springblade.transport.mapper.SettlementAdjustmentMapper;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementSaveRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementBatchPaymentRequest;
|
||||
import org.springblade.transport.pojo.dto.FormalSettlementStatusRequest;
|
||||
import org.springblade.transport.pojo.dto.PreSettlementDetailAdjustRequest;
|
||||
import org.springblade.transport.pojo.entity.FormalSettlement;
|
||||
@@ -348,9 +349,40 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String applyPayment(FormalSettlementPaymentRequest request) {
|
||||
FormalSettlement settlement = existing(request.getId());
|
||||
return createPayment(settlement, request.getAppliedAmount(), request.getRemark());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<String> applyPayments(FormalSettlementBatchPaymentRequest request) {
|
||||
if (request == null || request.getItems() == null || request.getItems().isEmpty()) {
|
||||
throw new ServiceException("请至少选择一条正式结算单");
|
||||
}
|
||||
List<FormalSettlementBatchPaymentRequest.Item> items = request.getItems();
|
||||
if (items.stream().anyMatch(item -> item == null || item.getId() == null)) {
|
||||
throw new ServiceException("付款申请单据不能为空");
|
||||
}
|
||||
if (items.stream().map(FormalSettlementBatchPaymentRequest.Item::getId).distinct().count() != items.size()) {
|
||||
throw new ServiceException("付款申请单据不能重复");
|
||||
}
|
||||
List<FormalSettlement> settlements = items.stream().map(item -> existing(item.getId())).toList();
|
||||
Long contractId = settlements.get(0).getContractId();
|
||||
if (items.size() > 1 && (contractId == null
|
||||
|| settlements.stream().anyMatch(item -> !Objects.equals(contractId, item.getContractId())))) {
|
||||
throw new ServiceException("批量付款申请必须选择同一合同的正式结算单");
|
||||
}
|
||||
List<String> paymentNos = new java.util.ArrayList<>();
|
||||
for (int index = 0; index < settlements.size(); index++) {
|
||||
FormalSettlementBatchPaymentRequest.Item item = items.get(index);
|
||||
paymentNos.add(createPayment(settlements.get(index), item.getAppliedAmount(), request.getRemark()));
|
||||
}
|
||||
return paymentNos;
|
||||
}
|
||||
|
||||
private String createPayment(FormalSettlement settlement, BigDecimal appliedAmount, String remark) {
|
||||
if (!APPROVED.equals(settlement.getApprovalStatus())) throw new ServiceException("仅审批通过的正式结算单允许发起付款申请");
|
||||
if (!"payable".equals(settlement.getSettlementType())) throw new ServiceException("仅应付正式结算单允许发起付款申请");
|
||||
BigDecimal amount = positive(request.getAppliedAmount(), "申请付款金额");
|
||||
BigDecimal amount = positive(appliedAmount, "申请付款金额");
|
||||
BigDecimal available = money(settlement.getSettlementAmount()).subtract(money(settlement.getAppliedPaymentAmount()));
|
||||
if (amount.compareTo(available) > 0) throw new ServiceException("申请付款金额不能超过剩余可申请金额" + available);
|
||||
FormalSettlementPayment payment = new FormalSettlementPayment();
|
||||
@@ -360,7 +392,7 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
||||
payment.setAppliedAmount(amount);
|
||||
payment.setPaidAmount(BigDecimal.ZERO);
|
||||
payment.setBillStatus(REVIEWING);
|
||||
payment.setRemark(limit(request.getRemark(), 200));
|
||||
payment.setRemark(limit(remark, 200));
|
||||
paymentMapper.insert(payment);
|
||||
settlement.setAppliedPaymentAmount(money(settlement.getAppliedPaymentAmount()).add(amount));
|
||||
updateById(settlement);
|
||||
@@ -392,7 +424,7 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
||||
FormalSettlementDetailFee fee = existing.get(row.getId());
|
||||
if (fee == null) throw new ServiceException("存在无效的货物费用行");
|
||||
BigDecimal beforeAmount = money(fee.getSettlementAmountTax());
|
||||
fee.setTransportQuantity(nonNegative(row.getTransportQuantity(), "运输总量"));
|
||||
fee.setTransportQuantity(money(nonNegative(row.getTransportQuantity(), "运输总量")));
|
||||
fee.setMileage(nonNegative(row.getMileage(), "里程"));
|
||||
fee.setUnitPrice(nonNegative(row.getUnitPrice(), "运输单价"));
|
||||
fee.setFreightAmount(nonNegative(row.getFreightAmount(), "运费"));
|
||||
@@ -727,7 +759,7 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
||||
detail.setFormalSettlementId(settlement.getId()); detail.setSourceDetailId(source.getId()); detail.setLineNo(lineNo++);
|
||||
detail.setDocumentNo(source.getDocumentNo()); detail.setWaybillId(source.getWaybillId()); detail.setWaybillNo(source.getWaybillNo());
|
||||
detail.setVehicleNo(source.getVehicleNo()); detail.setTransportType(source.getTransportType()); detail.setCargoName(source.getCargoName());
|
||||
detail.setCargoType(source.getCargoType()); detail.setTransportQuantity(source.getTransportQuantity()); detail.setQuantityUnit(source.getQuantityUnit());
|
||||
detail.setCargoType(source.getCargoType()); detail.setTransportQuantity(money(source.getTransportQuantity())); detail.setQuantityUnit(source.getQuantityUnit());
|
||||
detail.setMileage(source.getMileage()); detail.setBatchNo(source.getBatchNo()); detail.setUnitPrice(source.getUnitPrice());
|
||||
detail.setFreightAmount(money(source.getFreightAmount())); detail.setFeeItemsJson(source.getFeeItemsJson());
|
||||
detail.setOriginalAmount(money(source.getTotalAmount())); detail.setAdjustAmount(BigDecimal.ZERO);
|
||||
@@ -757,6 +789,7 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
||||
.eq(PreSettlementDetailFee::getPreSettlementDetailId, source.getId()).orderByAsc(PreSettlementDetailFee::getLineNo));
|
||||
for (PreSettlementDetailFee item : fees) {
|
||||
FormalSettlementDetailFee fee = Objects.requireNonNull(BeanUtil.copyProperties(item, FormalSettlementDetailFee.class));
|
||||
fee.setTransportQuantity(money(fee.getTransportQuantity()));
|
||||
fee.setId(null); fee.setFormalSettlementDetailId(target.getId()); fee.setSourceFeeId(item.getId()); detailFeeMapper.insert(fee);
|
||||
}
|
||||
if (fees.isEmpty()) createSingleFee(target);
|
||||
@@ -767,6 +800,7 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
|
||||
.eq(ReceivablePayableCargoFee::getDetailId, source.getId()).orderByAsc(ReceivablePayableCargoFee::getLineNo));
|
||||
for (ReceivablePayableCargoFee item : fees) {
|
||||
FormalSettlementDetailFee fee = Objects.requireNonNull(BeanUtil.copyProperties(item, FormalSettlementDetailFee.class));
|
||||
fee.setTransportQuantity(money(fee.getTransportQuantity()));
|
||||
fee.setId(null); fee.setFormalSettlementDetailId(target.getId()); fee.setSourceFeeId(item.getId());
|
||||
fee.setSettlementAmountTax(item.getAfterAmount() == null ? money(item.getOriginalAmount()) : item.getAfterAmount());
|
||||
fee.setSettlementAmountNoTax(null); detailFeeMapper.insert(fee);
|
||||
|
||||
+17
-14
@@ -581,10 +581,10 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
|
||||
fee.setFreightAmount(nonNegative(requestRow.getFreightAmount(), "运费"));
|
||||
fee.setFeeItemsJson(JsonUtil.toJson(normalizeFeeItems(requestRow.getFeeItems())));
|
||||
BigDecimal afterAmount = requestRow.getSettlementAmountTax() == null
|
||||
? calculateFeeAmount(fee) : nonNegative(requestRow.getSettlementAmountTax(), "结算金额(含税)");
|
||||
? calculateFeeAmount(fee) : money(requestRow.getSettlementAmountTax());
|
||||
fee.setSettlementAmountTax(afterAmount);
|
||||
fee.setSettlementAmountNoTax(requestRow.getSettlementAmountNoTax() == null ? null
|
||||
: nonNegative(requestRow.getSettlementAmountNoTax(), "结算金额(不含税)"));
|
||||
: money(requestRow.getSettlementAmountNoTax()));
|
||||
fee.setAdjustAmount(afterAmount.subtract(money(fee.getOriginalAmount())));
|
||||
fee.setRemark(limitRemark(requestRow.getRemark(), 200));
|
||||
detailFeeMapper.updateById(fee);
|
||||
@@ -858,16 +858,28 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
|
||||
for (PreSettlementDetailFee feeRow : feeRows) {
|
||||
Map<String, BigDecimal> feeItems = parseFeeItems(feeRow.getFeeItemsJson());
|
||||
boolean containsFreight = feeItems.keySet().stream().anyMatch(this::isFreightFeeItem);
|
||||
BigDecimal componentAmount = feeItems.values().stream().map(this::money)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
if (!containsFreight) {
|
||||
BigDecimal freightAmount = money(feeRow.getFreightAmount());
|
||||
aggregates.merge(
|
||||
summaryKey(feeTypeMap.getOrDefault("运输费", ""), "运输费"),
|
||||
money(feeRow.getFreightAmount()),
|
||||
freightAmount,
|
||||
BigDecimal::add);
|
||||
componentAmount = componentAmount.add(freightAmount);
|
||||
}
|
||||
feeItems.forEach((feeItem, amount) -> aggregates.merge(
|
||||
summaryKey(feeTypeMap.getOrDefault(feeItem,
|
||||
""), feeItem),
|
||||
money(amount), BigDecimal::add));
|
||||
BigDecimal residualAmount = money(money(feeRow.getSettlementAmountTax())
|
||||
.subtract(componentAmount));
|
||||
if (residualAmount.signum() != 0) {
|
||||
aggregates.merge(
|
||||
summaryKey(feeTypeMap.getOrDefault("其他费用", ""), "其他费用"),
|
||||
residualAmount,
|
||||
BigDecimal::add);
|
||||
}
|
||||
}
|
||||
summaryFeeMapper.delete(Wrappers.<PreSettlementSummaryFee>lambdaQuery()
|
||||
.eq(PreSettlementSummaryFee::getPreSettlementId, settlementId)
|
||||
@@ -885,9 +897,6 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
|
||||
row.setAdjustAmount(preserveAdjustments && old != null ? money(old.getAdjustAmount())
|
||||
: BigDecimal.ZERO.setScale(2));
|
||||
row.setSettlementAmount(row.getOriginalAmount().add(row.getAdjustAmount()));
|
||||
if (row.getSettlementAmount().compareTo(BigDecimal.ZERO) < 0) {
|
||||
throw new ServiceException("结算合计金额不能小于0");
|
||||
}
|
||||
row.setRemark(old == null ? "" : old.getRemark());
|
||||
row.setManualFlag(0);
|
||||
summaryFeeMapper.insert(row);
|
||||
@@ -940,9 +949,6 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
|
||||
row.setFeeItem(feeItem);
|
||||
row.setOriginalAmount(BigDecimal.ZERO.setScale(2));
|
||||
row.setAdjustAmount(money(requestRow.getAdjustAmount()));
|
||||
if (row.getAdjustAmount().compareTo(BigDecimal.ZERO) < 0) {
|
||||
throw new ServiceException("手工新增费用金额不能小于0");
|
||||
}
|
||||
row.setSettlementAmount(row.getAdjustAmount());
|
||||
row.setRemark(limitRemark(requestRow.getRemark(), 50));
|
||||
row.setManualFlag(1);
|
||||
@@ -976,9 +982,6 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
|
||||
BigDecimal before = money(row.getAdjustAmount());
|
||||
row.setAdjustAmount(money(requestRow.getAdjustAmount()));
|
||||
row.setSettlementAmount(money(row.getOriginalAmount()).add(row.getAdjustAmount()));
|
||||
if (row.getSettlementAmount().compareTo(BigDecimal.ZERO) < 0) {
|
||||
throw new ServiceException("结算金额不能小于0");
|
||||
}
|
||||
row.setRemark(limitRemark(requestRow.getRemark(), 50));
|
||||
if (row.getId() == null) summaryFeeMapper.insert(row); else summaryFeeMapper.updateById(row);
|
||||
retainedGeneratedIds.add(row.getId());
|
||||
@@ -1048,8 +1051,8 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
|
||||
if (listDetails(settlement.getId()).isEmpty()) {
|
||||
throw new ServiceException("请至少选择一条结算明细");
|
||||
}
|
||||
if (money(settlement.getSettlementAmount()).compareTo(BigDecimal.ZERO) <= 0) {
|
||||
throw new ServiceException("结算金额必须大于0");
|
||||
if (money(settlement.getSettlementAmount()).compareTo(BigDecimal.ZERO) == 0) {
|
||||
throw new ServiceException("结算金额不能为0");
|
||||
}
|
||||
if (!LOCAL_CURRENCY.equalsIgnoreCase(settlement.getCurrency())) {
|
||||
if (settlement.getExchangeRateDate() == null) {
|
||||
|
||||
Reference in New Issue
Block a user