From 98d88ac8caf7f0991d741079474c262f1e252927 Mon Sep 17 00:00:00 2001
From: chen.lin <1442464845@qq.com>
Date: 星期五, 06 三月 2026 08:14:54 +0800
Subject: [PATCH] 拣货过程中的出库库存匹配

---
 rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java |  371 ++++++++++++++++++++++++++++++-----------------------
 1 files changed, 210 insertions(+), 161 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java
index 8de29f8..fb2e32f 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java
@@ -5,6 +5,8 @@
 import com.vincent.rsf.framework.common.R;
 import com.vincent.rsf.framework.exception.CoolException;
 import com.vincent.rsf.server.api.entity.dto.ContainerWaveDto;
+import com.vincent.rsf.server.api.entity.dto.ContainerWaveItemDto;
+import com.vincent.rsf.server.api.entity.dto.QuickPickOrderModuleDto;
 import com.vincent.rsf.server.api.entity.params.ContainerWaveParam;
 import com.vincent.rsf.server.api.entity.params.WavePickItemsParams;
 import com.vincent.rsf.server.api.service.PdaOutStockService;
@@ -76,70 +78,132 @@
     @Autowired
     private ConfigServiceImpl configService;
 
+    /**
+     * 蹇�熸嫞璐ф煡璇細鍚屼竴绠辩爜鍙兘鏈夊鏉′换鍔★紝浠� RCS 鍑哄簱鍥炶皟鍚庡彉涓� 199 鐨勬墠灞曠ず锛涜绠辩爜涓嬩粛涓嶆槸 199 鐨� PDA 涓嶆樉绀恒��
+     * 杩斿洖锛歰rders 鎸夊嚭搴撳崟鍒嗘ā鍧椼�乴ist/taskItems 璇ョ鐮佷笅 199 浠诲姟鏄庣粏銆�
+     */
     @Override
     public R getOutStockTaskItem(String barcode) {
-        LambdaQueryWrapper<Task> lambdaQueryWrapper = new LambdaQueryWrapper<>();
-        lambdaQueryWrapper.eq(Task::getBarcode, barcode)
-                .orderByDesc(Task::getId)
-                .last("limit 1");
-        Task task = taskService.getOne(lambdaQueryWrapper);
-        if (null == task) {
-            return R.error("鏈煡璇㈠埌鐩稿叧浠诲姟");
+        // 鍙煡 199锛圵AVE_SEED锛�/AWAIT锛氬凡纭鍙樻垚 200 鐨勭粷涓嶈兘鎵嚭鏉ワ紝鏄庣‘鎺掗櫎 200 閬垮厤绗簩娆℃壂鍒�
+        List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>()
+                .eq(Task::getBarcode, barcode)
+                .in(Task::getTaskStatus, Arrays.asList(TaskStsType.WAVE_SEED.id, TaskStsType.AWAIT.id))
+                .ne(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id)
+                .orderByAsc(Task::getId));
+        if (tasks == null || tasks.isEmpty()) {
+            return R.error("鏈煡璇㈠埌寰呯‘璁や换鍔�");
         }
-        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
-        if (null == taskItems || taskItems.size() <= 0) {
+        List<Long> taskIds = tasks.stream().map(Task::getId).collect(Collectors.toList());
+        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().in(TaskItem::getTaskId, taskIds));
+        if (taskItems == null || taskItems.isEmpty()) {
             return R.error("浠诲姟鍑洪敊锛屾湭鏌ヨ鍒扮浉鍏充换鍔℃槑缁�");
         }
-
-        return R.ok(taskItems);
+        // 鍚屼竴绠辩爜涓嬪彲鑳芥湁澶氭潯锛堝涓嚭搴撳崟锛夛紝鎸夊嚭搴撳崟鍒嗙粍锛涗粎杩斿洖灏氭湭鎷e畬鐨勮鍗曟ā鍧�
+        String nullKey = "__none__";
+        Map<String, List<TaskItem>> byOrder = taskItems.stream()
+                .collect(Collectors.groupingBy(ti -> ti.getOrderId() != null ? "o_" + ti.getOrderId() : (StringUtils.isNotBlank(ti.getSourceCode()) ? "s_" + ti.getSourceCode() : nullKey)));
+        List<QuickPickOrderModuleDto> orders = new ArrayList<>();
+        for (Map.Entry<String, List<TaskItem>> e : byOrder.entrySet()) {
+            List<TaskItem> items = e.getValue();
+            boolean allPicked = items.stream().allMatch(ti -> ti.getQty() != null && ti.getAnfme() != null && ti.getQty().compareTo(ti.getAnfme()) >= 0);
+            if (allPicked) continue;
+            TaskItem first = items.get(0);
+            orders.add(new QuickPickOrderModuleDto()
+                    .setOrderId(first.getOrderId())
+                    .setOrderCode(StringUtils.isNotBlank(first.getSourceCode()) ? first.getSourceCode() : ("鍗曞彿:" + (first.getOrderId() != null ? first.getOrderId() : "鈥�")))
+                    .setItems(items));
+        }
+        R r = orders.isEmpty() ? R.ok("鍏ㄩ儴鎷h揣宸插畬鎴�") : R.ok();
+        r.put("orders", orders);
+        r.put("taskItems", taskItems);
+        r.put("list", taskItems); // 鍚屼竴绠辩爜涓嬪鏉℃槑缁嗭紝渚夸簬鐩存帴灞曠ず
+        return r;
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     @Synchronized
     public R saveOutTaskSts(String barcode) {
-        LambdaQueryWrapper<Task> lambdaQueryWrapper = new LambdaQueryWrapper<>();
-        lambdaQueryWrapper.eq(Task::getBarcode, barcode)
-                .orderByDesc(Task::getId)
-                .last("limit 1");
-        Task task = taskService.getOne(lambdaQueryWrapper);
-        if (null == task) {
-            throw new CoolException("鏈壘鍒版枡绠辩爜瀵瑰簲浠诲姟");
+        // 鍙粺璁″綋鍓嶃�屽緟纭銆嶄换鍔★細鍑哄簱鍗曟湁3鍗曚絾鍙笅鍙戜簡2涓换鍔℃椂锛�2涓换鍔¢兘鎷e畬鍗冲彲纭骞剁敓鎴愭嫞鏂欏叆搴擄紱鏈変换鍔¤鍙栨秷鍒欏彧澶勭悊鍓╀綑浠诲姟
+        List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>()
+                .eq(Task::getBarcode, barcode)
+                .in(Task::getTaskStatus, Arrays.asList(TaskStsType.WAVE_SEED.id, TaskStsType.AWAIT.id))
+                .orderByAsc(Task::getId));
+        if (tasks == null || tasks.isEmpty()) {
+            throw new CoolException("鏈壘鍒版枡绠辩爜瀵瑰簲浠诲姟鎴栦换鍔$姸鎬佷笉鏄瓑寰呯‘璁�");
         }
-        // 鍏佽 199锛圵AVE_SEED 鎾涓�/寰呯‘璁わ級鎴� 196锛圓WAIT 绛夊緟纭锛夛紝涓庣洏鐐� PDA 閫昏緫涓�鑷�
-        if (!task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)
-                && !task.getTaskStatus().equals(TaskStsType.AWAIT.id)) {
-            return R.error("浠诲姟鐘舵�佷笉鏄瓑寰呯‘璁�");
-        }
-        
         Long loginUserId = SystemAuthUtils.getLoginUserId();
         if (loginUserId == null) {
-            loginUserId = 1L; // 浣跨敤榛樿鍊�
+            loginUserId = 1L;
         }
-        
         try {
-            if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) {
-                // 鎷f枡鍑哄簱锛氬垱寤烘嫞鏂欏叆搴撲换鍔★紙褰㈡垚闂幆锛�
-                taskService.pickOrCheckTask(task.getId(), "");
-                return R.ok("纭鎴愬姛锛屽凡鍒涘缓鎷f枡鍏ュ簱浠诲姟");
-            } else if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
-                // 鐩樼偣鍑哄簱锛氬垱寤虹洏鐐瑰叆搴撲换鍔★紙褰㈡垚闂幆锛�
-                taskService.pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_CHECK);
+            Task first = tasks.get(0);
+            if (first.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) {
+                // 纭鍓嶈绠辩爜涓嬪凡鏈� 200 鐨勶紙渚嬪绗竴娆″凡纭鐨勶級锛氭湰娆″彧鎶婂綋鍓� 199 缃负 200锛屼笉鐢熸垚鎷f枡鍏ュ簱锛岄伩鍏嶁�滅浜屾璇‘璁も�濆鑷撮敊璇墸鍑忓拰鐢熸垚鍏ュ簱
+                long already200 = taskService.count(new LambdaQueryWrapper<Task>()
+                        .eq(Task::getBarcode, barcode)
+                        .eq(Task::getTaskType, TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)
+                        .eq(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id));
+                // 纭鍗冲凡纭锛氬綋鍓� 199 浠诲姟鍏ㄩ儴缃负 200锛屽苟鍥炲啓宸叉嫞鏁伴噺(qty)锛涗粎褰撴湰娆$‘璁ゅ墠娌℃湁浠讳綍 200 涓旂‘璁ゅ悗鍏ㄩ儴 200 鏃舵墠缁熶竴鎵e噺骞剁敓鎴愭嫞鏂欏叆搴�
+                for (Task task : tasks) {
+                    task.setTaskStatus(TaskStsType.UPDATED_OUT.id)
+                            .setUpdateBy(loginUserId)
+                            .setUpdateTime(new Date());
+                    if (!taskService.updateById(task)) {
+                        return R.error("鏇存柊浠诲姟鐘舵�佸け璐�");
+                    }
+                    List<TaskItem> items = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
+                    for (TaskItem ti : items) {
+                        if (ti.getQty() == null || ti.getQty().compareTo(0.0) <= 0) {
+                            ti.setQty(ti.getAnfme() != null ? ti.getAnfme() : 0.0);
+                            ti.setUpdateBy(loginUserId);
+                            ti.setUpdateTime(new Date());
+                            taskItemService.updateById(ti);
+                        }
+                    }
+                }
+                long not200 = taskService.count(new LambdaQueryWrapper<Task>()
+                        .eq(Task::getBarcode, barcode)
+                        .ne(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id));
+                if (not200 > 0) {
+                    return R.ok("纭鎴愬姛");
+                }
+                // 鏈纭鍓嶈绠辩爜涓嬪凡鏈� 200 鐨勶紝涓嶅湪姝ゅ鐢熸垚鎷f枡鍏ュ簱锛岀敱瀹氭椂浠诲姟鍦ㄢ�滃叏閮� 200鈥濇椂缁熶竴澶勭悊
+                if (already200 > 0) {
+                    return R.ok("纭鎴愬姛锛涘悓绠卞凡鏈夎繃纭浠诲姟锛屾墸鍑忎笌鎷f枡鍏ュ簱鐢辩郴缁熷湪鍏ㄩ儴200鍚庣粺涓�澶勭悊");
+                }
+                // 鏈纭鍓嶆病鏈変换浣� 200锛屼笖纭鍚庡悓绠辩爜宸插叏閮� 200锛氱粺涓�鎵e噺銆佹湁浣欓噺鎵嶇敓鎴愭嫞鏂欏叆搴撳崟
+                List<Task> all200 = taskService.list(new LambdaQueryWrapper<Task>()
+                        .eq(Task::getBarcode, barcode)
+                        .eq(Task::getTaskType, TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)
+                        .eq(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id)
+                        .orderByAsc(Task::getId));
+                for (Task task : all200) {
+                    taskService.pickOrCheckTask(task.getId(), "");
+                }
+                return R.ok("纭鎴愬姛锛屽凡缁熶竴鎵e噺骞剁敓鎴愭嫞鏂欏叆搴撲换鍔★紙鏈変綑閲忔椂锛�");
+            }
+            if (first.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
+                for (Task task : tasks) {
+                    taskService.pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_CHECK);
+                }
                 return R.ok("纭鎴愬姛锛屽凡鍒涘缓鐩樼偣鍏ュ簱浠诲姟");
