skyouc
2025-01-07 d3f22f29b52d7b49e78ce905b6700c92a6096933
#平仓出库功能
8个文件已修改
259 ■■■■■ 已修改文件
zy-asrs-admin/src/components/orderOut/orderOutWavePreview/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/dto/MergePreviewResultLocDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/enums/LocAreaTypeSts.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/param/OrderOutMergeParam.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/manage/OutManage.java 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LocDetlServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/resources/application.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/resources/mapper/asrs/ViewLocDetlMapper.xml 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-admin/src/components/orderOut/orderOutWavePreview/index.vue
@@ -212,6 +212,8 @@
                    dataTmp.locNo = null;
                    dataTmp.locDetlId = null;
                    dataTmp.anfme = item.anfme;
                    dataTmp.typeId = val.typeId;
                    dataTmp.workQty = val.workQty;
                    dataTmp.key = idx;
                    dataTmp.operationPort = defaultOperationPort;
@@ -232,6 +234,8 @@
                        dataTmp.locId = val.locId;
                        dataTmp.locNo = val.locNo;
                        dataTmp.locDetlId = val.locDetlId;
                        dataTmp.typeId = val.typeId;
                        dataTmp.workQty = val.workQty;
                        dataTmp.anfme = anfme;
                        dataTmp.key = idx;
                        dataTmp.operationPort = defaultOperationPort;
@@ -244,6 +248,8 @@
                        dataTmp.locId = null;
                        dataTmp.locNo = null;
                        dataTmp.locDetlId = null;
                        dataTmp.typeId = val.typeId;
                        dataTmp.workQty = val.workQty;
                        dataTmp.anfme = isused;
                        dataTmp.key = idx;
                        dataTmp.operationPort = defaultOperationPort;
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/dto/MergePreviewResultLocDto.java
@@ -15,4 +15,6 @@
    private Double workQty;
    private Long typeId;
}
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/enums/LocAreaTypeSts.java
@@ -9,7 +9,7 @@
    //四方库
    LOC_AREA_TYPE_ROUND(1L, "四向库"),
    //UTC库
    LOC_AREA_TYPE_UTC(4L, "UTC库"),
    LOC_AREA_TYPE_UTC(4L, "TUC库"),
    //平库
    LOC_AREA_TYPE_FLAT(7L, "平库")
;
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/param/OrderOutMergeParam.java
@@ -1,5 +1,6 @@
package com.zy.asrs.wms.asrs.entity.param;
import com.mysql.cj.log.Log;
import lombok.Data;
import java.io.Serializable;
@@ -18,6 +19,10 @@
    private String batch;
    private Long workQty;
    private Long typeId;
    private Double anfme;
    private Long operationPort;
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/manage/OutManage.java
@@ -14,7 +14,6 @@
import com.zy.asrs.wms.utils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -161,34 +160,34 @@
        orderDetls = orderDetlService.parseDetl(orderDetls);
        HashMap<Long, List<LocDetl>> orderDetlLocMap = new HashMap<>();
        //出库订单合计
//        //出库订单合计
        List<OutDetlDto> detlDtos = new ArrayList<>();
        //获取平仓中符合条件的所有库位
        orderDetls.forEach(detl -> {
            double issued = Optional.of(detl.getAnfme() - detl.getQty() - detl.getWorkQty()).orElse(0.0D);
            if (issued <= 0.0D) {
                return;
            }
            List<LocDetl> locs = locDetlService.queryFlatStock(detl.getMat$().getMatnr(), detl.getBatch(), detl.getUniqueField());
            //平库有当明物料优先出库
            if (!locs.isEmpty()) {
                for (LocDetl locDetl : locs) {
                    if (issued > 0) {
                        OutDetlDto outDetlDto = new OutDetlDto();
                        outDetlDto.setDetlId(locDetl.getId());
                        outDetlDto.setAnfme(issued >= locDetl.getAnfme() ? locDetl.getAnfme() : issued);
                        outDetlDto.setStock(locDetl.getAnfme());
                        outDetlDto.setOrderDetlId(locDetl.getId());
                        detlDtos.add(outDetlDto);
                        issued = issued - outDetlDto.getAnfme();
                    }
                }
                //订单明细需出库数量
                double workQty = Optional.of(detl.getAnfme() - detl.getQty() - detl.getWorkQty()).orElse(0.0D);
                //更新平库订单明细的实际可用数量
                detl.setWorkQty(workQty - issued);
            }
        });
