فهرست منبع

fix: 库位预警,推荐物料合并前后端接口调试

wang.sq@aliyun.com 1 سال پیش
والد
کامیت
8fddee1d0e

+ 15 - 0
src/main/java/com/imcs/admin/business/controller/ImportOrExportPolicyController.java

@@ -5,6 +5,7 @@ import com.imcs.admin.common.Result;
 import com.imcs.admin.entity.WPalletManagement;
 import com.imcs.admin.entity.assemble.RequiredMaterialDetail;
 import com.imcs.admin.entity.query.PolicyInputQuery;
+import com.imcs.admin.vo.MergeMaterielVo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -77,4 +78,18 @@ public class ImportOrExportPolicyController {
         return importOrExportPolicyService.findBlankPanelExportPolicy(wPalletManagement);
     }
 
+    /**
+     * 空盘出库策略
+     * @return
+     */
+    @RequestMapping(value = "/recommended_combined_pallet", method = RequestMethod.POST)
+    public Result recommendedCombinedPallet(@RequestBody MergeMaterielVo mergeMaterielVo){
+        /**
+         * 1、需要根据库房查询出出库策略
+         * 2、根据出库策略计算出库的托盘位置
+         */
+
+        return importOrExportPolicyService.recommendedCombinedPallet(mergeMaterielVo);
+    }
+
 }

+ 4 - 0
src/main/java/com/imcs/admin/business/dao/WInventoryManagementDao.java

@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.imcs.admin.entity.WInventoryManagement;
 import com.imcs.admin.entity.WInventoryManagementDetail;
 import com.imcs.admin.entity.WPalletManagement;
+import com.imcs.admin.entity.assemble.MergeMaterielGroup;
 import com.imcs.admin.entity.assemble.WInventoryManagementGroup;
+import com.imcs.admin.vo.MergeMaterielVo;
 import com.imcs.admin.vo.WInventoryManagementDetailVo;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
@@ -29,4 +31,6 @@ public interface WInventoryManagementDao extends BaseMapper<WInventoryManagement
     List<WInventoryManagementDetail>  queryByInventoryManagementId(Long id);
 
     List<WInventoryManagementDetail> selectByStorage(String storageLocation);
+
+    List<MergeMaterielGroup> findMergeMaterielGroup(@Param("mergeMaterielPar") MergeMaterielVo mergeMaterielVo);
 }

+ 3 - 0
src/main/java/com/imcs/admin/business/dao/WStoragelocationWarningDao.java

@@ -2,6 +2,7 @@ package com.imcs.admin.business.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.imcs.admin.entity.WStoragelocationWarning;
+import com.imcs.admin.vo.MergeMaterielVo;
 import com.imcs.admin.vo.WStoragelocationWarningVo;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
@@ -21,5 +22,7 @@ public interface WStoragelocationWarningDao extends BaseMapper<WStoragelocationW
 
     List<WStoragelocationWarning> queryByLimit(@Param(value = "storagelocationWarningVo") WStoragelocationWarningVo storagelocationWarningVo);
 
+    List<WStoragelocationWarning> findRule(@Param(value = "mergeMaterielPar") MergeMaterielVo mergeMaterielVo);
+
 
 }

+ 8 - 0
src/main/java/com/imcs/admin/business/service/ImportOrExportPolicyService.java

@@ -5,6 +5,7 @@ import com.imcs.admin.common.Result;
 import com.imcs.admin.entity.WPalletManagement;
 import com.imcs.admin.entity.assemble.RequiredMaterialDetail;
 import com.imcs.admin.entity.query.PolicyInputQuery;
+import com.imcs.admin.vo.MergeMaterielVo;
 
 import java.util.List;
 
@@ -33,4 +34,11 @@ public interface ImportOrExportPolicyService {
      */
     public Result findBlankPanelExportPolicy(WPalletManagement wPalletManagement);
 
+    /**
+     * 推荐合并数据
+     * @param mergeMaterielVo
+     * @return
+     */
+    public Result recommendedCombinedPallet(MergeMaterielVo mergeMaterielVo);
+
 }

+ 36 - 4
src/main/java/com/imcs/admin/business/service/impl/ImportOrExportPolicyServiceImpl.java

