Bladeren bron

更新备货流程 --ing

k 2 jaren geleden
bovenliggende
commit
f99fc66615

+ 1 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/pda/PdaInvLotLocIdController.java

@@ -48,7 +48,7 @@ public class PdaInvLotLocIdController {
         if (!StringUtils.isEmpty(invLotLocIdMoveForm.getLocationFrom())) {
             // 判断是否叫车
             if (invLotLocIdMoveForm != null
-                    && invLotLocIdMoveForm.getIsCallCar().equals(Constant.IS_YES.Y.getValue())) {
+                    && invLotLocIdMoveForm.getIsCallCar().equals(Constant.IS_YES.Y.name())) {
                 return invLotLocIdService.move(invLotLocIdMoveForm);
             } else {
                 return invLotLocIdService.moveDirect(invLotLocIdMoveForm);

+ 9 - 3
warewms-ams/src/main/java/com/ruoyi/ams/erp/service/impl/SyncServiceImpl.java

@@ -120,9 +120,13 @@ public class SyncServiceImpl implements ISyncService {
 
     @Override
     public void syncOrderList() {
+        boolean isDel = false;
         // ERP需求单
         List<JSONObject> list = (List<JSONObject>) redisTemplate.opsForValue().get("erpOrderList");
         List<JSONObject> list_failed = (List<JSONObject>) redisTemplate.opsForValue().get("erpOrderList_failed");
+        if (list != null && list.size() > 0) {
+            isDel = true;
+        }
         if (list_failed != null && list_failed.size() > 0) {
             list.addAll(list_failed);
         }
@@ -155,18 +159,20 @@ public class SyncServiceImpl implements ISyncService {
             for (Map.Entry<String, List<ErpOrderList>> entry : inmap.entrySet()) {
                 AjaxResult ajaxResult = wmsDocAsnHeaderService.addOrUpdateErp(entry.getValue());
                 if (!ajaxResult.isSuccess()) {
-                    log.error("ERP同步表插入入库单失败:" + ajaxResult.getMsg() + "!" + JSON.toJSONString(entry.getValue()));
+                    log.error("ERP同步入库单失败:" + ajaxResult.getMsg() + "!" + JSON.toJSONString(entry.getValue()));
                     erpOrderList_failed.addAll(entry.getValue());
                 }
             }
             for (Map.Entry<String, List<ErpOrderList>> entry : outmap.entrySet()) {
                 AjaxResult ajaxResult = wmsDocOrderHeaderService.addOrUpdateErp(entry.getValue());
                 if (!ajaxResult.isSuccess()) {
-                    log.error("ERP同步表插入出库单失败:" + ajaxResult.getMsg() + "!" + JSON.toJSONString(entry.getValue()));
+                    log.error("ERP同步出库单失败:" + ajaxResult.getMsg() + "!" + JSON.toJSONString(entry.getValue()));
                     erpOrderList_failed.addAll(entry.getValue());
                 }
             }
-            redisTemplate.delete("erpOrderList");
+            if (isDel) {
+                redisTemplate.delete("erpOrderList");
+            }
             redisTemplate.opsForValue().set("erpOrderList_failed", JSON.toJSONString(erpOrderList_failed));
         }
     }

+ 14 - 9
warewms-ams/src/main/java/com/ruoyi/ams/inv/service/impl/InvLotLocIdServiceImpl.java

@@ -205,6 +205,16 @@ public class InvLotLocIdServiceImpl implements IInvLotLocIdService {
         BaseLocationInfo baseLocationTo = null;
         String palletNo;
 
+        // 起始和目标库位
+        baseLocationFrom = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(locationFrom, warehouseId);
+        if (baseLocationFrom.getZoneId().equals(Constant.ZONE_TYPE.ZONE_VIRTUAL.getValue())) {
+            return AjaxResult.error("起始库位虚拟库位不可叫车!");
+        }
+        baseLocationTo = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(locationTo, warehouseId);
+        if (baseLocationTo.getZoneId().equals(Constant.ZONE_TYPE.ZONE_VIRTUAL.getValue())) {
+            return AjaxResult.error("目标库位虚拟库位不可叫车!");
+        }
+
         // 验证起始库位
         Boolean isIdleFrom = baseLocationInfoService.verifyLocationIsIdle(locationFrom, warehouseId);
         if (!isIdleFrom) {
@@ -219,12 +229,6 @@ public class InvLotLocIdServiceImpl implements IInvLotLocIdService {
         if (isInStock) {
             return AjaxResult.error("目标库位有货!");
         }
-        // 起始和目标库位
-        baseLocationFrom = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(locationFrom, warehouseId);
-        baseLocationTo = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(locationTo, warehouseId);
-        if (baseLocationTo.getZoneId().equals(Constant.ZONE_TYPE.ZONE_VIRTUAL.getValue())) {
-            return AjaxResult.error("目标库位虚拟库位不可叫车!");
-        }
 
         // 验证起始库位必须有货
         List<InvLotLocIdLotattVO> invLotLocIdLotattVOList = invLotLocIdService.selectInvLocIdLotattByLocationId(baseLocationFrom.getId());
@@ -281,6 +285,10 @@ public class InvLotLocIdServiceImpl implements IInvLotLocIdService {
         BaseLocationInfo baseLocationTo = null;
         String palletNo;
 
+        // 起始和目标库位
+        baseLocationFrom = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(locationFrom, warehouseId);
+        baseLocationTo = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(locationTo, warehouseId);
+
         // 验证起始库位
         Boolean isIdleFrom = baseLocationInfoService.verifyLocationIsIdle(locationFrom, warehouseId);
         if (!isIdleFrom) {
@@ -295,9 +303,6 @@ public class InvLotLocIdServiceImpl implements IInvLotLocIdService {
         if (isInStock) {
 //            return AjaxResult.error("目标库位有货!");
         }
-        // 起始和目标库位
-        baseLocationFrom = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(locationFrom, warehouseId);
-        baseLocationTo = baseLocationInfoService.selectBaseLocationInfoByIdOrNo(locationTo, warehouseId);
 
         // 验证起始库位必须有货
         List<InvLotLocIdLotattVO> invLotLocIdLotattVOList = invLotLocIdService.selectInvLocIdLotattByLocationId(baseLocationFrom.getId());

+ 5 - 0
warewms-ams/src/main/java/com/ruoyi/ams/order/service/UpdateOrderStockingProcess.java

@@ -1,6 +1,7 @@
 package com.ruoyi.ams.order.service;
 
 import com.ruoyi.ams.erp.domain.ErpOrderList;
+import com.ruoyi.ams.order.domain.WmsDocOrderDetails;
 import com.ruoyi.common.core.domain.AjaxResult;
 
 import java.util.List;
@@ -23,4 +24,8 @@ public interface UpdateOrderStockingProcess {
     AjaxResult startExecution(List<ErpOrderList> erpOrderList);
 
 
+
+
+
+
 }

+ 360 - 2
warewms-ams/src/main/java/com/ruoyi/ams/order/service/impl/UpdateOrderStockingProcessImpl.java

@@ -1,17 +1,25 @@
 package com.ruoyi.ams.order.service.impl;
 
 import com.ruoyi.ams.erp.domain.ErpOrderList;
+import com.ruoyi.ams.inv.domain.form.InvLocIdSearchFrom;
+import com.ruoyi.ams.inv.domain.vo.InvLotLocIdLotattVO;
+import com.ruoyi.ams.inv.service.IInvLotLocIdService;
+import com.ruoyi.ams.order.domain.WmsDocOrderDetails;
 import com.ruoyi.ams.order.domain.WmsDocOrderHeader;
 import com.ruoyi.ams.order.service.IWmsDocOrderDetailsService;
 import com.ruoyi.ams.order.service.IWmsDocOrderHeaderService;
 import com.ruoyi.ams.order.service.UpdateOrderStockingProcess;
 import com.ruoyi.base.constant.Constant;
+import com.ruoyi.base.service.IBaseLocationInfoService;
 import com.ruoyi.common.core.domain.AjaxResult;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
-import java.util.List;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 更新备货流程
@@ -27,17 +35,367 @@ public class UpdateOrderStockingProcessImpl implements UpdateOrderStockingProces
     private IWmsDocOrderHeaderService wmsDocOrderHeaderService;
     @Autowired
     private IWmsDocOrderDetailsService iWmsDocOrderDetailsService;
+    @Autowired
+    private IInvLotLocIdService invLotLocIdService;
+    @Autowired
+    private IBaseLocationInfoService baseLocationInfoService;
+    @Autowired
+    private UpdateOrderStockingProcess updateOrderStockingProcess;
 
+    /**
+     * 单据明细修改标记
+     */
+    public enum MODIFY_MARKER {
+        /**
+         * 插入
+         */
+        INSERT,
+        /**
+         * 增加数量
+         */
+        ADD,
+        /**
+         * 减少数量
+         */
+        DECREASE,
+        /**
+         * 删除
+         */
+        DELETE
+    }
 
+    /**
+     * 更新备货流程
+     *
+     * @param erpOrderList
+     * @return
+     */
+    @Transactional
     @Override
     public AjaxResult startExecution(List<ErpOrderList> erpOrderList) {
+        String orderNo = "";
         String erpName = erpOrderList.get(0).getOrderName();
         WmsDocOrderHeader header = wmsDocOrderHeaderService.selectWmsDocOrderHeaderByErpNo(erpName);
+        header.getOrderNo();
+        // 判断单据类型是否为备货单
+        if (!header.getOrderType().equals(Constant.ORDER_TYP.BH.getValue())) {
+            log.error("出库单类型不是备货类型,不可更新备货!" + header.getOrderNo());
+            return AjaxResult.success();
+        }
+        // 备货单部分或者完全出库不可更新备货
         if (header.getOrderStatus().equals(Constant.ORDER_STS.STS98.getValue())
                 || header.getOrderStatus().equals(Constant.ORDER_STS.STS99.getValue())) {
-            log.error("出库单状态为已经出库!不可更新备货!" + header.getOrderNo());
+            log.error("备货单状态为(部分出库)已经出库!不可更新备货!" + header.getOrderNo());
+            return AjaxResult.success();
+        }
+        // 备货单有分配任务不可更新备货
+        List<WmsDocOrderDetails> wmsDocOrderDetailsList = iWmsDocOrderDetailsService.selectWmsDocOrderDetailsByOrderNo(orderNo);
+        for (WmsDocOrderDetails wmsDocOrderDetails : wmsDocOrderDetailsList) {
+            if (wmsDocOrderDetails.getQtyAllocated().compareTo(wmsDocOrderDetails.getQtySoftAllocated()) != 0) {
+                return AjaxResult.error("备货单正在备货,暂不可更新备货" + header.getOrderNo());
+            }
+        }
+        // 备货库存并且没有正在执行的出库任务
+        InvLocIdSearchFrom invLocIdSearchFrom = new InvLocIdSearchFrom();
+        invLocIdSearchFrom.setLotatt14(orderNo);
+        List<InvLotLocIdLotattVO> invLotLocIdLotattVOList = invLotLocIdService.selectInvLocIdLotattList(invLocIdSearchFrom);
+        for (InvLotLocIdLotattVO locIdLotattVO : invLotLocIdLotattVOList) {
+            String stockStatus = locIdLotattVO.getStockStatus();
+            if (!stockStatus.equals(Constant.STOCK_STATUS.STOCK00)) {
+                return AjaxResult.error("备货库存任务占用,暂不可更新备货" + locIdLotattVO.getLocationNo());
+            }
+        }
+        // 是否作废
+        if (erpOrderList.get(0).getVaild().equalsIgnoreCase("X")) {
+            return documentVoided(orderNo);
+        }
+        // 转换ERP单据为WMS明细
+        List<WmsDocOrderDetails> detailsErp = convertDocuments(erpOrderList, orderNo);
+        // 当前WMS明细
+        List<WmsDocOrderDetails> detailsWms = wmsDocOrderDetailsList;
+        // 对比ERP和WMS明细
+        Map<MODIFY_MARKER, List<WmsDocOrderDetails>> markerListMap = comparisonDocument(detailsErp, detailsWms);
+        // 变更出库明细和单头
+        updateQuantityAndStatusOfDocuments(markerListMap);
+        // 更新库存
+        updateInventory(markerListMap);
+        return null;
+    }
+
+    /**
+     * 变更出库明细和单头
+     *
+     * @param markerListMap
+     * @return
+     */
+    @Transactional
+    public AjaxResult updateQuantityAndStatusOfDocuments(Map<MODIFY_MARKER, List<WmsDocOrderDetails>> markerListMap) {
+        for (Map.Entry<MODIFY_MARKER, List<WmsDocOrderDetails>> modify_markerListEntry : markerListMap.entrySet()) {
+            MODIFY_MARKER key = modify_markerListEntry.getKey();
+            List<WmsDocOrderDetails> value = modify_markerListEntry.getValue();
+            switch (key) {
+                case INSERT:
+                    detailsInsert(value);
+                    break;
+                case DELETE:
+                    detailsDelete(value);
+                    break;
+                case ADD:
+                    detailsAdd(value);
+                    break;
+                case DECREASE:
+                    detailsDecrease(value);
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        return AjaxResult.success();
+    }
+
+    /**
+     * 更新库存
+     *
+     * @param markerListMap
+     * @return
+     */
+    @Transactional
+    public AjaxResult updateInventory(Map<MODIFY_MARKER, List<WmsDocOrderDetails>> markerListMap) {
+        for (Map.Entry<MODIFY_MARKER, List<WmsDocOrderDetails>> modify_markerListEntry : markerListMap.entrySet()) {
+            MODIFY_MARKER key = modify_markerListEntry.getKey();
+            List<WmsDocOrderDetails> value = modify_markerListEntry.getValue();
+            switch (key) {
+                case INSERT:
+                    detailsInsert(value);
+                    break;
+                case DELETE:
+                    detailsDelete(value);
+                    break;
+                case ADD:
+                    detailsAdd(value);
+                    break;
+                case DECREASE:
+                    detailsDecrease(value);
+                    break;
+                default:
+                    break;
+            }
         }
 
+        return AjaxResult.success();
+    }
+
+    /**
+     * 单据失效
+     *
+     * @param orderNo
+     * @return
+     */
+    @Transactional
+    public AjaxResult documentVoided(String orderNo) {
         return null;
     }
+
+    /**
+     * 新增
+     *
+     * @param value
+     * @return
+     */
+    private AjaxResult detailsInsert(List<WmsDocOrderDetails> value) {
+        for (WmsDocOrderDetails details : value) {
+
+        }
+        return AjaxResult.success();
+    }
+
+    /**
+     * 删除
+     *
+     * @param value
+     * @return
+     */
+    private AjaxResult detailsDelete(List<WmsDocOrderDetails> value) {
+        return AjaxResult.success();
+    }
+
+    /**
+     * 增加数量
+     *
+     * @param value
+     * @return
+     */
+    private AjaxResult detailsAdd(List<WmsDocOrderDetails> value) {
+        return AjaxResult.success();
+    }
+
+    /**
+     * 减少数量
+     *
+     * @param value
+     * @return
+     */
+    private AjaxResult detailsDecrease(List<WmsDocOrderDetails> value) {
+        return AjaxResult.success();
+    }
+
+    /**
+     * 新增,修改库存
+     *
+     * @param value
+     * @return
+     */
+    private AjaxResult detailsInsertModifyInventory(List<WmsDocOrderDetails> value) {
+        return AjaxResult.success();
+    }
+
+    /**
+     * 删除,修改库存
+     *
+     * @param value
+     * @return
+     */
+    private AjaxResult detailsDeleteModifyInventory(List<WmsDocOrderDetails> value) {
+        return AjaxResult.success();
+    }
+
+    /**
+     * 增加数量,修改库存
+     *
+     * @param value
+     * @return
+     */
+    private AjaxResult detailsAddModifyInventory(List<WmsDocOrderDetails> value) {
+        return AjaxResult.success();
+    }
+
+    /**
+     * 减少数量,修改库存
+     *
+     * @param value
+     * @return
+     */
+    private AjaxResult detailsDecreaseModifyInventory(List<WmsDocOrderDetails> value) {
+        return AjaxResult.success();
+    }
+
+
+    /**
+     * 对比ERP和WMS明细
+     *
+     * @param detailsErp
+     * @param detailsWms
+     * @return 返回差异
+     */
+    public Map<MODIFY_MARKER, List<WmsDocOrderDetails>> comparisonDocument(List<WmsDocOrderDetails> detailsErp, List<WmsDocOrderDetails> detailsWms) {
+        Map<MODIFY_MARKER, List<WmsDocOrderDetails>> markerListMap = new HashMap<>();
+        // 新增
+        List<WmsDocOrderDetails> detailsInsert = detailsErp.stream().filter(a -> {
+            String orderNo = a.getOrderNo();
+            String edi07 = a.getdEdi07();
+            for (WmsDocOrderDetails details : detailsWms) {
+                if (details.getOrderNo().equals(orderNo) && details.getdEdi07().equals(edi07)) {
+                    return false;
+                }
+            }
+            return true;
+        }).collect(Collectors.toList());
+        // 删除
+        List<WmsDocOrderDetails> detailsDel = detailsWms.stream().filter(a -> {
+            String orderNo = a.getOrderNo();
+            String edi07 = a.getdEdi07();
+            for (WmsDocOrderDetails details : detailsErp) {
+                if (details.getOrderNo().equals(orderNo) && details.getdEdi07().equals(edi07)) {
+                    return false;
+                }
+            }
+            return true;
+        }).collect(Collectors.toList());
+        // 增加
+        List<WmsDocOrderDetails> detailsAdd = detailsWms.stream().filter(a -> {
+            String orderNo = a.getOrderNo();
+            String edi07 = a.getdEdi07();
+            BigDecimal qtyWms = a.getQtyOrdered();
+            for (WmsDocOrderDetails details : detailsErp) {
+                if (details.getOrderNo().equals(orderNo) && details.getdEdi07().equals(edi07)) {
+                    BigDecimal qtyErp = details.getQtyOrdered();
+                    if (qtyWms.compareTo(qtyErp) == -1) {
+                        // 需要增加的数量
+                        BigDecimal qtyAdd = qtyErp.subtract(qtyWms);
+                        a.setQtyOrdered(qtyAdd);
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }).collect(Collectors.toList());
+        // 减少
+        List<WmsDocOrderDetails> detailsDecrease = detailsWms.stream().filter(a -> {
+            String orderNo = a.getOrderNo();
+            String edi07 = a.getdEdi07();
+            BigDecimal qtyWms = a.getQtyOrdered();
+            for (WmsDocOrderDetails details : detailsErp) {
+                if (details.getOrderNo().equals(orderNo) && details.getdEdi07().equals(edi07)) {
+                    BigDecimal qtyErp = details.getQtyOrdered();
+                    if (qtyWms.compareTo(qtyErp) == 1) {
+                        BigDecimal qtyDec = qtyWms.subtract(qtyErp);
+                        a.setQtyOrdered(qtyDec);
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }).collect(Collectors.toList());
+
+        markerListMap.put(MODIFY_MARKER.INSERT, detailsInsert);
+        markerListMap.put(MODIFY_MARKER.DELETE, detailsDel);
+        markerListMap.put(MODIFY_MARKER.ADD, detailsAdd);
+        markerListMap.put(MODIFY_MARKER.DECREASE, detailsDecrease);
+        return markerListMap;
+    }
+
+
+    /**
+     * 转换ERP为WMS单据
+     *
+     * @param erpOrderList
+     * @param orderNo
+     * @return
+     */
+    public List<WmsDocOrderDetails> convertDocuments(List<ErpOrderList> erpOrderList, String orderNo) {
+        List<WmsDocOrderDetails> detailsArrayList = new ArrayList<>();
+        WmsDocOrderDetails details = null;
+        for (ErpOrderList erpOrder : erpOrderList) {
+            String erpOrderNo = erpOrder.getOrderNo() + "";
+            details = new WmsDocOrderDetails();
+            details.setOrderNo(orderNo);
+            details.setOrderLineNo(BigDecimal.valueOf(0));
+            details.setLineStatus(Constant.ORDER_STS.STS00.getValue());
+            details.setQtyOrdered(erpOrder.getQty());
+            details.setQtyOrderedEach(erpOrder.getQty());
+            details.setQtyAllocatedEach(BigDecimal.ZERO);
+            details.setQtyAllocated(BigDecimal.ZERO);
+            details.setQtySoftAllocated(BigDecimal.ZERO);
+            details.setQtySoftallocatedEach(BigDecimal.ZERO);
+            details.setCustomerId(Constant.CUSTOMER_ID);
+            details.setQtyShippedEach(BigDecimal.ZERO);
+            details.setQtyShipped(BigDecimal.ZERO);
+            details.setQtyPicked(BigDecimal.ZERO);
+            details.setQtyPickedEach(BigDecimal.ZERO);
+            details.setQtyPacked(BigDecimal.ZERO);
+            details.setQtyPackedEach(BigDecimal.ZERO);
+            details.setSku(erpOrder.getIma01()); //品号
+            details.setdEdi04(erpOrder.getVaild());//单据状态
+            details.setdEdi05(erpOrder.getStockId());//仓库编号
+            details.setdEdi06(erpOrder.getOrderState());//是否扫描完成
+            details.setdEdi07(erpOrderNo); //项次
+            details.setdEdi08(erpOrder.getOrderType());//erp单据类型
+            details.setdEdi09(erpOrder.getInout());//erp出入库类型
+            details.setCreateTime(new Date());
+            details.setCreateBy(erpOrder.getCreateUser());
+            detailsArrayList.add(details);
+        }
+        return detailsArrayList;
+    }
 }

+ 1 - 1
warewms-ams/src/main/java/com/ruoyi/ams/order/service/impl/WmsDocOrderHeaderServiceImpl.java

@@ -825,7 +825,7 @@ public class WmsDocOrderHeaderServiceImpl implements IWmsDocOrderHeaderService {
             WmsDocOrderHeader wmsDocOrderHeader = wmsDocOrderHeaderService.selectWmsDocOrderHeaderByOrderNo(orderNo);
             if (!wmsDocOrderHeader.getOrderType().equals(Constant.ORDER_TYP.BH.getValue())) {
                 log.error("出库单类型必须为备货!" + wmsDocOrderHeader.getSoReference1());
-                return null;
+                return endCheckOutVOList;
             }
         }
         for (String orderNo : orderNoList) {