skyouc
2025-01-08 d1511d2d12b4223882fcfdabd3ba6b59c038edc4
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/manage/OutManage.java
@@ -1,6 +1,7 @@
package com.zy.asrs.wms.asrs.manage;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.asrs.framework.exception.CoolException;
import com.zy.asrs.wms.asrs.entity.dto.*;
@@ -14,10 +15,13 @@
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;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@@ -63,6 +67,12 @@
    private CacheSiteService cacheSiteService;
    @Autowired
    private WaveSeedService waveSeedService;
    @Autowired
    private PickSheetService pickSheetService;
    @Autowired
    private PickSheetDetlService pickSheetDetlService;
    @Autowired
    private MatService matService;
    /**
     * 出库
@@ -195,7 +205,9 @@
        //获取TCU符合条件库位
        for (OrderDetl orderDetl : orderDetls) {
            double issued = Optional.of(orderDetl.getAnfme() - orderDetl.getQty() - orderDetl.getWorkQty()).orElse(0.0D);
            if (issued <= 0.0D) { continue; }
            if (issued <= 0.0D) {
                continue;
            }
            List<LocDetl> locDetls = locDetlService.queryStock(orderDetl.getMat$().getMatnr(), orderDetl.getBatch(), orderDetl.getUniqueField());
            orderDetlLocMap.put(orderDetl.getId(), locDetls);
            for (LocDetl locDetl : locDetls) {
@@ -600,7 +612,9 @@
        for (MergePreviewDto dto : param) {
            Double anfme = dto.getAnfme() - dto.getWorkQty();
            //减去平库数量后,小于等于0,跳出处理
            if (anfme <= 0) {continue;}
            if (anfme <= 0) {
                continue;
            }
            List<LocDetl> locDetls = locDetlService.queryStock(dto.getMatnr(), dto.getBatch(), dto.getFieldParams(), sortParams);
            if(locDetls.isEmpty()){
                MergePreviewResultDto resultDto = new MergePreviewResultDto();
@@ -883,6 +897,7 @@
     * 4. 生成出库单PDA端,统一出库扣减库存
     * 5. 生成拣货单历史档,出库单据加入历史档,删除原单据
     * 6. 删除波次列表数据
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
@@ -903,7 +918,6 @@
        /**
         * 波次合并出库
         * 1. 判断是平库还TCU库
         * 2. 根据单库单据类型
         * 2. 平库生成拣货单
         * 3. TCU库生成任务单
         */
