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 |  471 +++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 315 insertions(+), 156 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 52a5c8c..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;
@@ -28,6 +30,7 @@
 import com.vincent.rsf.server.system.service.impl.FieldsItemServiceImpl;
 import com.vincent.rsf.server.system.service.impl.FieldsServiceImpl;
 import com.vincent.rsf.server.system.utils.SerialRuleUtils;
+import com.vincent.rsf.server.common.constant.Constants;
 import com.vincent.rsf.server.system.utils.SystemAuthUtils;
 import lombok.Synchronized;
 import org.apache.commons.lang3.StringUtils;
@@ -43,6 +46,7 @@
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
+import java.util.Date;
 
 @Service
 public class PdaOutStockServiceImpl implements PdaOutStockService {
@@ -74,47 +78,135 @@
     @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);
-        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);
-        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("鏈壘鍒版枡绠辩爜瀵瑰簲浠诲姟鎴栦换鍔$姸鎬佷笉鏄瓑寰呯‘璁�");
         }
-        if (!task.getTaskStatus().equals(TaskStsType.AWAIT.id)) {
-            return R.error("浠诲姟鐘舵�佷笉鏄瓑寰呯‘璁�");
+        Long loginUserId = SystemAuthUtils.getLoginUserId();
+        if (loginUserId == null) {
+            loginUserId = 1L;
         }
-        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
-        Map<Long, List<TaskItem>> maps = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getSource));
-        maps.keySet().forEach(key -> {
-            WkOrderItem orderItem = asnOrderItemService.getById(key);
-            if (Objects.isNull(orderItem)) {
-                throw new CoolException("鍗曟嵁鏄庣粏涓嶅瓨鍦紒锛�");
+        try {
+            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噺骞剁敓鎴愭嫞鏂欏叆搴撲换鍔★紙鏈変綑閲忔椂锛�");
             }
-        });
-        task.setTaskStatus(TaskStsType.COMPLETE_OUT.id);
-        if (!taskService.updateById(task)) {
-            return R.error("鏇存柊浠诲姟鐘舵�佸け璐�");
+            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("纭鎴愬姛锛屽凡鍒涘缓鐩樼偣鍏ュ簱浠诲姟");
+            }
+            if (first.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) {
+                for (Task task : tasks) {
+                    taskService.completeFullOutStock(task.getId(), loginUserId);
+                }
+                return R.ok("纭鎴愬姛锛屽叏鐗堝嚭搴撳凡瀹屾垚");
+            }
+            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("纭鎴愬姛");
+        } catch (Exception e) {
+            throw new CoolException("蹇�熸嫞璐х‘璁ゅけ璐ワ細" + e.getMessage());
         }
-
-        return R.ok("纭鎴愬姛");
     }
 
     @Override
@@ -131,31 +223,56 @@
         if (Cools.isEmpty(barcode)) {
             throw new CoolException("鍙傛暟鏈夎");
         }
-        Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, barcode));
+        Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, barcode)
+                .orderByDesc(Task::getId)
+                .last("limit 1"));
         if (null == task) {
-            throw new CoolException("鏈壘鍒板鍣ㄥ彿瀵瑰簲浠诲姟");
+            throw new CoolException("鏈壘鍒版枡绠辩爜瀵瑰簲浠诲姟");
         }
         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()));
@@ -164,7 +281,7 @@
 //            containerWaveDto.setTaskItem(taskItem);
 //            Wave wave = waveService.getById(taskItem.getSourceId());
 //            if (null == wave) {
-//                throw new CoolException("鏈壘鍒板鍣ㄥ彿瀵瑰簲娉㈡");
+//                throw new CoolException("鏈壘鍒版枡绠辩爜瀵瑰簲娉㈡");
 //            }
 //            List<WaveOrderRela> waveOrderRelas = waveOrderRelaService.list(new LambdaQueryWrapper<WaveOrderRela>()
 //                    .eq(WaveOrderRela::getWaveId, wave.getId()));
