From b1123ede8199b691d6d684af6b3b58b223b6bdae Mon Sep 17 00:00:00 2001
From: chen.lin <1442464845@qq.com>
Date: 星期三, 11 二月 2026 14:05:31 +0800
Subject: [PATCH] 修改预约库位变更

---
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java     |  100 +++++++++++++++++++++++++++++++++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java      |    3 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java |    3 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java     |   22 ++++++-
 4 files changed, 122 insertions(+), 6 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java
index 6b18567..c2d7766 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java
@@ -247,7 +247,8 @@
         if (Objects.isNull(matnr)) {
             throw new CoolException("鏁版嵁閿欒锛氱墿鏂�" + wkOrderItem.getMatnrCode() + "涓嶅瓨鍦紒锛�");
         }
-        BeanUtils.copyProperties(matnr, wkOrderItem);
+        // 澶嶅埗鏃舵帓闄� id锛岄伩鍏嶇墿鏂� id 瑕嗙洊鍗曟嵁鏄庣粏 id锛屽鑷� saveOrUpdate 璇垽涓烘柊澧炶�岄噸澶嶆彃鍏ワ紙鍑哄簱鍗曠紪杈戜繚瀛樺悗 1 鏉″彉 2 鏉★級
+        BeanUtils.copyProperties(matnr, wkOrderItem, "id");
         wkOrderItem.setMatnrCode(matnr.getCode())
                 .setSplrBatch(!Objects.isNull(wkOrderItem.getBatch()) ? wkOrderItem.getBatch() : null)
                 .setMatnrId(matnr.getId())
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java
index 9eba8f0..d0f6cab 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java
@@ -143,6 +143,10 @@
      * @param loginUserId
      * @return
      */