-            } else if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) {
-                // 鍏ㄧ増鍑哄簱锛氭洿鏂颁负200锛堟渶缁堝畬鎴愶紝涓嶉棴鐜級
-                taskService.completeFullOutStock(task.getId(), loginUserId);
+            }
+            if (first.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) {
+                for (Task task : tasks) {
+                    taskService.completeFullOutStock(task.getId(), loginUserId);
+                }
                 return R.ok("纭鎴愬姛锛屽叏鐗堝嚭搴撳凡瀹屾垚");
-            } else {
-                // 鍏朵粬鍑哄簱绫诲瀷锛氱洿鎺ユ洿鏂颁负200
+            }
+            for (Task task : tasks) {
                 task.setTaskStatus(TaskStsType.UPDATED_OUT.id)
                         .setUpdateBy(loginUserId)
                         .setUpdateTime(new Date());
                 if (!taskService.updateById(task)) {
                     return R.error("鏇存柊浠诲姟鐘舵�佸け璐�");
                 }
-                return R.ok("纭鎴愬姛");
             }
+            return R.ok("纭鎴愬姛");
         } catch (Exception e) {
             throw new CoolException("蹇�熸嫞璐х‘璁ゅけ璐ワ細" + e.getMessage());
         }
@@ -168,24 +232,47 @@
         if (!task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) {
             return R.error("浠诲姟鐘舵�佷笉鏄弨鏂欑媭鎱�");
         }
