自动化立体仓库 - WMS系统
Junjie
2023-05-29 e607f23451a8d7d5feb4ed19ad8eb9227905aaf6
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -160,8 +160,38 @@
    @Transactional
    public void startupFullTakeStore(StockOutParam param, Long userId) {
        ArrayList<String> locNos = new ArrayList<>();
        for (StockOutParam.LocDetl locDetl:param.getLocDetls()){
            if (!locNos.contains(locDetl.getLocNo())){
        List<StockOutParam.LocDetl> locDetls = new ArrayList<>();
        ArrayList<String> matnrs = new ArrayList<>();//目的做数据去重
        for (StockOutParam.LocDetl locDetl : param.getLocDetls()) {
            if (!matnrs.contains(locDetl.getMatnr())) {
                matnrs.add(locDetl.getMatnr());
                //1.根据物料号先搜索高频区域是否有库存
                List<StockOutParam.LocDetl> locNoStep1 = this.findLocNoStep1(locDetl);
                if (locNoStep1 != null) {
                    locDetls.addAll(locNoStep1);
                    continue;
                }
                //高频混放区域没有满足的库位,在单品区域进行搜索
                List<StockOutParam.LocDetl> locNoStep2 = this.findLocNoStep2(locDetl);
                if (locNoStep2 != null) {
                    locDetls.addAll(locNoStep2);
                    continue;
                }
                //低频混放区域进行搜索
                List<StockOutParam.LocDetl> locNoStep3 = this.findLocNoStep3(locDetl);
                if (locNoStep3 != null) {
                    locDetls.addAll(locNoStep3);
                    continue;
                }
            }
        }
        for (StockOutParam.LocDetl locDetl : locDetls) {
            if (!locNos.contains(locDetl.getLocNo())) {
                locNos.add(locDetl.getLocNo());
            }
        }
@@ -173,7 +203,7 @@
        BasDevp staNo = basDevpService.checkSiteStatus(param.getOutSite());
        // 获取库位明细
        List<LocDetlDto> locDetlDtos = new ArrayList<>();
        for (StockOutParam.LocDetl paramLocDetl : param.getLocDetls()) {
        for (StockOutParam.LocDetl paramLocDetl : locDetls) {
            if (!Cools.isEmpty(paramLocDetl.getLocNo(), paramLocDetl.getMatnr(), paramLocDetl.getCount())) {
                LocDetl one = locDetlService.selectItem(paramLocDetl.getLocNo(), paramLocDetl.getMatnr(), paramLocDetl.getBatch());
                if (null != one) locDetlDtos.add(new LocDetlDto(one, paramLocDetl.getCount()));
@@ -192,6 +222,132 @@
        }
    }
    //1.根据物料号先搜索高频区域是否有库存
    private List<StockOutParam.LocDetl> findLocNoStep1(StockOutParam.LocDetl locDetl) {
        List<StockOutParam.LocDetl> locDetlList = new ArrayList<>();
        //1.根据物料号先搜索高频区域是否有库存
        List<LocDetl> locDetls = locDetlService.findHighAreaByMatnr(locDetl.getMatnr());
        if (locDetls.size() > 0) {
            for (LocDetl locDetl0 : locDetls) {
                if (locDetl0.getAnfme() >= locDetl.getCount()) {
                    //找到的库存 >= 所需库存,满足条件
                    locDetlList.add(new StockOutParam.LocDetl(locDetl0.getLocNo(), locDetl.getMatnr(), locDetl.getBatch(), locDetl.getCount()));
                    return locDetlList;
                } else {
                    //不满足库存条件
                    //判断最外侧库位的深处是否有相同物料
                    Double useCount = locDetl0.getAnfme();//已使用的数量
                    List<StockOutParam.LocDetl> tmpLocDetlList = new ArrayList<>();//记录经过的库位
                    tmpLocDetlList.add(new StockOutParam.LocDetl(locDetl0.getLocNo(), locDetl.getMatnr(), locDetl.getBatch(), locDetl0.getAnfme()));
                    List<String> insideLoc = Utils.getGroupInsideLoc(locDetl0.getLocNo());
                    List<LocDetl> locDetls1 = locDetlService.selectByLocNosAndMatnr(insideLoc, locDetl.getMatnr());
                    if (locDetls1.size() == 0) {//内侧库位没有相同的物料,跳过
                        continue;
                    }
                    for (LocDetl detl : locDetls1) {
                        double lastCount = locDetl.getCount() - useCount;//剩余所需数量
                        double realCount = 0;//实际提供数量
                        if (detl.getAnfme() >= lastCount) {//实际数量大于所需数量,按所需数量提供
                            realCount = lastCount;
                        }else {
                            //实际小于所需数量,按实际数量提供
                            realCount = detl.getAnfme();
                        }
                        useCount += realCount;
                        tmpLocDetlList.add(new StockOutParam.LocDetl(detl.getLocNo(), locDetl.getMatnr(), locDetl.getBatch(), realCount));
                        if (useCount >= locDetl.getCount()) {
                            //找到的库存 >= 所需库存,满足条件
                            locDetlList.addAll(tmpLocDetlList);
                            return locDetlList;
                        }
                    }
                }
            }
            //最外侧包括内侧都无满足库位,则判断搜索出来的全部最外侧库位加起来是否满足出库数量要求
            Double useCount = 0D;
            for (LocDetl locDetl0 : locDetls) {
                double lastCount = locDetl.getCount() - useCount;//剩余所需数量
                double realCount = 0;//实际提供数量
                if (locDetl0.getAnfme() >= lastCount) {//实际数量大于所需数量,按所需数量提供
                    realCount = lastCount;
                }else {
                    //实际小于所需数量,按实际数量提供
                    realCount = locDetl0.getAnfme();
                }
                useCount += realCount;//已使用的数量
                locDetlList.add(new StockOutParam.LocDetl(locDetl0.getLocNo(), locDetl.getMatnr(), locDetl.getBatch(), realCount));
                if (useCount >= locDetl.getCount()) {
                    //找到的库存 >= 所需库存,满足条件
                    return locDetlList;
                }
            }
        }
        return null;
    }
    //高频混放区域没有满足的库位,在单品区域进行搜索
    private List<StockOutParam.LocDetl> findLocNoStep2(StockOutParam.LocDetl locDetl) {
        List<StockOutParam.LocDetl> locDetlList = new ArrayList<>();
        //在单品区域进行搜索
        List<LocDetl> locDetls = locDetlService.findSingleAreaByMatnr(locDetl.getMatnr());
        if (locDetls.size() > 0) {
            Double useCount = 0D;
            for (LocDetl locDetl0 : locDetls) {
                double lastCount = locDetl.getCount() - useCount;//剩余所需数量
                double realCount = 0;//实际提供数量
                if (locDetl0.getAnfme() >= lastCount) {//实际数量大于所需数量,按所需数量提供
                    realCount = lastCount;
                }else {
                    //实际小于所需数量,按实际数量提供
                    realCount = locDetl0.getAnfme();
                }
                useCount += realCount;//已使用的数量
                locDetlList.add(new StockOutParam.LocDetl(locDetl0.getLocNo(), locDetl.getMatnr(), locDetl.getBatch(), realCount));
                if (useCount >= locDetl.getCount()) {
                    //找到的库存 >= 所需库存,满足条件
                    return locDetlList;
                }
            }
        }
        return null;
    }
    //低频混放区域进行搜索
    private List<StockOutParam.LocDetl> findLocNoStep3(StockOutParam.LocDetl locDetl) {
        List<StockOutParam.LocDetl> locDetlList = new ArrayList<>();
        //在单品区域进行搜索
        List<LocDetl> locDetls = locDetlService.findLowAreaByMatnr(locDetl.getMatnr());
        if (locDetls.size() > 0) {
            Double useCount = 0D;
            for (LocDetl locDetl0 : locDetls) {
                double lastCount = locDetl.getCount() - useCount;//剩余所需数量
                double realCount = 0;//实际提供数量
                if (locDetl0.getAnfme() >= lastCount) {//实际数量大于所需数量,按所需数量提供
                    realCount = lastCount;
                }else {
                    //实际小于所需数量,按实际数量提供
                    realCount = locDetl0.getAnfme();
                }
                useCount += realCount;//已使用的数量
                locDetlList.add(new StockOutParam.LocDetl(locDetl0.getLocNo(), locDetl.getMatnr(), locDetl.getBatch(), realCount));
                if (useCount >= locDetl.getCount()) {
                    //找到的库存 >= 所需库存,满足条件
                    return locDetlList;
                }
            }
        }
        return null;
    }
    @Override
    @Transactional
    public void stockOut(BasDevp staNo, List<LocDetlDto> locDetlDtos, IoWorkType ioWorkType, Long userId) {