@@ -5,10 +5,7 @@ import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.imcs.admin.business.constants.Status;
-import com.imcs.admin.business.dao.ImportOrExportPolicyMapper;
-import com.imcs.admin.business.dao.WInventoryManagementDao;
-import com.imcs.admin.business.dao.WShelfManagementDao;
-import com.imcs.admin.business.dao.WWarehouseManagementMapper;
+import com.imcs.admin.business.dao.*;
 import com.imcs.admin.business.service.ImportOrExportPolicyService;
 import com.imcs.admin.common.BeanCopyUtil;
 import com.imcs.admin.common.ListUtils;
@@ -18,6 +15,7 @@ import com.imcs.admin.common.wmspolicy.impl.ImportOrExportPolicyContext;
 import com.imcs.admin.entity.*;
 import com.imcs.admin.entity.assemble.*;
 import com.imcs.admin.entity.query.PolicyInputQuery;
+import com.imcs.admin.vo.MergeMaterielVo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -307,4 +305,38 @@ public class ImportOrExportPolicyServiceImpl implements ImportOrExportPolicyServ
 
         return importOrExportPolicyContext.blankPanelExportPolicy(policyOutPar);
     }
+
+
+    @Autowired
+    private WStoragelocationWarningDao storagelocationWarningDao;
+
+    @Override
+    public Result recommendedCombinedPallet(MergeMaterielVo mergeMaterielVo) {
+
+        if(mergeMaterielVo.getWarehouseCode() == null){
+            return Result.error("库房编码不能为空");
+        }
+        if(mergeMaterielVo.getShelfCode() == null){
+            return Result.error("货架编码不能为空");
+        }
+        if(mergeMaterielVo.getPalletType() == null){
+            return Result.error("托盘类型不能为空");
+        }
+
+        //
+        List<WStoragelocationWarning> rule = storagelocationWarningDao.findRule(mergeMaterielVo);
+        if(ListUtils.isEmpty(rule)){
+            return Result.error("预警规则为空");
+        }
+
+        List<MergeMaterielGroup> mergeMaterielGroups = wInventoryManagementDao.findMergeMaterielGroup(mergeMaterielVo);
+
+        if(ListUtils.isEmpty(mergeMaterielGroups)){
+            return Result.error("无存储数据");
+        }
+
+        Result result = importOrExportPolicyContext.MergeMaterielPolicy(mergeMaterielGroups, rule.get(0));
+
+        return result;
+    }
 }

+ 2 - 2
src/main/java/com/imcs/admin/business/service/impl/WStoragelocationWarningServiceImpl.java

@@ -69,8 +69,8 @@ public class WStoragelocationWarningServiceImpl implements WStoragelocationWarni
             String key = item.getWarehouseCode()+"\n"+ item.getShelfCode() +"\n"+item.getPalletType()+"\n"+ Constants.FIRST;
             String key1 = item.getWarehouseCode()+"\n"+ item.getShelfCode() +"\n"+item.getPalletType()+"\n"+ Constants.SIX;
 
-            item.setKtpNumbers(0L);
-            item.setKkwNumbers(0L);
+            item.setKtpNumbers(0l);
+            item.setKkwNumbers(0l);
             if(ListUtils.isNotEmpty(hashMap.get(key))){
                 item.setKkwNumbers(hashMap.get(key).get(0).getNumbers());
             }

+ 165 - 12
src/main/java/com/imcs/admin/common/wmspolicy/impl/ImportOrExportPolicyContext.java

@@ -1,20 +1,22 @@
 package com.imcs.admin.common.wmspolicy.impl;
 
+import com.imcs.admin.common.BeanCopyUtil;
 import com.imcs.admin.common.ListUtils;
 import com.imcs.admin.common.Result;
 import com.imcs.admin.common.constants.Constants;
 import com.imcs.admin.common.wmspolicy.ImportOrExportPolicy;
 import com.imcs.admin.entity.ImportOrExportPolicyPo;
+import com.imcs.admin.entity.WStoragelocationWarning;
 import com.imcs.admin.entity.assemble.*;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeansException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.annotation.Bean;
 import org.springframework.stereotype.Component;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
 @Component
@@ -196,13 +198,164 @@ public class ImportOrExportPolicyContext implements ApplicationContextAware {
     }
 
 