-        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
-        Set<Long> longSet = taskItems.stream().map(TaskItem::getSourceId).collect(Collectors.toSet());
-        List<WaveOrderRela> waveOrderRelas = waveOrderRelaService.list(new LambdaQueryWrapper<WaveOrderRela>()
-                .in(WaveOrderRela::getWaveId, longSet));
-        if (Cools.isEmpty(waveOrderRelas)) {
+        // 褰撳墠鏂欑瀵瑰簲搴撲綅涓嬫墍鏈夊浜庛�岄绾﹀嚭搴�/鎷h揣涓�嶇殑浠诲姟锛堝惈鍙拷鍔犵殑鍚庣画璁㈠崟锛�
+        String orgLoc = task.getOrgLoc();
+        List<Integer> pickingStatuses = Arrays.asList(TaskStsType.GENERATE_OUT.id, TaskStsType.WAVE_SEED.id);
+        List<Task> sameLocTasks = taskService.list(new LambdaQueryWrapper<Task>()
+                .eq(Task::getOrgLoc, orgLoc)
+                .in(Task::getTaskStatus, pickingStatuses));
+        Set<Long> waveIds = new java.util.HashSet<>();
+        Set<String> matnrCodes = new java.util.HashSet<>();
+        for (Task t : sameLocTasks) {
+            List<TaskItem> items = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, t.getId()));
+            for (TaskItem ti : items) {
+                if (ti.getSourceId() != null) waveIds.add(ti.getSourceId());
+                if (StringUtils.isNotBlank(ti.getMatnrCode())) matnrCodes.add(ti.getMatnrCode());
+            }
+        }
+        if (waveIds.isEmpty()) {
             throw new CoolException("娉㈡瀵瑰簲鍏宠仈鍗曟湭鎵惧埌");
         }
+        List<WaveOrderRela> waveOrderRelas = waveOrderRelaService.list(new LambdaQueryWrapper<WaveOrderRela>()
+                .in(WaveOrderRela::getWaveId, waveIds));
         Set<Long> orderIds = waveOrderRelas.stream().map(WaveOrderRela::getOrderId).collect(Collectors.toSet());
         List<WkOrder> wkOrders = asnOrderService.listByIds(orderIds);
         if (wkOrders.isEmpty()) {
             throw new CoolException("鍗曟嵁涓嶅瓨鍦紒锛�");
         }
-        Set<String> codes = taskItems.stream().map(TaskItem::getMatnrCode).collect(Collectors.toSet());
+        // 鎸夎鍗曞垱寤烘椂闂存帓搴忥紝鍏堝垱寤虹殑涓轰富璁㈠崟锛屽悗缁负鍙拷鍔�
+        wkOrders.sort(Comparator.comparing(WkOrder::getCreateTime, Comparator.nullsLast(Comparator.naturalOrder())));
+        Set<String> codes = matnrCodes.isEmpty() ? taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()))
+                .stream().map(TaskItem::getMatnrCode).filter(StringUtils::isNotBlank).collect(Collectors.toSet()) : matnrCodes;
         List<WkOrderItem> orderItems = asnOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>()
                 .in(WkOrderItem::getMatnrCode, codes)
                 .in(WkOrderItem::getOrderId, orderIds));
-
-        return R.ok("鏌ヨ鎴愬姛").add(orderItems);
+        List<ContainerWaveItemDto> result = new ArrayList<>();
+        Long firstOrderId = wkOrders.isEmpty() ? null : wkOrders.get(0).getId();
+        for (WkOrderItem item : orderItems) {
+            boolean appendable = firstOrderId != null && !firstOrderId.equals(item.getOrderId());
+            result.add(new ContainerWaveItemDto().setOrderItem(item).setAppendable(appendable));
+        }
+        R r = R.ok("鏌ヨ鎴愬姛");
+        r.put("list", result);
+        return r;
 
 //        ArrayList<ContainerWaveDto> containerWaveDtos = new ArrayList<>();
 ////        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
@@ -320,109 +407,52 @@
         }
         List<TaskItem> taskItems = params.getTaskItems();
         Map<String, List<TaskItem>> listMap = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getMatnrCode));
+        // 鎷h揣瀹屾垚浠呮墸鍑忓簱浣嶆暟閲忓苟绱姞 TaskItem.qty锛屼笉鏇存柊鍑哄簱鍗�/璁㈠崟锛涘緟鎵樼洏鍏ㄩ儴鎷e畬鍦� saveWavePick 鍐嶆寜椤哄簭鏇存柊搴撳瓨骞舵牎楠�
+        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()));
             if (Objects.isNull(orderItem)) {
                 throw new CoolException("鏁版嵁閿欒锛屾嫞鏂欎笉鍦ㄥ崟鎹渶姹備腑锛侊紒");
             }
