Commit fa350536 by jianan

分期出账优化、应收款应付款金额精度3

parent baf660f8
......@@ -37,6 +37,7 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
......@@ -850,34 +851,42 @@ public class FortuneServiceImpl extends ServiceImpl<FortuneMapper, Fortune>
List<FortuneSplitDto> splitList = fortuneSplitRequest.getFortuneSplitDtoList();
// 3. 保单币锚守恒:Σ各期保单币份额 严格等于原记录 ruleAmount(来的钱,2位)
BigDecimal originalRuleAmount = originalFortune.getRuleAmount();
int lastIndex = splitList.size() - 1;
// 3. 保单币金额守恒:Σ各期 ruleAmount 必须等于原锚。
// 各期金额由财务人工维护,系统不判断各期该填多少;总平不上时只给出末期找平金额,帮其通过校验。
BigDecimal totalRuleAmount = splitList.stream()
.map(FortuneSplitDto::getRuleAmount)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
if (totalRuleAmount.compareTo(originalFortune.getRuleAmount()) != 0) {
throw new BusinessException(ResultCode.PARAM_CHECK_ERROR.getCode(),
String.format("分期保单币金额总和(%s)与原记录保单币金额(%s)必须一致",
totalRuleAmount, originalFortune.getRuleAmount()));
if (totalRuleAmount.compareTo(originalRuleAmount) != 0) {
BigDecimal sumBeforeLast = BigDecimal.ZERO;
for (int i = 0; i < lastIndex; i++) {
if (splitList.get(i).getRuleAmount() != null) {
sumBeforeLast = sumBeforeLast.add(splitList.get(i).getRuleAmount());
}
}
// 末期找平金额 = 原锚 - Σ前n-1期(精确到2位,填此值必能过校验)
BigDecimal lastLevelAmount = originalRuleAmount.subtract(sumBeforeLast)
.setScale(2, RoundingMode.HALF_UP);
String tip = lastLevelAmount.signum() >= 0
? String.format("「保单币种金额」不平:各期合计 %s,应等于 %s。请将最后一期(第%d期)的「保单币种金额」改为 %s 后提交",
totalRuleAmount, originalRuleAmount, splitList.size(), lastLevelAmount.toPlainString())
: String.format("前%d期「保单币种金额」合计 %s,已超过应发金额 %s,请调减前期金额后提交",
lastIndex, sumBeforeLast, originalRuleAmount);
throw new BusinessException(ResultCode.PARAM_CHECK_ERROR.getCode(), tip);
}
// 4. 每期港币必须为非负整数(元)。各期汇率可能不同,港币合计不卡总额,以Σ为实际发放港币
// 4. 每期港币必须为非负整数(元)。各期汇率可能不同、港币可手改,港币合计不卡总额。
for (FortuneSplitDto dto : splitList) {
if (dto.getHkdAmount() == null || dto.getHkdAmount().signum() < 0
|| dto.getHkdAmount().stripTrailingZeros().scale() > 0) {
throw new BusinessException(ResultCode.PARAM_CHECK_ERROR.getCode(), "每期港币金额必须为非负整数(元)");
}
}
// 5. 比例总和必须严格等于 100
BigDecimal totalSplitRatio = splitList.stream()
.map(FortuneSplitDto::getSplitRatio)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
if (totalSplitRatio.compareTo(BigDecimal.ZERO) > 0
&& totalSplitRatio.compareTo(new BigDecimal("100")) != 0) {
throw new BusinessException(ResultCode.PARAM_CHECK_ERROR.getCode(),
String.format("分期比例总和(%s%%)必须为100%%", totalSplitRatio));
}
// 比例不再校验合计=100:金额由人工维护,比例仅作前端算金额的输入与记录参考;
// 若同时卡比例=100,会与金额守恒在舍入场景下互斥(如33.33×3金额合计差0.01),无法提交。
// 4. 生成新记录
List<Fortune> newFortuneList = new ArrayList<>();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment