cl
22 小时以前 91831843f3b9fa4c9f29e518e10dae5d3f9aead8
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java
@@ -406,64 +406,58 @@
            return R.error("单据信息不存在!!");
        }
        List<TaskItem> taskItems = params.getTaskItems();
        Map<String, List<TaskItem>> listMap = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getMatnrCode));
        // 拣货完成仅扣减库位数量并累加 TaskItem.qty,不更新出库单/订单;待托盘全部拣完在 saveWavePick 再按顺序更新库存并校验
        // 按订单明细行区分:同单同物料多行不得按 matnr 合并
        Config config = configService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getFlag, GlobalConfigCode.ALLOW_OVER_CHANGE));
        listMap.keySet().forEach(code -> {
            List<TaskItem> items = listMap.get(code);
            WkOrderItem orderItem = asnOrderItemService.getOne(new LambdaQueryWrapper<WkOrderItem>()
                    .eq(WkOrderItem::getMatnrCode, code)
                    .eq(WkOrderItem::getOrderId, order.getId()));
        Map<Long, Double> batchPickSumByOrderItem = new HashMap<>();
        for (TaskItem taskItemParam : taskItems) {
            TaskItem item = taskItemService.getById(taskItemParam.getId());
            if (Objects.isNull(item)) {
                throw new CoolException("任务明细不存在!!");
            }
            WkOrderItem orderItem = resolveOrderItemForPick(item, order.getId());
            if (Objects.isNull(orderItem)) {
                throw new CoolException("数据错误,拣料不在单据需求中!!");
            }
            Double summed = items.stream().mapToDouble(ti -> ti.getAnfme() != null ? ti.getAnfme() : 0.0).sum();
            Double pickQty = Math.round((orderItem.getQty() != null ? orderItem.getQty() : 0.0) + summed) * 1000000.0 / 1000000.0;
            Double pickInc = taskItemParam.getAnfme() != null ? taskItemParam.getAnfme() : 0.0;
            Double prevBatch = batchPickSumByOrderItem.getOrDefault(orderItem.getId(), 0.0);
            Double pickQty = Math.round((orderItem.getQty() != null ? orderItem.getQty() : 0.0) + prevBatch + pickInc) * 1000000.0 / 1000000.0;
            if (!Objects.isNull(config) && !Boolean.parseBoolean(config.getVal())) {
                if (pickQty.compareTo(orderItem.getAnfme()) > 0.0) {
                    throw new CoolException("播种数量不能超出订单需求数量");
                }
                Double v = Math.round(((item.getQty() != null ? item.getQty() : 0.0) + pickInc) * 1000000.0) / 1000000.0;
                if (item.getAnfme() != null && item.getAnfme().compareTo(v) < 0.0) {
                    throw new CoolException("当前物料已超出可拣范围,请核对后再操作!!");
                }
            }
            items.forEach(taskItem -> {
                TaskItem item = taskItemService.getById(taskItem.getId());
                if (Objects.isNull(item)) {
                    throw new CoolException("任务明细不存在!!");
                }
                if (!Objects.isNull(config) && !Boolean.parseBoolean(config.getVal())) {
                    Double v = Math.round(((item.getQty() != null ? item.getQty() : 0.0) + (taskItem.getAnfme() != null ? taskItem.getAnfme() : 0.0)) * 1000000.0) / 1000000.0;
                    if (item.getAnfme() != null && item.getAnfme().compareTo(v) < 0.0) {
                        throw new CoolException("当前物料已超出可拣范围,请核对后再操作!!");
                    }
                }
                Double picQty = Math.round(((item.getQty() != null ? item.getQty() : 0.0) + (taskItem.getAnfme() != null ? taskItem.getAnfme() : 0.0)) * 1000000.0) / 1000000.0;
                item.setQty(picQty).setOrderId(order.getId()).setOrderItemId(orderItem.getId());
                if (!taskItemService.updateById(item)) {
                    throw new CoolException("拣货数量更新失败!!");
                }
                if (StringUtils.isNotBlank(task.getOrgLoc())) {
                    LocItem locItem = locItemService.getOne(new LambdaQueryWrapper<LocItem>()
                            .eq(LocItem::getLocCode, task.getOrgLoc())
                            .eq(LocItem::getMatnrId, item.getMatnrId())
                            .eq(StringUtils.isNotBlank(item.getBatch()), LocItem::getBatch, item.getBatch())
                            .eq(StringUtils.isNotBlank(item.getFieldsIndex()), LocItem::getFieldsIndex, item.getFieldsIndex()));
                    if (Objects.nonNull(locItem)) {
                        Double pickAmt = taskItem.getAnfme() != null ? taskItem.getAnfme() : 0.0;
                        Double newAnfme = Math.round((locItem.getAnfme() - pickAmt) * 1000000.0) / 1000000.0;
                        if (newAnfme.compareTo(0.0) <= 0) {
                            locItemService.removeById(locItem.getId());
                        } else {
                            locItem.setAnfme(newAnfme)
                                    .setUpdateBy(SystemAuthUtils.getLoginUserId())
                                    .setUpdateTime(new Date());
                            if (!locItemService.updateById(locItem)) {
                                throw new CoolException("库位明细数量扣减失败!!");
                            }
            batchPickSumByOrderItem.merge(orderItem.getId(), pickInc, (a, b) -> (a != null ? a : 0.0) + (b != null ? b : 0.0));
            Double picQty = Math.round(((item.getQty() != null ? item.getQty() : 0.0) + pickInc) * 1000000.0) / 1000000.0;
            item.setQty(picQty).setOrderId(order.getId()).setOrderItemId(orderItem.getId());
            if (!taskItemService.updateById(item)) {
                throw new CoolException("拣货数量更新失败!!");
            }
            if (StringUtils.isNotBlank(task.getOrgLoc())) {
                LocItem locItem = locItemService.getOne(new LambdaQueryWrapper<LocItem>()
                        .eq(LocItem::getLocCode, task.getOrgLoc())
                        .eq(LocItem::getMatnrId, item.getMatnrId())
                        .eq(StringUtils.isNotBlank(item.getBatch()), LocItem::getBatch, item.getBatch())
                        .eq(StringUtils.isNotBlank(item.getFieldsIndex()), LocItem::getFieldsIndex, item.getFieldsIndex()));
                if (Objects.nonNull(locItem)) {
                    Double pickAmt = pickInc;
                    Double newAnfme = Math.round((locItem.getAnfme() - pickAmt) * 1000000.0) / 1000000.0;
                    if (newAnfme.compareTo(0.0) <= 0) {
                        locItemService.removeById(locItem.getId());
                    } else {
                        locItem.setAnfme(newAnfme)
                                .setUpdateBy(SystemAuthUtils.getLoginUserId())
                                .setUpdateTime(new Date());
                        if (!locItemService.updateById(locItem)) {
                            throw new CoolException("库位明细数量扣减失败!!");
                        }
                    }
                }
            });
        });
            }
        }
        return R.ok();
    }
@@ -607,18 +601,27 @@
            WkOrder order = asnOrderService.getById(orderId);
            if (order == null) continue;
            List<TaskItem> items = byOrder.get(orderId);
            Map<String, List<TaskItem>> byMatnr = items.stream().collect(Collectors.groupingBy(TaskItem::getMatnrCode));
            for (String code : byMatnr.keySet()) {
                List<TaskItem> matItems = byMatnr.get(code);
                WkOrderItem orderItem = asnOrderItemService.getOne(new LambdaQueryWrapper<WkOrderItem>()
                        .eq(WkOrderItem::getMatnrCode, code)
                        .eq(WkOrderItem::getOrderId, orderId));
                if (orderItem == null) continue;
            Map<Long, List<TaskItem>> byOrderItem = new LinkedHashMap<>();
            for (TaskItem ti : items) {
                WkOrderItem oi = resolveOrderItemForPick(ti, orderId);
                if (oi == null) {
                    continue;
                }
                byOrderItem.computeIfAbsent(oi.getId(), k -> new ArrayList<>()).add(ti);
            }
            for (Map.Entry<Long, List<TaskItem>> e : byOrderItem.entrySet()) {
                WkOrderItem orderItem = asnOrderItemService.getById(e.getKey());
                if (orderItem == null) {
                    continue;
                }
                List<TaskItem> matItems = e.getValue();
                Double summed = matItems.stream().mapToDouble(t -> t.getQty() != null ? t.getQty() : 0.0).sum();
                orderItem.setQty(summed);
                asnOrderItemService.updateById(orderItem);
                String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_STOCK_CODE, null);
                if (StringUtils.isBlank(ruleCode)) continue;
                if (StringUtils.isBlank(ruleCode)) {
                    continue;
                }
                Stock stock = new Stock();
                stock.setCode(ruleCode)
                        .setUpdateBy(loginUserId)
@@ -630,7 +633,9 @@
                        .setSourceCode(orderItem.getOrderCode())
                        .setUpdateTime(new Date())
                        .setAnfme(summed);
                if (!stockService.save(stock)) continue;
                if (!stockService.save(stock)) {
                    continue;
                }
                List<StockItem> stockItems = new ArrayList<>();
                for (TaskItem ti : matItems) {
                    StockItem si = new StockItem();
@@ -666,6 +671,31 @@
    }
    /**
     * 波次拣货:任务明细与订单行对应(orderItemId 优先,否则行内码 platItemId),避免同单同料多行只命中一条
     */
    private WkOrderItem resolveOrderItemForPick(TaskItem taskItem, Long orderId) {
        if (taskItem.getOrderItemId() != null) {
            WkOrderItem oi = asnOrderItemService.getById(taskItem.getOrderItemId());
            if (oi != null && orderId.equals(oi.getOrderId())) {
                return oi;
            }
        }
        if (StringUtils.isNotBlank(taskItem.getPlatItemId())) {
            WkOrderItem oi = asnOrderItemService.getOne(new LambdaQueryWrapper<WkOrderItem>()
                    .eq(WkOrderItem::getOrderId, orderId)
                    .eq(WkOrderItem::getPlatItemId, taskItem.getPlatItemId())
                    .last("LIMIT 1"));
            if (oi != null) {
                return oi;
            }
        }
        return asnOrderItemService.getOne(new LambdaQueryWrapper<WkOrderItem>()
                .eq(WkOrderItem::getMatnrCode, taskItem.getMatnrCode())
                .eq(WkOrderItem::getOrderId, orderId)
                .last("LIMIT 1"));
    }
    private Boolean checkWaveComplete(TaskItem taskItem) {
        Wave wave = waveService.getById(taskItem.getSourceId());
        List<WkOrder> wkOrderList = asnOrderService.list(new LambdaQueryWrapper<WkOrder>().eq(WkOrder::getWaveId, wave.getId()));