-            //taskItems涓烘嫞璐ф槑缁嗭紝浣滃弬鏁颁笂鎶�
-            Double summed = items.stream().mapToDouble(TaskItem::getAnfme).sum();
-            //鍔犱笂鍘嗗彶鎷f枡鏁伴噺
-            Double pickQty = Math.round((orderItem.getQty() + summed) * 1000000) / 1000000.0;
-            Config config = configService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getFlag, GlobalConfigCode.ALLOW_OVER_CHANGE));
-            //鍒ゆ柇鏄惁鍏佽瓒呮敹锛屼笉鍏佽瓒呮敹娣诲姞鎷掓敹鍒ゆ柇
-            if (!Objects.isNull(config)) {
-                if (!Boolean.parseBoolean(config.getVal())) {
-                    if (pickQty.compareTo(orderItem.getAnfme()) > 0.0) {
-                        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;
+            if (!Objects.isNull(config) && !Boolean.parseBoolean(config.getVal())) {
+                if (pickQty.compareTo(orderItem.getAnfme()) > 0.0) {
+                    throw new CoolException("鎾鏁伴噺涓嶈兘瓒呭嚭璁㈠崟闇�姹傛暟閲�");
                 }
             }
 
-            orderItem.setQty(pickQty);
-
-            if (!asnOrderItemService.updateById(orderItem)) {
-                throw new CoolException("鍑哄簱鍗曟槑缁嗘洿鏂板け璐ワ紒锛�");
-            }
-
-            Stock stock = new Stock();
-            String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_STOCK_CODE, null);
-            if (StringUtils.isBlank(ruleCode)) {
-                throw new CoolException("褰撳墠涓氬姟锛�" + SerialRuleCode.SYS_STOCK_CODE + "锛岀紪鐮佽鍒欎笉瀛樺湪锛侊紒");
-            }
-            Double sum = taskItems.stream().mapToDouble(TaskItem::getAnfme).sum();
-            stock.setCode(ruleCode)
-                    .setUpdateBy(SystemAuthUtils.getLoginUserId())
-                    .setBarcode(task.getBarcode())
-                    .setLocCode(task.getOrgLoc())
-                    .setType(order.getType())
-                    .setWkType(Short.parseShort(order.getWkType()))
-                    .setSourceId(orderItem.getOrderId())
-                    .setSourceCode(orderItem.getOrderCode())
-                    .setUpdateTime(new Date())
-                    .setAnfme(sum);
-
-            if (!stockService.save(stock)) {
-                throw new CoolException("鍑哄叆搴撳巻鍙蹭繚瀛樺け璐ワ紒锛�");
-            }
-
-           List<StockItem> stockItems = new ArrayList<>();
             items.forEach(taskItem -> {
                 TaskItem item = taskItemService.getById(taskItem.getId());
-                //鍒ゆ柇鏄惁鍏佽瓒呮敹锛屼笉鍏佽瓒呮敹娣诲姞鎷掓敹鍒ゆ柇
-                if (!Objects.isNull(config)) {
-                    TaskItem serviceOne = taskItemService.getOne(new LambdaQueryWrapper<TaskItem>()
-                            .eq(TaskItem::getTaskId, task.getId())
-                            .eq(TaskItem::getFieldsIndex, item.getFieldsIndex()));
-                    if (Objects.isNull(serviceOne)) {
-                        throw new CoolException("缂撳瓨鏁版嵁涓㈠け锛侊紒");
-                    }
-                    LocItemWorking workItem = locItemWorkingService.getOne(new LambdaQueryWrapper<LocItemWorking>()
-                            .eq(LocItemWorking::getTaskId, task.getId())
-                            .eq(LocItemWorking::getFieldsIndex, item.getFieldsIndex()));
-                    if (Objects.isNull(workItem)) {
-                        throw new CoolException("缂撳瓨鏁版嵁涓㈠け锛侊紒");
-                    }
-                    Double v1 = Math.round((workItem.getAnfme() - serviceOne.getQty()) * 1000000) / 1000000.0;
-                    //涓嶇鏄惁鍏佽瓒呮敹锛岄兘闇�鍒ゆ柇鏄惁瓒呭嚭搴撳瓨鑼冨洿锛堢エ鍙锋殏涓嶄娇鐢紝璇ュ垽鏂敞閲婏級
-                    // if (taskItem.getAnfme().compareTo(v1) > 0) {
-                    //     throw new CoolException("鎷h揣鏁伴噺瓒呭嚭褰撳墠绁ㄥ彿搴撳瓨鏁伴噺锛侊紒");
-                    // }
-                    if (!Boolean.parseBoolean(config.getVal())) {
-                        Double v = Math.round((item.getQty() + taskItem.getAnfme()) * 1000000) / 1000000.0;
-                        if (item.getAnfme().compareTo(v) < 0.0) {
-                            throw new CoolException("鍓嶅綋鐗╂枡宸茶秴鍑哄彲鎷h寖鍥达紝璇锋牳瀵瑰悗鍐嶆搷浣滐紒锛�");
-                        }
+                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("褰撳墠鐗╂枡宸茶秴鍑哄彲鎷h寖鍥达紝璇锋牳瀵瑰悗鍐嶆搷浣滐紒锛�");
                     }
                 }
-
-                Double picQty = Math.round((item.getQty() + taskItem.getAnfme()) * 1000000) / 1000000.0;
+                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("鐘舵�佸畬鎴愬け璐ワ紒锛�");
+                    throw new CoolException("鎷h揣鏁伴噺鏇存柊澶辫触锛侊紒");
                 }
-                
-                // 鎵e噺搴撲綅鏄庣粏搴撳瓨锛堜笌鍑哄簱瀹屾垚閫昏緫淇濇寔涓�鑷达級
                 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)) {
-                        // 浣跨敤瀹為檯鎷h揣鏁伴噺锛坱askItem.getAnfme()锛夋墸鍑忓簱浣嶆槑缁�
-                        Double newAnfme = Math.round((locItem.getAnfme() - taskItem.getAnfme()) * 1000000) / 1000000.0;
-                        
+                        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) {
-                            // 鏁伴噺灏忎簬绛変簬0锛屽垹闄ゅ簱浣嶆槑缁�
                             locItemService.removeById(locItem.getId());
                         } else {
-                            // 鏇存柊搴撲綅鏄庣粏鏁伴噺
                             locItem.setAnfme(newAnfme)
                                     .setUpdateBy(SystemAuthUtils.getLoginUserId())
                                     .setUpdateTime(new Date());
@@ -432,33 +462,8 @@
                         }
                     }
                 }