-//
-//    public static TestStrategy getStrategy(String code){
-//        TestStrategy testStrategy = testServiceMap.get(code);
-//        if (Objects.isNull(testStrategy)) {
-//            // 如果通过自定义编码没能找到具体实现类, 去执行默认的实现类代码
-//            return testServiceMap.get("default");
-//        } else
-//            return testStrategy;
-//    }
+    /**
+     * 合并出库策略
+     * @return
+     */
+    public Result MergeMaterielPolicy(List<MergeMaterielGroup> mergeMaterielGroups, WStoragelocationWarning storagelocationWarning){
+        HashMap<String , MergeMaterielGroup> materielHashMap = new HashMap();
+        for (MergeMaterielGroup mergeMaterielGroup : mergeMaterielGroups) {
+            materielHashMap.put(mergeMaterielGroup.getPalletCode()+"\n"+ mergeMaterielGroup.getMaterialCode(), mergeMaterielGroup);
+        }
+
+        Map<String, List<MergeMaterielGroup>> collect = mergeMaterielGroups.stream().collect(Collectors.groupingBy(MergeMaterielGroup::getPalletCode));
+
+        List<MergeMaterielGroup> materielGroups = ListUtils.newArrayList();
+
+        collect.forEach((s, items) -> {
+
+            // 总重
+            Double allUpWeight = items.stream()
+                    .map(item -> (item.getAmount() == null ? 0 : item.getAmount()) * (item.getMaterialWeight() == null ? 1 : item.getMaterialWeight()))
+                    .reduce(0.0, Double::sum);
+
+            // 总数量
+            Integer amount = items.stream()
+                    .map(item -> item.getAmount())
+                    .reduce(0, Integer::sum);
+
+            MergeMaterielGroup materielGroup = BeanCopyUtil.copyPropertiesSet(items.get(0), MergeMaterielGroup::new);
+            materielGroup.setAllUpWeight(allUpWeight);
+            materielGroup.setAmount(amount);
+
+            materielGroups.add(materielGroup);
+        });
+
+        // 根据需求计算出需要腾出的箱子数
+        Integer warningNumber = storagelocationWarning.getWarningNumber();
+
+        // 升序排序
+        List<MergeMaterielGroup> collect1 = materielGroups.stream().sorted(Comparator.comparingDouble(MergeMaterielGroup::getAllUpWeight))
+                .collect(Collectors.toList());
+
+        // 降序排序
+        List<MergeMaterielGroup> collect2 = materielGroups.stream().sorted(Comparator.comparingDouble(MergeMaterielGroup::getAllUpWeight).reversed())
+                .collect(Collectors.toList());
+
+        HashMap<String, MergeMaterielGroup> newHashMap= new HashMap<>();
+        HashMap<String, MergeMaterielGroup> useHashMap= new HashMap<>();
+
+        // 求第一个,满足的数据
+        for (MergeMaterielGroup materielGroup : collect1) {
+            if(newHashMap!=null && newHashMap.size() >= warningNumber){
+                log.info("以满足需求");
+            }
+
+            if(useHashMap !=null && useHashMap.get(materielGroup.getPalletCode()) != null){
+                log.info("主数据已被使用,跳过进行下一个");
+                continue;
+            }
+
+            // 需要对这里面的集合进行合并到其他料箱中
+            List<MergeMaterielGroup> tempMaterielGroups = collect.get(materielGroup.getPalletCode());
+
+            for (MergeMaterielGroup needToMergeMateriel : tempMaterielGroups) {
+                // 倒叙循环物料集合, 优先合并到物料最终的料箱中
+                for (MergeMaterielGroup mergeMaterielGroup : collect2) {
+                    // 判断此需要合并的物料在此料箱中是否存在
+                    MergeMaterielGroup materialIsExist= materielHashMap.get(mergeMaterielGroup.getPalletCode() + "\n" + needToMergeMateriel.getMaterialCode());
+                    if(materialIsExist == null){
+                        log.info("此物料箱不存在此物料,物料编码{},被合并物料{},合并物料{}",needToMergeMateriel.getMaterialCode(), needToMergeMateriel.getPalletCode(), mergeMaterielGroup.getPalletCode());
+                        continue;
+                    }
+                    if(materielGroup.getPalletCode().equals( materialIsExist.getPalletCode())){
+                        log.info("相同料箱不做处理");
+                        continue;
+                    }
+                    if(newHashMap !=null && newHashMap.get(materialIsExist.getPalletCode()) != null){
+                        log.info("包含主数据,放弃查找下一个");
+                        continue;
+                    }
+
+                    double combinedAllUpWeight = mergeMaterielGroup.getAllUpWeight() + (needToMergeMateriel.getAmount() * (needToMergeMateriel.getMaterialWeight() == null? 1: needToMergeMateriel.getMaterialWeight() ));
+                    if(materialIsExist.getPalletMaxLoad() !=null && combinedAllUpWeight> Double.valueOf(materialIsExist.getPalletMaxLoad())){
+                        log.info("料箱剩余容器不满足要求");
+                        continue;
+                    }
+
+                    // 合并临时主数据参数
+                    // 此料箱下:合并后的总数量
+                    int  consolidatedQuantity = needToMergeMateriel.getAmount() + mergeMaterielGroup.getAmount();
+                    mergeMaterielGroup.setAmount(consolidatedQuantity);
+                    mergeMaterielGroup.setAllUpWeight(combinedAllUpWeight);
+
+                    // 设置合并后的参数
+                    // 此物料下:合并后的总数量
+                    Integer consolidatedAmount = materialIsExist.getAmount() + needToMergeMateriel.getAmount();
+                    // 此物料下:合并后的总数量
+                    Double allUpWeight = consolidatedAmount * (materialIsExist.getMaterialWeight() == null ? 1 : materialIsExist.getMaterialWeight());
+
+                    materialIsExist.setConsolidatedAmount(consolidatedAmount);
+                    materialIsExist.setAllUpWeight(allUpWeight);
+
+                    MergeMaterielGroup newMaterielGroup = newHashMap.get(needToMergeMateriel.getPalletCode());
+                    if(newMaterielGroup == null){
+                        newMaterielGroup = BeanCopyUtil.copyPropertiesSet(needToMergeMateriel, MergeMaterielGroup::new);
+                    }
+
+                    if(ListUtils.isEmpty(newMaterielGroup.getChildren())){
+                        newMaterielGroup.setChildren(ListUtils.newArrayList());
+                    }
+                    newMaterielGroup.getChildren().add(materialIsExist);
+
+                    newHashMap.put(newMaterielGroup.getPalletCode(), newMaterielGroup);
+
+                    // 使用的数据物料编号填充到map 保证 不会下次使用到
+                    useHashMap.put(needToMergeMateriel.getPalletCode(), needToMergeMateriel);
+                    useHashMap.put(materialIsExist.getPalletCode(), materialIsExist);
+
+                    break ;
+                }
+            }
+        }
+
+
+        List<MergeMaterielGroup> newMaterielGroups = ListUtils.newArrayList();
+        /**
+         * 转换成集合返回
+         */
+
+        AtomicReference<Long> tempId = new AtomicReference<>(1l);
+        newHashMap.forEach((s, temp) -> {
+            MergeMaterielGroup newMaterielGroup = BeanCopyUtil.copyPropertiesSet(temp, MergeMaterielGroup::new);
+            newMaterielGroup.setId(tempId.getAndSet(tempId.get() + 1));
+            newMaterielGroup.setMaterialCode(null);
+            newMaterielGroup.setMaterialName(null);
+
+            if(ListUtils.isEmpty(newMaterielGroup.getChildren())){
+                newMaterielGroup.setChildren(ListUtils.newArrayList());
+            }else {
+                newMaterielGroup.setChildren(null);
+                newMaterielGroup.setChildren(ListUtils.newArrayList());
+            }
+
+            List<MergeMaterielGroup> children = temp.getChildren();
+            if(ListUtils.isNotEmpty(children)){
+                for (MergeMaterielGroup child : children) {
+                    MergeMaterielGroup materielGroup = BeanCopyUtil.copyPropertiesSet(child, MergeMaterielGroup::new);
+                    materielGroup.setId(tempId.getAndSet(tempId.get() + 1));
+                    newMaterielGroup.getChildren().add(materielGroup);
+                }
+            }
+            newMaterielGroups.add(newMaterielGroup);
+        });
+
+        if(ListUtils.isEmpty(newMaterielGroups)){
+            return Result.error("不满足合并要求");
+        }
+
+        return Result.success(newMaterielGroups);
+    }
+
+
 }