//        //获取平仓中符合条件的所有库位
//        orderDetls.forEach(detl -> {
//            double issued = Optional.of(detl.getAnfme() - detl.getQty() - detl.getWorkQty()).orElse(0.0D);
//            if (issued <= 0.0D) {
//                return;
//            }
//            List<LocDetl> locs = locDetlService.queryFlatStock(detl.getMat$().getMatnr(), detl.getBatch(), detl.getUniqueField());
//            //平库有当明物料优先出库
//            if (!locs.isEmpty()) {
//                for (LocDetl locDetl : locs) {
//                    if (issued > 0) {
//                        OutDetlDto outDetlDto = new OutDetlDto();
//                        outDetlDto.setDetlId(locDetl.getId());
//                        outDetlDto.setAnfme(issued >= locDetl.getAnfme() ? locDetl.getAnfme() : issued);
//                        outDetlDto.setStock(locDetl.getAnfme());
//                        outDetlDto.setOrderDetlId(locDetl.getId());
//                        detlDtos.add(outDetlDto);
//                        issued = issued - outDetlDto.getAnfme();
//                    }
//                }
//                //订单明细需出库数量
//                double workQty = Optional.of(detl.getAnfme() - detl.getQty() - detl.getWorkQty()).orElse(0.0D);
//                //更新平库订单明细的实际可用数量
//                detl.setWorkQty(workQty - issued);
//            }
//        });
        /**
         * 平库优先出库完成后,当订单明细workQty + qty 还不等于anfme时,查询TCU库
@@ -517,11 +516,10 @@
            mergePreviewDtos.add(dto);
        }
        return mergePreviewDtos;
    }
    @Transactional
    @Transactional(rollbackFor = Exception.class)
    public List<MergePreviewResultDto> orderOutMergeLocPreview(List<MergePreviewDto> param) {
        if (param == null) {
            throw new CoolException("参数不能为空");
@@ -544,6 +542,11 @@
        param.forEach(pars -> {
            List<MergePreviewResultLocDto> locDtos = new ArrayList<>();
            MergePreviewResultDto resultDto = new MergePreviewResultDto();
            resultDto.sync(pars);
            resultDto.setOrderIds(pars.getOrderIds());
            resultDto.setLocs(locDtos);
            List<LocDetl> locs = locDetlService.queryFlatStock(pars.getMatnr(), pars.getBatch(), pars.getFieldParams());
            if (!locs.isEmpty()) {
                double anfme = pars.getAnfme() - pars.getWorkQty();
@@ -559,29 +562,45 @@
                    MergePreviewResultLocDto locDto = new MergePreviewResultLocDto();
                    locDto.setLocId(detl.getLocId());
                    locDto.setLocNo(detl.getLocNo());
                    locDto.setTypeId(LocAreaTypeSts.LOC_AREA_TYPE_FLAT.id);
                    locDto.setLocDetlId(detl.getId());
                    locDtos.add(locDto);
                    //库位实际可用数量
                    double surplusQty = detl.getAnfme() - detl.getWorkQty();
                    //波次数量减去库位可用数量后,盈余数量
//                    double workQty = anfme - surplusQty;
                    anfme = anfme - surplusQty;
                    if (anfme > 0) {
                        locDto.setAnfme(detl.getAnfme());
                        locDto.setWorkQty(surplusQty);
                    } else {
                        locDto.setAnfme(anfme);
                        locDto.setWorkQty(anfme);
                        locDto.setAnfme(pars.getAnfme() - pars.getWorkQty());
                        locDto.setWorkQty(pars.getAnfme() - pars.getWorkQty());
                        break;
                    }
                }
                //保存出库数量(平库)
                pars.setWorkQty(pars.getAnfme() - pars.getWorkQty() - anfme);
                resultDto.setOtherLocs(new ArrayList<>());
                resultDto.setAnfme(pars.getAnfme());
                resultDtos.add(resultDto);
            } else {
                resultDto.sync(pars);
                resultDto.setLocs(new ArrayList<>());
                resultDto.setOrderIds(pars.getOrderIds());
                resultDto.setAnfme(pars.getAnfme());
                resultDtos.add(resultDto);
            }
        });
        for (MergePreviewDto dto : param) {
            Double anfme = dto.getAnfme() - dto.getWorkQty();
            //减去平库数量后,小于等于0,跳出处理
            if (anfme <= 0) {continue;}
            List<LocDetl> locDetls = locDetlService.queryStock(dto.getMatnr(), dto.getBatch(), dto.getFieldParams(), sortParams);
            if(locDetls.isEmpty()){
                MergePreviewResultDto resultDto = new MergePreviewResultDto();
@@ -598,7 +617,7 @@
            MergePreviewResultDto resultDto = new MergePreviewResultDto();
            resultDto.sync(dto);
            resultDto.setOrderIds(dto.getOrderIds());
            Double anfme = dto.getAnfme();
//            Double anfme = dto.getAnfme();
            resultDto.setLocs(locDtos);
            for (LocDetl locDetl : locDetls) {
                Loc loc = locService.getById(locDetl.getLocId());
@@ -652,17 +671,6 @@
        return resultDtos;
    }
    /**
     * 波次生成出库任务
     * UTC出库任务逻辑不变,添加平库判别逻辑
     * 1. 获取波次订单明细,判别是否为平库订单
     * 2. 平库订单生成拣货单, UTC订单生成出库任务
     * 3. 平库单据明细所占库位物料数量加锁
     * 4. 生成出库单PDA端,统一出库扣减库存
     * 5. 生成拣货单历史档,出库单据加入历史档,删除原单据
     * 6. 删除波次列表数据
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    public void orderOutMerge(OrderOutMergeParamDto dto) {
        if(dto == null){
@@ -865,6 +873,18 @@
    }
    /**
     * 波次生成出库任务
     * UTC出库任务逻辑不变,添加平库判别逻辑
     * 1. 获取波次订单明细,判别是否为平库订单
     * 2. 平库订单生成拣货单, UTC订单生成出库任务
     * 3. 平库单据明细所占库位物料数量加锁
     * 4. 生成出库单PDA端,统一出库扣减库存
     * 5. 生成拣货单历史档,出库单据加入历史档,删除原单据
     * 6. 删除波次列表数据
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    public void orderOutMergeWave(OrderOutMergeParamDto dto) {
        if(dto == null){
@@ -880,24 +900,26 @@
            throw new CoolException("波次不存在");
        }
        List<OrderOutMergeParam> params = dto.getList();
        /**
         * 波次合并出库
         * 1. 判断是平库还TCU库
         * 2. 根据单库单据类型
         * 2. 平库生成拣货单
         * 3. TCU库生成任务单
         */
        outStockByArea(dto, wave);
        if (params.isEmpty()) {
            throw new CoolException("参数不能为空");
        //波次状态修改为--生成任务
        wave.setWaveStatus(WaveStatusType.GENERATE.id);
        wave.setUpdateTime(new Date());
        if (!waveService.updateById(wave)) {
            throw new CoolException("波次更新失败");
        }
        }
        List<Long> filterParamsList = new ArrayList<>();
        List<OrderOutMergeParam> filterParams = new ArrayList<>();
        params.forEach(action -> {
            if (action.getLocId() != null) {
                filterParamsList.add(action.getLocId());
                filterParams.add(action);
            }
        });
    private Map<Long, List<OrderOutMergeDto>> checkLoc(List<OrderOutMergeParam>  mergeParams, Wave wave) {
        HashMap<String, Double> stockMap = new HashMap<>();
        for (OrderOutMergeParam param : filterParams) {
        for (OrderOutMergeParam param : mergeParams) {
            String matUniqueKey = Utils.getMatUniqueKey(param.getMatnr(), param.getBatch(), param.getFieldParams());
            WaveDetl waveDetl = waveDetlService.getOne(new LambdaQueryWrapper<WaveDetl>().eq(WaveDetl::getStockIndex, matUniqueKey).eq(WaveDetl::getWaveId, wave.getId()));
            if(waveDetl == null){
@@ -911,7 +933,7 @@
        }
        HashMap<Long, List<OrderOutMergeDto>> map = new HashMap<>();
        for (OrderOutMergeParam param : filterParams) {
        for (OrderOutMergeParam param : mergeParams) {
            LocDetl locDetl = locDetlService.getById(param.getLocDetlId());
            if(locDetl == null) {
                continue;
@@ -947,6 +969,57 @@
        if (map.isEmpty()) {
            throw new CoolException("库存不足");
        }
        return map;
    }
    /**
     * 根据不同库位类型生成出库拣单及TUC任务档
     * @param dto
     * @param wave
     */
    private void outStockByArea(OrderOutMergeParamDto dto, Wave wave) {
        List<OrderOutMergeParam> params = dto.getList();
        if (params.isEmpty()) {
            throw new CoolException("参数不能为空");
        }
        //平库数据源
        List<OrderOutMergeParam> flatOrders = new ArrayList<>();// listMap.get(LocAreaTypeSts.LOC_AREA_TYPE_FLAT);
        //TUC数据源
        List<OrderOutMergeParam> tucOrders = new ArrayList<>();//listMap.get(LocAreaTypeSts.LOC_AREA_TYPE_UTC);
        //按库位类型分类
        Map<Long, List<OrderOutMergeParam>> listMap = params.stream().collect(Collectors.groupingBy(OrderOutMergeParam::getTypeId));
        //数据分类 1.平库数据  2. TUC数据
        listMap.keySet().forEach(key -> {
            if (key == LocAreaTypeSts.LOC_AREA_TYPE_FLAT.id) {
                flatOrders.addAll(listMap.get(key));
            } else {
                tucOrders.addAll(listMap.get(key));
            }
        });
        if (flatOrders.isEmpty()) {
            //平库出库
            outStockByFlat(flatOrders, wave);
        }
        if (tucOrders.isEmpty()) {
            //TUC出库
            outStockByTUC(tucOrders, wave);
        }
    }
    /**
     * TUC出库--生成出库任务档
     *
     * @param tucOrders
     * @param wave
     */
    private void outStockByTUC(List<OrderOutMergeParam> tucOrders, Wave wave) {
        Map<Long, List<OrderOutMergeDto>>  map = checkLoc(tucOrders, wave);
        for (Map.Entry<Long, List<OrderOutMergeDto>> entry : map.entrySet()) {
            Long locId = entry.getKey();
@@ -1017,11 +1090,8 @@
                    }
                }
                //TODO 确认后,需将注释打开
                String matUniqueKey = Utils.getMatUniqueKey(taskDetl.getMatnr(), taskDetl.getBatch(), taskDetl.getUniqueField());
                WaveDetl waveDetl = waveDetlService.getOne(new LambdaQueryWrapper<WaveDetl>().eq(WaveDetl::getStockIndex, matUniqueKey).eq(WaveDetl::getWaveId, wave.getId()));
//                WaveDetl waveDetl = waveDetlService.getOne(new LambdaQueryWrapper<WaveDetl>().eq(WaveDetl::getWaveId, wave.getId()), false);
                if (waveDetl == null) {
                    throw new CoolException("波次数据不存在");
                }
@@ -1032,7 +1102,6 @@
                }
            }
            //库位F => R
            loc.setLocStsId(LocStsType.R.val());
            loc.setUpdateTime(new Date());
@@ -1041,19 +1110,21 @@
                throw new CoolException("库位状态更新失败");
            }
        }
//        Wave wave = waveService.getById(dto.getWaveId());
//        if (wave == null) {
//            throw new CoolException("波次不存在");
//        }
        wave.setWaveStatus(WaveStatusType.GENERATE.id);
        wave.setUpdateTime(new Date());
        if (!waveService.updateById(wave)) {
            throw new CoolException("波次更新失败");
        }
    /**
     * 平库出库--生成出库拣货单
     *
     * @param flatOrders
     * @param wave
     */
    private void outStockByFlat(List<OrderOutMergeParam> flatOrders, Wave wave) {
        Map<Long, List<OrderOutMergeDto>> map = checkLoc(flatOrders, wave);
    }
    @Transactional(rollbackFor = Exception.class)
    public void generateWave(GenerateWaveParam param) {
        if (param == null) {
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LocDetlServiceImpl.java
@@ -233,9 +233,8 @@
        List<Map<String, Object>> list = viewLocDetlMapper.queryFlatStock(matnr, batch, params);
        List<LocDetl> detls = new ArrayList<>();
        list.forEach(action -> {
            LocDetl locDetl = new LocDetl();
            BeanUtils.copyProperties(action, locDetl);
            detls.add(locDetl);
            LocDetl parseObject = JSONObject.parseObject(JSON.toJSONString(action), LocDetl.class);
            detls.add(parseObject);
        });
        return detls;
    }
zy-asrs-wms/src/main/resources/application.yml
@@ -13,8 +13,8 @@
      validation-timeout: 3000
      connection-test-query: select 1
    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://127.0.0.1:3306/wms_dev_test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    url: jdbc:mysql://127.0.0.1:3306/wms_dev?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    url: jdbc:mysql://127.0.0.1:3306/wms_dev_test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
#    url: jdbc:mysql://127.0.0.1:3306/wms_dev?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    username: root
    password: 34821015
#    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
zy-asrs-wms/src/main/resources/mapper/asrs/ViewLocDetlMapper.xml
@@ -78,7 +78,7 @@
    <select id="queryFlatStock" resultType="map">
        SELECT * FROM
        (
            SELECT id, loc_id, loc_no, mat_id, type_id, matnr, order_no, batch, anfme, host_id, memo, freeze
            SELECT id, loc_id, loc_no, mat_id, type_id, work_qty, matnr, order_no, batch, anfme, host_id, memo, freeze
            FROM
            view_man_loc_detl
            WHERE
@@ -87,15 +87,15 @@
        ) t
        WHERE 1 = 1
        <if test="matnr != null and matnr != ''">
            AND t.matnr  #{matnr}
            AND t.matnr = #{matnr}
        </if>
        <if test="batch != null and batch != ''">
            AND t.batch = #{batch}
        </if>
        <if test="params != null and params.size() > 0">
            <foreach collection="params" item="item" open="order by " separator="," close="  ">
                ${item.name} = #{item.value}
            </foreach>
        </if>
<!--        <if test="params != null and params.size() > 0">-->
<!--            <foreach collection="params" item="item" open="in " separator="," close="  ">-->
<!--                ${item.name} #{item.value}-->
<!--            </foreach>-->
<!--        </if>-->
    </select>
</mapper>