-                
-                StockItem stockItem = new StockItem();
-                BeanUtils.copyProperties(item, stockItem);
-                //taskItem涓轰笂鎶ユ暟鎹�
-                stockItem.setStockId(stock.getId()).setAnfme(taskItem.getAnfme()).setStockCode(stock.getCode()).setSourceItemId(orderItem.getId());
-                stockItems.add(stockItem);
             });
-            if (!stockItemService.saveBatch(stockItems)) {
-                throw new CoolException("鍑哄叆搴撳巻鍙叉槑缁嗕繚瀛樺け璐ワ紒锛�");
-            }
         });
-
-        List<WkOrderItem> orderItems = asnOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>().eq(WkOrderItem::getOrderId, params.getOrderId()));
-        Double total = orderItems.stream().mapToDouble(WkOrderItem::getQty).sum();
-        Double wkQty = orderItems.stream().mapToDouble(WkOrderItem::getWorkQty).sum();
-        double v = order.getWorkQty().compareTo(wkQty) < 0 ? 0.0 : Math.round((total - wkQty) * 1000000) / 1000000.0;
-        order.setQty(total).setWorkQty(v);
-        if (!asnOrderService.updateById(order)) {
-            throw new CoolException("璁㈠崟鏁伴噺鏇存柊澶辫触锛侊紒");
-        }
-//        //妫�鏌ュ崟鎹槸鍚﹀畬鎴�
-//        if (order.getAnfme().compareTo(order.getQty()) == 0) {
-//            order.setExceStatus(AsnExceStatus.OUT_STOCK_STATUS_TASK_DONE.val);
-//            if (!asnOrderService.updateById(order)) {
-//                throw new CoolException("鍑哄簱鍗曟洿鏂扮姸鎬佸け璐�");
-//            }
-//        }
         return R.ok();
     }
 
@@ -582,36 +587,80 @@
             return R.error("浠诲姟鐘舵�佷笉鏄緟鎻�鐙�鎱�");
         }
 