+ 72 - 0
src/main/java/com/imcs/admin/entity/assemble/MergeMaterielGroup.java

@@ -0,0 +1,72 @@
+package com.imcs.admin.entity.assemble;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Project: zh_wms-code-platform
+ * @Package: com.imcs.admin.entity.assemble
+ * @Author: Lenovo
+ * @Time: 2024 - 07 - 04 14 : 03
+ * @Description:
+ */
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class MergeMaterielGroup implements Serializable {
+
+    private Long id;
+
+    // 库房编码
+    private String warehouseCode;
+    // 货架编码
+    private String shelfCode;
+    //托盘类型(字典表)
+    private Integer palletType;
+    // 托盘编号
+    private String palletCode;
+    // 存储位置
+    private String storageLocationCode;
+    /**
+     * 入库数量
+     */
+    private Integer amount;
+
+    /**
+     * 合并后数量
+     */
+    private Integer consolidatedAmount;
+    /**
+     * 物料编码
+     */
+    private String materialCode;
+    /**
+     * 物料编码
+     */
+    private String materialName;
+    /**
+     * 单个物料重量
+     */
+    private Double materialWeight;
+    /**
+     * 总重
+     */
+    private Double allUpWeight;
+
+    /**
+     * 托盘承重
+     */
+    private String palletMaxLoad;
+
+    List<MergeMaterielGroup> children;
+
+
+
+}