@@ -201,41 +318,58 @@
         if (Objects.isNull(param)) {
             return R.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
         }
-        if (Objects.isNull(param.get("fieldsIndex"))) {
-            return R.error("绁ㄥ彿涓嶈兘涓虹┖锛侊紒");
-        }
+        // 绁ㄥ彿鏆備笉浣跨敤锛屾敞閲婃牎楠�
+        // if (Objects.isNull(param.get("fieldsIndex"))) {
+        //     return R.error("绁ㄥ彿涓嶈兘涓虹┖锛侊紒");
+        // }
         if (Objects.isNull(param.get("barcode"))) {
-            return R.error("瀹瑰櫒鍙蜂笉鑳戒负绌猴紒锛�");
+            return R.error("鏂欑鐮佷笉鑳戒负绌猴紒锛�");
         }
         if (Objects.isNull(param.get("orderId"))) {
             return R.error("璁㈠崟ID涓嶈兘涓虹┖锛侊紒");
         }
-        Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, param.get("barcode").toString()));
+        Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, param.get("barcode").toString())
+                .orderByDesc(Task::getId)
+                .last("limit 1"));
         if (Objects.isNull(task)) {
             throw new CoolException("鏁版嵁閿欒锛屼换鍔℃。宸蹭笉瀛樺湪锛侊紒");
         }
-        FieldsItem fieldsItem = fieldsItemService.getOne(new LambdaQueryWrapper<FieldsItem>()
-                .eq(FieldsItem::getValue, param.get("fieldsIndex").toString())
-                .last("limit 1"));
-        if (Objects.isNull(fieldsItem)) {
-            return R.error("鏁版嵁閿欒锛岀エ鍙蜂笉瀛樺湪锛侊紒");
-        }
-        TaskItem taskItem = taskItemService.getOne(new LambdaQueryWrapper<TaskItem>()
+        // 绁ㄥ彿鏆備笉浣跨敤锛屾寜浠诲姟鍙栫涓�鏉℃槑缁�
+        // FieldsItem fieldsItem = fieldsItemService.getOne(new LambdaQueryWrapper<FieldsItem>()
+        //         .eq(FieldsItem::getValue, param.get("fieldsIndex").toString())
+        //         .last("limit 1"));
+        // if (Objects.isNull(fieldsItem)) {
+        //     return R.error("鏁版嵁閿欒锛岀エ鍙蜂笉瀛樺湪锛侊紒");
+        // }
+        TaskItem taskItem = null;
+        FieldsItem fieldsItem = null;
+        if (param.get("fieldsIndex") != null && StringUtils.isNotBlank(param.get("fieldsIndex").toString())) {
+            fieldsItem = fieldsItemService.getOne(new LambdaQueryWrapper<FieldsItem>()
+                    .eq(FieldsItem::getValue, param.get("fieldsIndex").toString())
+                    .last("limit 1"));
+            if (fieldsItem != null) {
+                taskItem = taskItemService.getOne(new LambdaQueryWrapper<TaskItem>()
                         .eq(TaskItem::getFieldsIndex, fieldsItem.getUuid())
-                .eq(TaskItem::getTaskId, task.getId()));
+                        .eq(TaskItem::getTaskId, task.getId()));
+            }
+        }
+        if (taskItem == null) {
+            taskItem = taskItemService.getOne(new LambdaQueryWrapper<TaskItem>()
+                    .eq(TaskItem::getTaskId, task.getId())
+                    .last("limit 1"));
+        }
         if (Objects.isNull(taskItem)) {
             return R.error("鏁版嵁閿欒锛屼换鍔℃。鏄庣粏涓嶅瓨鍦紒锛�");
         }