-        Config config = configService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getFlag, GlobalConfigCode.ALLOW_OVER_CHANGE));
-        //鍒ゆ柇鏄惁鍏佽瓒呮敹锛屼笉鍏佽瓒呮敹娣诲姞鎷掓敹鍒ゆ柇
-        if (!Objects.isNull(config)) {
-            if (!Boolean.parseBoolean(config.getVal())) {
-                List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
-                taskItems.forEach(taskItem -> {
-                    if ((taskItem.getQty().compareTo(taskItem.getAnfme()) < 0)) {
-                        throw new CoolException("鏈夊崟鎹墿鏂欐湭鎷o紝璇锋嫞瀹屽悗鍐嶇‘璁わ紒锛�");
-                    }
-                });
+        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
+        // 蹇呴』褰撳墠鎵樼洏鍏宠仈鍑哄簱鍗曞叏閮ㄦ嫞璐у畬鎴愭墠鍏佽纭
+        for (TaskItem ti : taskItems) {
+            Double q = ti.getQty() != null ? ti.getQty() : 0.0;
+            Double a = ti.getAnfme() != null ? ti.getAnfme() : 0.0;
+            if (q.compareTo(a) < 0) {
+                throw new CoolException("鏈夊崟鎹墿鏂欐湭鎷e畬锛岃瀹屾垚璇ユ墭鐩樹笅鎵�鏈夎鍗曟嫞璐у悗鍐嶇‘璁わ紒锛�");
             }
         }
 
+        // 鎸夐『搴忔洿鏂板嚭搴撳崟鏄庣粏銆佽鍗曞強搴撳瓨娴佹按锛堜笌 wavePickItems 鍘熼�昏緫涓�鑷达紝鍦ㄥ叏閮ㄦ嫞瀹屽悗缁熶竴鎵ц锛�
+        Map<Long, List<TaskItem>> byOrder = taskItems.stream()
+                .filter(ti -> ti.getOrderId() != null)
+                .collect(Collectors.groupingBy(TaskItem::getOrderId));
+        List<Long> orderIds = new ArrayList<>(byOrder.keySet());
+        orderIds.sort(Long::compareTo);
+        for (Long orderId : orderIds) {
+            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;
+                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;
+                Stock stock = new Stock();
+                stock.setCode(ruleCode)
+                        .setUpdateBy(loginUserId)
+                        .setBarcode(task.getBarcode())
+                        .setLocCode(task.getOrgLoc())
+                        .setType(order.getType())
+                        .setWkType(Short.parseShort(order.getWkType()))
+                        .setSourceId(orderItem.getOrderId())
+                        .setSourceCode(orderItem.getOrderCode())
+                        .setUpdateTime(new Date())
+                        .setAnfme(summed);
+                if (!stockService.save(stock)) continue;
+                List<StockItem> stockItems = new ArrayList<>();
+                for (TaskItem ti : matItems) {
+                    StockItem si = new StockItem();
+                    BeanUtils.copyProperties(ti, si);
+                    si.setStockId(stock.getId()).setAnfme(ti.getQty()).setStockCode(stock.getCode()).setSourceItemId(orderItem.getId());
+                    stockItems.add(si);
+                }
+                stockItemService.saveBatch(stockItems);
+            }
+            List<WkOrderItem> ois = asnOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>().eq(WkOrderItem::getOrderId, orderId));
+            Double total = ois.stream().mapToDouble(oi -> oi.getQty() != null ? oi.getQty() : 0.0).sum();
+            Double wkQty = ois.stream().mapToDouble(oi -> oi.getWorkQty() != null ? oi.getWorkQty() : 0.0).sum();
+            double v = (order.getWorkQty() != null && order.getWorkQty().compareTo(wkQty) < 0) ? 0.0 : Math.round((total - wkQty) * 1000000.0) / 1000000.0;
+            order.setQty(total).setWorkQty(v);
+            asnOrderService.updateById(order);
+        }
 
         try {
             if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) {
-                // 鎷f枡鍑哄簱锛氬垱寤烘嫞鏂欏叆搴撲换鍔�
                 taskService.pickOrCheckTask(task.getId(), "");
             } else if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
-                // 鐩樼偣鍑哄簱锛氬垱寤虹洏鐐瑰叆搴撲换鍔�
                 taskService.pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_CHECK);
             } else {
-                // 鍏朵粬鍑哄簱绫诲瀷锛氱洿鎺ユ洿鏂颁负200
                 task.setTaskStatus(TaskStsType.UPDATED_OUT.id);
                 if (!taskService.updateById(task)) {
                     throw new CoolException("浠诲姟鐘舵�佹洿鏂板け璐�");
                 }
             }
         } catch (Exception e) {
-            throw new CoolException("鍒嗘嫞澶辫触");
+            throw new CoolException("鍒嗘嫞澶辫触锛�" + e.getMessage());
         }
         return R.ok();
     }

--
Gitblit v1.9.1