+ 49 - 0
src/main/java/com/imcs/admin/vo/MergeMaterielVo.java

@@ -0,0 +1,49 @@
+package com.imcs.admin.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @Project: zh_wms-code-platform
+ * @Package: com.imcs.admin.vo
+ * @Author: Lenovo
+ * @Time: 2024 - 07 - 04 12 : 58
+ * @Description: 物料合并
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class MergeMaterielVo implements Serializable {
+
+    // 库房编码
+    private String warehouseCode;
+    // 货架编码
+    private String shelfCode;
+    //托盘类型(字典表)
+    private Integer palletType;
+    // 托盘编号
+    private String palletCode;
+    /**
+     * 入库数量
+     */
+    private Integer amount;
+    /**
+     * 物料编码
+     */
+    private String materialCode;
+    /**
+     * 物料编码
+     */
+    private String materialName;
+    /**
+     * 物料重量
+     */
+    private Double materialWeight;
+
+
+}

+ 23 - 0
src/main/resources/mapper/WInventoryManagementDao.xml

@@ -110,4 +110,27 @@
 
     </select>
 
+    <select id="findMergeMaterielGroup" resultType="com.imcs.admin.entity.assemble.MergeMaterielGroup">
+        SELECT
+            wim.warehouse_code,
+            wim.shelf_code,
+            wpm.pallet_type,
+            wpm.pallet_code,
+            wimd.amount,
+            wim.storage_location_code,
+            wm.material_code,
+            wm.material_name,
+            wm.material_weight,
+            wpm.pallet_max_load
+        FROM
+            w_inventory_management wim
+                LEFT JOIN w_inventory_management_detail wimd ON wim.id = wimd.inventory_management_id
+                LEFT JOIN w_pallet_management wpm on wim.pallet_code = wpm.pallet_code
+                LEFT JOIN w_material wm ON wm.material_code = wimd.material_code
+        WHERE wim.warehouse_code = #{mergeMaterielPar.warehouseCode}
+          AND wim.shelf_code = #{mergeMaterielPar.shelfCode}
+          AND wpm.pallet_type  = #{mergeMaterielPar.palletType}
+
+    </select>
+
 </mapper>

+ 10 - 0
src/main/resources/mapper/WStorageLocationWarningDao.xml

@@ -21,5 +21,15 @@
         order by warehouse_code ASC, shelf_code ASC
     </select>
 
+    <select id="findRule" resultType="com.imcs.admin.entity.WStoragelocationWarning">
+        SELECT
+        *
+        FROM
+        w_storage_location_warning
+        WHERE warehouse_code = #{mergeMaterielPar.warehouseCode}
+          AND shelf_code = #{mergeMaterielPar.shelfCode}
+          AND pallet_type  = #{mergeMaterielPar.palletType}
+    </select>
+
 </mapper>