@@ -917,6 +931,14 @@
        }
    }
    /**
     * 1. 判断当波次及库位明细是否存在
     * 2. 组合key-value(list)形式数据
     *
     * @param mergeParams
     * @param wave
     * @return
     */
    private Map<Long, List<OrderOutMergeDto>> checkLoc(List<OrderOutMergeParam>  mergeParams, Wave wave) {
        HashMap<String, Double> stockMap = new HashMap<>();
        for (OrderOutMergeParam param : mergeParams) {
@@ -925,7 +947,7 @@
            if(waveDetl == null){
                throw new CoolException("波次数据不存在");
            }
            //获取当前需要执行数量
            double issued = Optional.of(waveDetl.getAnfme() - waveDetl.getWorkQty()).orElse(0.0D);
            if(!stockMap.containsKey(matUniqueKey)){
                stockMap.put(matUniqueKey, issued);
@@ -938,14 +960,14 @@
            if(locDetl == null) {
                continue;
            }
            if (locDetl.getAnfme() - param.getAnfme() < 0) {
            //库位数量小于出库数量 //新增workQty用于平库锁库存
            if (locDetl.getAnfme() - locDetl.getWorkQty() - param.getAnfme() < 0) {
                continue;
            }
            OrderOutMergeDto orderOutMergeDto = new OrderOutMergeDto();
            orderOutMergeDto.sync(param);
            //fixme 确认stockMap是否有用,此处入值后却没有使用
            String matUniqueKey = Utils.getMatUniqueKey(param.getMatnr(), param.getBatch(), param.getFieldParams());
            Double issued = stockMap.get(matUniqueKey);
            if (issued - orderOutMergeDto.getAnfme() < 0) {
@@ -954,14 +976,16 @@
            }else {
                issued -= orderOutMergeDto.getAnfme();
            }
            stockMap.put(matUniqueKey, issued);
            stockMap.put(matUniqueKey, issued);
            //根据库位做分类,可使用stream().groupby
            List<OrderOutMergeDto> list = null;
            if (map.containsKey(orderOutMergeDto.getLocId())) {
                list = map.get(orderOutMergeDto.getLocId());
            }else {
                list = new ArrayList<>();
            }
            list.add(orderOutMergeDto);
            map.put(orderOutMergeDto.getLocId(), list);
        }
@@ -975,6 +999,7 @@
    /**
     * 根据不同库位类型生成出库拣单及TUC任务档
     *
     * @param dto
     * @param wave
     */
@@ -999,12 +1024,12 @@
                tucOrders.addAll(listMap.get(key));
            }
        });
        if (flatOrders.isEmpty()) {
        if (!flatOrders.isEmpty()) {
            //平库出库
            outStockByFlat(flatOrders, wave);
        }
        if (tucOrders.isEmpty()) {
        if (!tucOrders.isEmpty()) {
            //TUC出库
            outStockByTUC(tucOrders, wave);
        }
@@ -1018,12 +1043,15 @@
     * @param tucOrders
     * @param wave
     */
    private void outStockByTUC(List<OrderOutMergeParam> tucOrders, Wave wave) {
    private void outStockByTUC(List<OrderOutMergeParam> tucOrders, Wave wave) {//123
        Map<Long, List<OrderOutMergeDto>>  map = checkLoc(tucOrders, wave);
        if (!Objects.isNull(map)) {
            return;
        }
        for (Map.Entry<Long, List<OrderOutMergeDto>> entry : map.entrySet()) {
            Long locId = entry.getKey();
            List<OrderOutMergeDto> list = entry.getValue();
            //判断是否全仓出库
            Boolean all = outUtils.isAllForMerge(locId, list);
            OrderOutMergeDto param = list.get(0);
            Long operationPortId = param.getOperationPort();
@@ -1041,7 +1069,7 @@
            if (operationPort == null) {
                throw new CoolException("作业口不存在");
            }
            //101 全拖出库   103 拣货出库
            long taskType = all ? 101L : 103L;
            Task task = new Task();
@@ -1114,18 +1142,80 @@
    /**
     * 平库出库--生成出库拣货单
     * 1. 判断当前库位是否存在
     * 2. 一张单据一个波次
     * 3. 一个波次多条订单
     * 4. 一个库位可多条明细
     * 5. 拣货单完成后,释放库位明细锁定数量
     *
     * @param flatOrders
     * @param wave
     */
    private void outStockByFlat(List<OrderOutMergeParam> flatOrders, Wave wave) {
        //校验库存数量
        Map<Long, List<OrderOutMergeDto>> map = checkLoc(flatOrders, wave);
        //生成拣货单
        PickSheet pickSheet = new PickSheet();
        //波次数量汇总
        double sum = flatOrders.stream().mapToDouble(OrderOutMergeParam::getAnfme).sum();
        //生成拣货单号
        String pickNo = generatePickNO();
        pickSheet.setId(null)
                .setPickNo(pickNo)
                .setMemo(wave.getMemo())
                .setAnfme(sum)
                .setWaveId(wave.getId())
                .setWaveNo(wave.getWaveNo());
        if (!pickSheetService.save(pickSheet)) {
            throw new CoolException("拣货单写入失败!!");
        }
        //根据库位ID分组
        Map<Long, List<OrderOutMergeParam>> listMap = flatOrders.stream().collect(Collectors.groupingBy(OrderOutMergeParam::getLocId));
        //生成拣货明细
        listMap.keySet().forEach(key -> {
            Loc curLoc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getId, key));
            if (Objects.isNull(curLoc)) {
                throw new CoolException("主键." + key + "的库位不存在!!");
            }
            listMap.get(key).forEach(outOder -> {
                //获取库位明细信息
                LocDetl locDetl = locDetlService.getOne(new LambdaQueryWrapper<LocDetl>().eq(LocDetl::getId, outOder.getLocDetlId()));
                PickSheetDetl sheetDetl = new PickSheetDetl();
                BeanUtils.copyProperties(outOder, sheetDetl);
                //获取物料信息
                Mat mat = matService.getOne(new LambdaQueryWrapper<Mat>().eq(Mat::getMatnr, outOder.getMatnr()));
                //拣货单明细
                sheetDetl.setBarcode(curLoc.getBarcode())
                        .setPickId(pickSheet.getId())
                        .setAnfme(BigDecimal.valueOf(outOder.getAnfme()))
                        .setLocDetlId(locDetl.getId())
                        .setMaktx(mat.getMaktx())
                        .setMatId(mat.getId());
                if (!pickSheetDetlService.save(sheetDetl)) {
                    throw new CoolException("拣货明细列新失败");
                }
                //锁定库存量
                locDetl.setWorkQty(locDetl.getWorkQty() + outOder.getAnfme());
            });
        });
    }
    /**
     * 生成拣货单号
     *
     * @return
     */
    private String generatePickNO() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = simpleDateFormat.format(new Date());
        Random random = new Random();
        return "PN" + format + random.nextInt(10000);
    }
    @Transactional(rollbackFor = Exception.class)
    public void generateWave(GenerateWaveParam param) {