zhaowenxuan
3 天以前 1794429446df460995c5db95729258e922710338
结算价格处理
1个文件已修改
119 ■■■■■ 已修改文件
ltkj-admin/src/main/java/com/ltkj/web/controller/system/TjOrderController.java 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ltkj-admin/src/main/java/com/ltkj/web/controller/system/TjOrderController.java
@@ -14,6 +14,7 @@
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@@ -1575,6 +1576,23 @@
            }
            if(StringUtil.isNotBlank(lycdzjhmxj) && lycdzjhmxj.equalsIgnoreCase("N")){
                BigDecimal paidIn = tjFlowingWater.getPaidIn();
                BigDecimal difference = zongjia.subtract(paidIn);
                if (difference.compareTo(BigDecimal.ZERO) > 0) {
                    log.info("金额多出了:{}",difference);
                    log.info("-----------------------原明细-------------------------");
                    calculateTotalPrice(array,false);
                    log.info("-----------------------新明细-------------------------");
                    adjustPrice(array,paidIn);
                    zongjia = calculateTotalPrice(array,true);
                } else if (difference.compareTo(BigDecimal.ZERO) < 0) {
                    log.info("金额缺少了:{}", difference.abs());
                    log.info("-----------------------原明细-------------------------");
                    calculateTotalPrice(array,false);
                    log.info("-----------------------新明细-------------------------");
                    adjustPrice(array,paidIn);
                    zongjia = calculateTotalPrice(array,true);
                }
                map.put("feiYongInfoList", array);
            }else {
                zongjia = tjFlowingWater.getPaidIn();
@@ -1618,6 +1636,107 @@
        return null;
    }
    /**
     * 判断总价是否一致 是否进行价格补减
     * - 保证所有单价不为负数
     * - 差额分摊策略为:平均分摊 + 误差补最后一项
     *
     * @param items       his传递的明细项目
     * @param targetTotal 总价
     */
    public static void adjustPrice(JSONArray items, BigDecimal targetTotal) {
        BigDecimal actualTotal = BigDecimal.ZERO;
        int size = items.size();
        // 计算目前明细集合总价
        for (int i = 0; i < size; i++) {
            JSONObject item = items.getJSONObject(i);
            BigDecimal danJia = item.getBigDecimal("danJia");
            BigDecimal shuliang = item.getBigDecimal("shuliang");
            BigDecimal jieSuanJe = danJia.multiply(shuliang).setScale(2, RoundingMode.HALF_UP);
            item.set("jieSuanJe", jieSuanJe);
            actualTotal = actualTotal.add(jieSuanJe);
        }
        BigDecimal diff = targetTotal.subtract(actualTotal).setScale(2, RoundingMode.HALF_UP);
        // 无需调整
        if (diff.compareTo(BigDecimal.ZERO) == 0 || size == 0) {
            return;
        }
        // 剩余待分摊差额
        BigDecimal remainingDiff = diff;
        for (int i = 0; i < size; i++) {
            JSONObject item = items.getJSONObject(i);
            BigDecimal danJia = item.getBigDecimal("danJia");
            BigDecimal shuliang = item.getBigDecimal("shuliang");
            if (shuliang.compareTo(BigDecimal.ZERO) == 0) continue;
            // 分摊比例(平均分)
            // 示例:若剩余差额 remainingDiff = 1.50,剩余 3 项,当前 portion = 1.50 ÷ 3 = 0.50
            BigDecimal portion = remainingDiff.divide(new BigDecimal(size - i), 10, RoundingMode.HALF_UP);
            // 分摊到单价上
            // 示例:portion = 0.50,shuliang = 2,deltaPerUnit = 0.25
            BigDecimal deltaPerUnit = portion.divide(shuliang, 10, RoundingMode.HALF_UP);
            // 调整单价:新单价 = 原单价 + 单位差额
            BigDecimal adjustedDanJia = danJia.add(deltaPerUnit).setScale(2, RoundingMode.HALF_UP);
            // 防止负数价格
            if (adjustedDanJia.compareTo(BigDecimal.ZERO) < 0) {
                adjustedDanJia = BigDecimal.ZERO;
            }
            item.set("danJia", adjustedDanJia);
            BigDecimal adjustedJieSuan = adjustedDanJia.multiply(shuliang).setScale(2, RoundingMode.HALF_UP);
            item.set("jieSuanJe", adjustedJieSuan);
            // 计算本次实际调整的差额,继续分摊剩余部分
            BigDecimal oldJieSuan = danJia.multiply(shuliang).setScale(2, RoundingMode.HALF_UP);
            remainingDiff = remainingDiff.subtract(adjustedJieSuan.subtract(oldJieSuan));
        }
        // 若仍存在小额差额(如由于四舍五入导致),尝试把差额补到最后一项
        if (remainingDiff.abs().compareTo(new BigDecimal("0.01")) > 0) {
            JSONObject lastItem = items.getJSONObject(size - 1);
            BigDecimal danJia = lastItem.getBigDecimal("danJia");
            BigDecimal shuliang = lastItem.getBigDecimal("shuliang");
            if (shuliang.compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal delta = remainingDiff.divide(shuliang, 10, RoundingMode.HALF_UP);
                BigDecimal newDanJia = danJia.add(delta).setScale(2, RoundingMode.HALF_UP);
                if (newDanJia.compareTo(BigDecimal.ZERO) < 0) {
                    newDanJia = BigDecimal.ZERO;
                }
                lastItem.set("danJia", newDanJia);
                BigDecimal newJieSuan = newDanJia.multiply(shuliang).setScale(2, RoundingMode.HALF_UP);
                lastItem.set("jieSuanJe", newJieSuan);
            }
        }
    }
    /**
     * 明细价格日志输出
     * @param array
     */
    public static BigDecimal calculateTotalPrice(JSONArray array,Boolean isOverride) {
        BigDecimal total = BigDecimal.ZERO;
        for (int i = 0; i < array.size(); i++) {
            JSONObject obj = array.getJSONObject(i);
            BigDecimal danJia = new BigDecimal(obj.getStr("danJia", "0")).setScale(2, RoundingMode.HALF_UP);
            BigDecimal shuliang = new BigDecimal(obj.getStr("shuliang", "0")).setScale(2, RoundingMode.HALF_UP);
            BigDecimal jieSuanJe = danJia.multiply(shuliang).setScale(2, RoundingMode.HALF_UP);
            obj.set("danJia", danJia);
            obj.set("shuliang", shuliang);
            obj.set("jieSuanJe", jieSuanJe);
            total = total.add(jieSuanJe);
            log.info(String.format("第%d项 -> 单价: %s, 数量: %s, 结算金额: %s", i + 1, danJia, shuliang, jieSuanJe));
        }
        log.info("总价为: {}", total.setScale(2, RoundingMode.HALF_UP));
        if (isOverride) return total.setScale(2, RoundingMode.HALF_UP);
        return null;
    }
    public void addCaiYangDengJi(List<TjOrderDetail> detailList, boolean detailList1, TjOrder order, SysUser sysUser, String jxbz) {
        String lis_tmh_prefix = configService.selectConfigByKey("make_lis_tmh_prefix");
        String config = configService.selectConfigByKey("sfkqdyhis");