+    /** 鍏ュ簱鍗曚笟鍔$被鍨嬶細鎷f枡鍏ュ簱銆佺洏鐐瑰叆搴撶瓑涓嶅彲淇敼鏄庣粏锛屾澶勪负瀛楀吀 value锛屾寜瀹為檯閰嶇疆琛ュ厖 */
+    private static final Set<String> ASN_WKTYPE_NO_EDIT = Collections.unmodifiableSet(new HashSet<>(
+            Arrays.asList("53", "57"))); // 53=鎷f枡鍐嶅叆搴� 57=鐩樼偣鍐嶅叆搴擄紙涓� TaskType 涓�鑷达紝鑻ュ瓧鍏镐笉鍚岃鏀逛负瀹為檯 value锛�
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public R updateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) throws Exception {
@@ -153,11 +157,23 @@
         if (Objects.isNull(orders.getId())) {
             throw new CoolException("鏁版嵁閿欒锛氬崟鎹甀D涓嶈兘涓虹┖锛侊紒");
         }
-        if (!this.updateById(orders)) {
-            throw new CoolException("涓诲崟淇敼澶辫触锛侊紒");
+        WkOrder currentOrder = this.getById(orders.getId());
+        if (Objects.isNull(currentOrder)) {
+            throw new CoolException("鍗曟嵁涓嶅瓨鍦紒锛�");
+        }
+        // 浠呮湭鎵ц鐘舵�佸彲淇敼
+        if (!Objects.equals(currentOrder.getExceStatus(), AsnExceStatus.ASN_EXCE_STATUS_UN_EXCE.val)) {
+            throw new CoolException("褰撳墠鍗曟嵁鐘舵�佷笉鍏佽淇敼锛屼粎鏈墽琛岀姸鎬佸彲淇敼");
+        }
+        // 鎷f枡鍏ュ簱銆佺洏鐐瑰叆搴撶被鍨嬩笉鍙慨鏀�
+        if (StringUtils.isNotBlank(currentOrder.getWkType()) && ASN_WKTYPE_NO_EDIT.contains(currentOrder.getWkType())) {
+            throw new CoolException("鎷f枡鍏ュ簱銆佺洏鐐瑰叆搴撶被鍨嬬殑鍗曟嵁涓嶈兘淇敼");
         }
         if (Objects.isNull(params.getItems()) || params.getItems().isEmpty()) {
-            return R.ok("鏄庣粏鍙傛暟涓嶈兘涓虹┖锛侊紒");
+            throw new CoolException("鏄庣粏鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        if (!this.updateById(orders)) {
+            throw new CoolException("涓诲崟淇敼澶辫触锛侊紒");
         }
 
         svaeOrUpdateOrderItem(params, loginUserId);
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java
index 1944a8a..666c054 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocItemServiceImpl.java
@@ -218,7 +218,8 @@
                 if (map.getType().equals(Constants.TASK_TYPE_ORDER_OUT_STOCK)) {
                     taskItem.setWkType(Short.parseShort(order.getWkType()))
                             .setSourceCode(order.getCode())
-                            .setSourceId(order.getId());
+                            .setSourceId(order.getId())
+                            .setOrderItemId(item.getOrderItemId());
                 } else if (map.getType().equals(Constants.TASK_TYPE_WAVE_OUT_STOCK)) {
                     taskItem.setSourceId(wave.getId())
                             .setWkType(Short.parseShort(OrderWorkType.ORDER_WORK_TYPE_OTHER.type))
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
index 0d00940..2e999d3 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
@@ -81,6 +81,8 @@
     private LocService locService;
     @Autowired
     private WaveOrderRelaServiceImpl waveOrderRelaService;
+    @Autowired
+    private TaskItemService taskItemService;
 
 
     /**
@@ -419,6 +421,7 @@
      * @time 2025/4/29 13:47
      */
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public R updateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) {
         WkOrder orders = params.getOrders();
         if (Objects.isNull(orders)) {
@@ -433,12 +436,102 @@
         if (Objects.isNull(params.getItems()) || params.getItems().isEmpty()) {
             throw new CoolException("鏄庣粏鍙傛暟涓嶈兘涓虹┖锛侊紒");
         }
+        // 鍒犻櫎/淇敼鏄庣粏鍓嶆敹闆嗗綋鍓嶅崟鎹笅鐨勬槑缁� id锛岀敤浜庢牎楠屼笌鍚屾搴撲綅鐘舵��
+        List<Long> existingIds = asnOrderItemService.list(
+                new LambdaQueryWrapper<WkOrderItem>().eq(WkOrderItem::getOrderId, orders.getId()))
+                .stream().map(WkOrderItem::getId).collect(Collectors.toList());
+        Set<Long> requestedIds = params.getItems().stream()
+                .map(item -> item.get("id"))
+                .filter(Objects::nonNull)
+                .map(id -> Long.valueOf(id.toString()))
+                .collect(Collectors.toSet());
+        // 宸茬敓鎴愬伐浣滄。鐨勬槑缁嗕笉鍏佽鍒犻櫎
+        for (Long existingId : existingIds) {
+            if (!requestedIds.contains(existingId) && hasGeneratedTask(orders.getId(), existingId)) {
+                throw new CoolException("璇ユ槑缁嗗凡鐢熸垚宸ヤ綔妗o紝涓嶈兘鍒犻櫎");
+            }
+        }
+        // 宸茬敓鎴愬伐浣滄。鐨勬槑缁嗕笉鍏佽淇敼
+        for (Map<String, Object> item : params.getItems()) {
+            Object idObj = item.get("id");
+            if (idObj != null && hasGeneratedTask(orders.getId(), Long.valueOf(idObj.toString()))) {
+                throw new CoolException("璇ユ槑缁嗗凡鐢熸垚宸ヤ綔妗o紝涓嶈兘淇敼");
+            }
+        }
         try {
             svaeOrUpdateOrderItem(params, loginUserId);
         } catch (Exception e) {
             throw new CoolException(e.getMessage());
         }
+        // 瀵规湰娆¤鍒犻櫎鐨勬槑缁嗭紙浠呭垵濮嬪寲鐘舵�侊級锛氬厛鍚屾搴撲綅鐘舵�侊紝鍐嶅垹闄ゆ槑缁嗚褰�
+        for (Long existingId : existingIds) {
+            if (!requestedIds.contains(existingId)) {
+                syncLocStatusOnOrderItemRemoved(orders.getId(), existingId, loginUserId);
+                outStockItemService.removeById(existingId);
+            }
+        }
+        // 閲嶆柊姹囨�讳富鍗曟暟閲忥紙鍒犻櫎鏄庣粏鍚庯級
+        List<WkOrderItem> afterItems = asnOrderItemService.list(new LambdaQueryWrapper<WkOrderItem>()
+                .eq(WkOrderItem::getOrderId, orders.getId()));
+        Double sum = afterItems.stream().mapToDouble(WkOrderItem::getAnfme).sum();
+        orders.setAnfme(sum);
+        this.updateById(orders);
         return R.ok();
+    }
+
+    /**
+     * 鍒ゆ柇鍑哄簱鍗曟槑缁嗘槸鍚﹀凡鐢熸垚宸ヤ綔妗o紙瀛樺湪鍏宠仈鐨勪换鍔℃槑缁嗭級
+     */
+    private boolean hasGeneratedTask(Long orderId, Long orderItemId) {
+        return taskItemService.count(new LambdaQueryWrapper<TaskItem>()
+                .eq(TaskItem::getSourceId, orderId)
+                .eq(TaskItem::getOrderItemId, orderItemId)) > 0;
+    }
+
+    /**
+     * 鍑哄簱鍗曟槑缁嗚鍒犻櫎鏃跺悓姝ュ簱浣嶇姸鎬侊細閲婃斁璇ユ槑缁嗗叧鑱旂殑搴撲綅棰勭害銆佸洖婊� LocItem.workQty銆佹仮澶嶅簱浣嶄负鍦ㄥ簱(F)
+     */
+    private void syncLocStatusOnOrderItemRemoved(Long orderId, Long orderItemId, Long loginUserId) {
+        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>()
+                .eq(TaskItem::getSourceId, orderId)
+                .eq(TaskItem::getOrderItemId, orderItemId));
+        if (taskItems.isEmpty()) {
+            return;
+        }
+        Set<Long> affectedLocIds = new HashSet<>();
+        Date now = new Date();
+        for (TaskItem taskItem : taskItems) {
+            if (taskItem.getSource() == null) {
+                continue;
+            }
+            LocItem locItem = locItemService.getById(taskItem.getSource());
+            if (locItem == null) {
+                continue;
+            }
+            Double anfme = taskItem.getAnfme() != null ? taskItem.getAnfme() : 0.0;
+            Double newWorkQty = Math.round((locItem.getWorkQty() - anfme) * 1000000) / 1000000.0;
+            locItem.setWorkQty(newWorkQty >= 0 ? newWorkQty : 0)
+                    .setOrderId(null)
+                    .setOrderItemId(null)
+                    .setUpdateBy(loginUserId)
+                    .setUpdateTime(now);
+            locItemService.updateById(locItem);
+            affectedLocIds.add(locItem.getLocId());
+        }
+        for (Long locId : affectedLocIds) {
+            long stillReserved = locItemService.count(new LambdaQueryWrapper<LocItem>()
+                    .eq(LocItem::getLocId, locId)
+                    .isNotNull(LocItem::getOrderId));
+            if (stillReserved == 0) {
+                Loc loc = locService.getById(locId);
+                if (loc != null && LocStsType.LOC_STS_TYPE_R.type.equals(loc.getUseStatus())) {
+                    loc.setUseStatus(LocStsType.LOC_STS_TYPE_F.type)
+                            .setUpdateBy(loginUserId)
+                            .setUpdateTime(now);
+                    locService.updateById(loc);
+                }
+            }
+        }
     }
 
     @Override
@@ -579,6 +672,8 @@
 
                 locItem.setOutQty(param.getOutQty())
                         .setBatch(param.getBatch())
+                        .setOrderId(outId)
+                        .setOrderItemId(orderItem.getId())
                         .setSourceId(outId)
                         .setSourceCode(orderItem.getOrderCode())
                         .setSource(orderItem.getId());
@@ -714,10 +809,13 @@
                 }
                 // 璇ュ簱浣嶅彲鍒嗛厤鏁伴噺锛氬彇鏈寰呭垎閰嶄笌搴撲綅搴撳瓨鐨勮緝灏忓��
                 double allocatable = Math.min(issued.doubleValue(), locItem.getAnfme() != null ? locItem.getAnfme() : 0);
+                // 褰撳垎閰嶉噺绛変簬搴撲綅搴撳瓨鏃讹紝浣跨敤搴撲綅搴撳瓨绮惧害浣滀负鍑哄簱鏁伴噺锛岄伩鍏嶆埅鏂鑷寸晫闈㈡樉绀�/搴撳瓨鏍¢獙涓嶄竴鑷达紙濡傚簱瀛�15.123457琚埅鎴�15.123锛�
+                double outQtyToSet = (locItem.getAnfme() != null && Math.abs(allocatable - locItem.getAnfme()) < 1e-6)
+                        ? locItem.getAnfme() : allocatable;
                 ExistDto existDto = new ExistDto().setBatch(locItem.getBatch()).setMatnr(locItem.getMatnrCode()).setLocNo(locItem.getLocCode());
                 if (existDtos.add(existDto)) {
                     // 棣栨浣跨敤璇ュ簱浣嶏細鍔犲叆鍒楄〃骞舵墸鍑� issued
-                    locItem.setOutQty(allocatable);
+                    locItem.setOutQty(outQtyToSet);
                     locItem.setBarcode(loc.getBarcode());
                     OrderOutItemDto orderOutItemDto = new OrderOutItemDto();
                     orderOutItemDto.setLocItem(locItem);

--
Gitblit v1.9.1