-//        Long orderId = Long.valueOf(param.get("orderId").toString());
-//        List<WkOrderItem> orderItems = asnOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>().eq(WkOrderItem::getOrderId, orderId));
-//        if (orderItems.isEmpty()) {
-//            return R.error("鏁版嵁閿欒锛岃鍗曟暟鎹笉瀛樺湪锛侊紒");
-//        }
-        //鏍规嵁绱㈠紩鑾峰彇鍔ㄦ�佸瓧娈礦alue鍊�
-        Map<String, String> fields = new HashMap<>();
-        Fields fields1 = fieldsService.getById(fieldsItem.getFieldsId());
-        fields.put(fields1.getFields(), fieldsItem.getValue());
-        taskItem.setExtendFields(fields);
+        // 绁ㄥ彿鏆備笉浣跨敤锛氫粎褰撴湁 fieldsItem 鏃惰缃� extendFields
+        if (fieldsItem != null) {
+            Fields fields1 = fieldsService.getById(fieldsItem.getFieldsId());
+            if (fields1 != null) {
+                Map<String, String> fields = new HashMap<>();
+                fields.put(fields1.getFields(), fieldsItem.getValue());
+                taskItem.setExtendFields(fields);
+            }
+        }
 
         return R.ok().add(taskItem);
     }
@@ -248,9 +382,9 @@
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public R wavePickItems(WavePickItemsParams params) {
+    public synchronized R wavePickItems(WavePickItemsParams params) {
         if (Objects.isNull(params.getBarcode())) {
-            return R.error("鎵樼洏鐮佷笉鑳戒负绌猴紒锛�");
+            return R.error("鏂欑鐮佷笉鑳戒负绌猴紒锛�");
         }
         if (Objects.isNull(params.getOrderId())) {
             return R.error("璁㈠崟ID涓嶈兘涓虹┖锛侊紒");
@@ -258,9 +392,11 @@
         if (Objects.isNull(params.getTaskItems()) || params.getTaskItems().isEmpty()) {
             return R.error("鎷h揣鏄庣粏涓嶈兘涓虹┖锛�");
         }
-        Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, params.getBarcode()));
+        Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, params.getBarcode())
+                .orderByDesc(Task::getId)
+                .last("limit 1"));
         if (null == task) {
-            return R.error("鏈壘鍒版墭鐩樺搴旂殑浠诲姟");
+            return R.error("鏈壘鍒版枡绠卞搴旂殑浠诲姟");
         }
         if (!task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) {
             return R.error("浠诲姟鐘舵�佷笉鏄弨鏂欑媭鎱�");
@@ -271,96 +407,63 @@
         }
         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("鏁版嵁閿欒锛屾嫞鏂欎笉鍦ㄥ崟鎹渶姹備腑锛侊紒");
             }
-
-            Double summed = items.stream().mapToDouble(TaskItem::getAnfme).sum();
-            //鍔犱笂鍘嗗彶鎷f枡鏁伴噺
-            Double pickQty = Math.round((orderItem.getQty() + summed) * 100) / 100.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)) {
-                    if (!Boolean.parseBoolean(config.getVal())) {
-                        if (item.getAnfme().compareTo(item.getQty() + taskItem.getAnfme()) < 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() != 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("鎷h揣鏁伴噺鏇存柊澶辫触锛侊紒");
+                }
+                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("搴撲綅鏄庣粏鏁伴噺鎵e噺澶辫触锛侊紒");
+                            }
                         }
                     }
                 }
-
-                item.setQty(item.getQty() + taskItem.getAnfme()).setOrderId(order.getId()).setOrderItemId(orderItem.getId());
-                if (!taskItemService.updateById(item)) {
-                    throw new CoolException("鐘舵�佸畬鎴愬け璐ワ紒锛�");
-                }
-                StockItem stockItem = new StockItem();
-                BeanUtils.copyProperties(taskItem, stockItem);
-                stockItem.setStockId(stock.getId()).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();
-        order.setQty(total).setWorkQty(order.getWorkQty().compareTo(wkQty) < 0 ? 0.0 : (total - wkQty));
-        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();
     }
 
@@ -380,7 +483,7 @@
                 .in(Task::getTaskType, integers)
                 .eq(Task::getBarcode, params.get("barcode")), false);
         if (Objects.isNull(task)) {
-            return R.error("鎵樼洏鎵�鍦ㄤ换鍔′笉瀛樺湪锛侊紒");
+            return R.error("鏂欑鎵�鍦ㄤ换鍔′笉瀛樺湪锛侊紒");
         }
         List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
         taskItems.forEach(taskItem -> {
@@ -405,6 +508,9 @@
             return R.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
         }
         for (TaskItem item : items) {
+            // 绁ㄥ彿鏆備笉浣跨敤锛岃烦杩囦慨鏀瑰嚭搴撲换鍔℃。鏄庣粏绁ㄥ彿閫昏緫
+            continue;
+            /*
             if (Objects.isNull(item.getCrushNo())) {
                 continue;
             }
@@ -413,7 +519,7 @@
                 Map<String, String> fields = FieldsUtils.getFields(byId.getFieldsIndex());
                 byId.setExtendFields(fields);
             }
-            if (byId.getExtendFields().get("crushNo").equals(item.getCrushNo())) {
+            if (byId.getExtendFields() != null && byId.getExtendFields().get("crushNo") != null && byId.getExtendFields().get("crushNo").equals(item.getCrushNo())) {
                 continue;
             }
             FieldsItem fieldsItem = fieldsItemService.getOne(new LambdaQueryWrapper<FieldsItem>()
@@ -428,13 +534,15 @@
                throw new CoolException("浠诲姟鏄庣粏淇敼澶辫触");
             }
             LocItemWorking oldOne = locItemWorkingService.getOne(new LambdaQueryWrapper<LocItemWorking>()
+                    .eq(LocItemWorking::getTaskId, byId.getTaskId())
                     .eq(LocItemWorking::getMatnrCode, byId.getMatnrCode())
                     .eq(LocItemWorking::getFieldsIndex, byId.getFieldsIndex()));
             if (Objects.isNull(oldOne)) {
                 throw new CoolException("鏄庣粏涓嶅瓨鍦ㄦ垨宸插嚭搴擄紒锛�");
             }
             LocItemWorking one = locItemWorkingService.getOne(new LambdaQueryWrapper<LocItemWorking>()
-                            .eq(LocItemWorking::getMatnrCode, byId.getMatnrCode())
+                    .eq(LocItemWorking::getTaskId, byId.getTaskId())
+                    .eq(LocItemWorking::getMatnrCode, byId.getMatnrCode())
                     .eq(LocItemWorking::getFieldsIndex, uuid));
             if (Objects.isNull(one)) {
                 throw new CoolException("鏄庣粏涓嶅瓨鍦ㄦ垨宸插嚭搴擄紒锛�");
@@ -445,7 +553,7 @@
             //鏇存柊搴撲綅淇℃伅
             locItemWorkingService.updateById(oldOne);
             locItemWorkingService.updateById(one);
-
+            */
         }
         return R.ok();
     }
@@ -469,31 +577,82 @@
             return R.error("鏁版嵁閿欒锛侊紒");
         }
 
-        Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, containerWaveParam.getContainer()));
+        Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, containerWaveParam.getContainer())
+                .orderByDesc(Task::getId)
+                .last("limit 1"));
         if (null == task) {
-            return R.error("鏈壘鍒版墭鐩樺搴旂殑浠诲姟");
+            return R.error("鏈壘鍒版枡绠卞搴旂殑浠诲姟");
         }
         if (!task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) {
             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) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
+            if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) {
                 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 {
                 task.setTaskStatus(TaskStsType.UPDATED_OUT.id);
                 if (!taskService.updateById(task)) {
@@ -501,7 +660,7 @@
                 }
             }
         } catch (Exception e) {
-            throw new CoolException("鍒嗘嫞澶辫触");
+            throw new CoolException("鍒嗘嫞澶辫触锛�" + e.getMessage());
         }
         return R.ok();
     }

--
Gitblit v1.9.1