自动化立体仓库 - WMS系统
#
lsh
2025-04-08 abc40d18cdfde0826bd7ae1377e9973cff3eefb8
src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -13,12 +13,14 @@
import com.zy.asrs.entity.param.LocDetlAdjustParam;
import com.zy.asrs.entity.param.StockOutParam;
import com.zy.asrs.service.*;
import com.zy.asrs.utils.OutboundAllocationUtil;
import com.zy.asrs.utils.Utils;
import com.zy.common.model.*;
import com.zy.common.model.enums.IoWorkType;
import com.zy.common.model.enums.WorkNoType;
import com.zy.common.properties.SlaveProperties;
import com.zy.common.service.CommonService;
import com.zy.common.utils.YyyyMmddUtils;
import com.zy.common.web.WcsController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -45,6 +47,8 @@
    private MatService matService;
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private DocTypeService docTypeService;
    @Autowired
    private WrkDetlService wrkDetlService;
    @Autowired
@@ -77,6 +81,10 @@
    private SlaveProperties slaveProperties;
    @Autowired
    private WaitPakinService waitPakinService;
    @Autowired
    private OrderGiftService orderGiftService;
    @Autowired
    private OrderDetlGiftService orderDetlGiftService;
    @Override
    @Transactional
@@ -90,8 +98,8 @@
        BasDevp sourceStaNo = basDevpService.checkSiteStatus(param.getDevpNo(), true);
        // 检索库位
        LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo);
        List<String> matnrs = param.getList().stream().map(FullStoreParam.MatCodeStore::getMatnr).distinct().collect(Collectors.toList());
        StartupDto dto = commonService.getLocNo(DEFAULT_ROW_NO_TYPE, 1, param.getDevpNo(), matnrs, locTypeDto, 0);
//        List<String> matnrs = param.getList().stream().map(FullStoreParam.MatCodeStore::getMatnr).distinct().collect(Collectors.toList());
        StartupDto dto = commonService.getLocNo(DEFAULT_ROW_NO_TYPE, 1, param.getDevpNo(), param.getList().get(0).getMatnr(),null,null, locTypeDto);
        // 生成工作号
        int workNo = dto.getWorkNo();
        // 生成工作档
@@ -158,27 +166,238 @@
    @Transactional
    public void startupFullTakeStore(StockOutParam param, Long userId) {
        // 目标站点状态检测
        Date now = param.getNowTime();
        BasDevp staNo = basDevpService.checkSiteStatus(param.getOutSite());
        // 获取库位明细
        List<LocDetlDto> locDetlDtos = new ArrayList<>();
        for (StockOutParam.LocDetl paramLocDetl : param.getLocDetls()) {
            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()));
                one.setMemo(paramLocDetl.getMemo());
                one.setColor(paramLocDetl.getColor());
                if (null != one) locDetlDtos.add(new LocDetlDto(one, paramLocDetl.getCount(), param.getOrderNo()));
            }
        }
        if (!locDetlDtos.isEmpty()) {
            // 启动出库开始 101.出库
            stockOut(staNo, locDetlDtos, null, userId);
            LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", locDetlDtos.get(0).getLocDetl().getLocNo()));
            if (locMast.getLocSts().equals("F") || locMast.getLocSts().equals("D") ){
                // 启动出库开始 101.出库
                staNo.setModiTime(now);
                stockOut(staNo, locDetlDtos, null, userId);
            }else {
                throw new CoolException("所选库位存在状态不为F、D的库位,库位号:"+locMast.getLocNo()+" 、当前状态:"+locMast.getLocSts()+"-"+locMast.getLocSts$());
            }
        } else {
            throw new CoolException("库存不存在");
        }
    }
    @Override
    @Transactional
    public void startupFullTakeStoreOrder(StockOutParam param, Long userId) {
        if (Cools.isEmpty(param) || Cools.isEmpty(param.getLocDetls())){
            throw new CoolException("参数为空");
        }
        if (Cools.isEmpty(param.getOrderNo())){
            throw new CoolException("订单号参数为空");
        }
        DocType docType = docTypeService.selectOrAdd("手动出库单", Boolean.FALSE);
        Order order = orderService.selectByNo(param.getOrderNo());
        if (Cools.isEmpty(order)){
            Date now = new Date();
            order = new Order(
                    String.valueOf(snowflakeIdWorker.nextId()),    // 编号[非空]
                    param.getOrderNo(),    // 订单编号
                    DateUtils.convert(now),    // 单据日期
                    docType.getDocId(),    // 单据类型
                    null,    // 项目编号
                    null,    //
                    null,    // 调拨项目编号
                    null,    // 初始票据号
                    null,    // 票据号
                    null,    // 客户编号
                    param.getCstmrName(),    // 客户
                    null,    // 联系方式
                    null,    // 操作人员
                    null,    // 合计金额
                    null,    // 优惠率
                    null,    // 优惠金额
                    null,    // 销售或采购费用合计
                    null,    // 实付金额
                    null,    // 付款类型
                    null,    // 业务员
                    null,    // 结算天数
                    null,    // 邮费支付类型
                    null,    // 邮费
                    null,    // 付款时间
                    null,    // 发货时间
                    null,    // 物流名称
                    null,    // 物流单号
//                    2L,    // 订单状态
                    1L,    // 订单状态
                    1,    // 状态
                    userId,    // 添加人员
                    now,    // 添加时间
                    userId,    // 修改人员
                    now,    // 修改时间
                    null    // 备注
            );
            if (!orderService.insert(order)) {
                throw new CoolException("保存订单主档失败");
            }
            // 单据明细档
            List<DetlDto> list = new ArrayList<>();
            List<StockOutParam.LocDetl> locDetls = param.getLocDetls();
            int i=0;
            for (StockOutParam.LocDetl locDetl : locDetls) {
                i++;
                Mat mat = matService.selectByMatnr(locDetl.getMatnr());
                if (Cools.isEmpty(mat)) {
                    throw new CoolException(locDetl.getMatnr() + "物料编码检索失败,请先添加商品");
                }
                OrderDetl orderDetl = new OrderDetl();
                orderDetl.sync(mat);
                orderDetl.setSuppCode(String.valueOf(i));  // 行号
                orderDetl.setManu(locDetl.getLocNo());  //库位号
                orderDetl.setBatch(locDetl.getBatch()); //木箱编码
                orderDetl.setAnfme(locDetl.getAnfme());//出库数量
                orderDetl.setModel(locDetl.getModel());//批次
                orderDetl.setSpecs(locDetl.getSpecs());//规格
                orderDetl.setBrand(locDetl.getBrand());//木箱类型
                orderDetl.setBarcode(locDetl.getZpallet());//木箱类型
                orderDetl.setWeight(locDetl.getWeight());
//                orderDetl.setWorkQty(locDetl.getAnfme());
                orderDetl.setWorkQty(0.0);
                orderDetl.setOrderId(order.getId());
                orderDetl.setOrderNo(order.getOrderNo());
                orderDetl.setOrigin(locDetl.getOrigin());
                orderDetl.setCreateBy(userId);
                orderDetl.setCreateTime(now);
                orderDetl.setUpdateBy(userId);
                orderDetl.setUpdateTime(now);
                orderDetl.setStatus(1);
                orderDetl.setQty(0.0D);
                orderDetl.setMemo(locDetl.getMemo());
                if (!orderDetlService.insert(orderDetl)) {
                    throw new CoolException("生成单据明细失败,请联系管理员");
                }
            }
//            List<StockOutParam> stockOutParams = OutboundAllocationUtil.OutboundClassification(param);
//            for (StockOutParam stockOutParam : stockOutParams){
//                startupFullTakeStore(stockOutParam,userId);
//            }
        } else {
            throw new CoolException("订单号重复,订单"+param.getOrderNo()+"已存在!!!");
        }
    }
    @Override
    @Transactional
    public void startupFullTakeStoreOrderGift(StockOutParam param, Long userId) {
        if (Cools.isEmpty(param) || Cools.isEmpty(param.getLocDetls())){
            throw new CoolException("参数为空");
        }
        if (Cools.isEmpty(param.getOrderNo())){
            throw new CoolException("订单号参数为空");
        }
        DocType docType = docTypeService.selectOrAdd("手动出库单", Boolean.FALSE);
        OrderGift order = orderGiftService.selectByNo(param.getOrderNo());
        if (Cools.isEmpty(order)){
            Date now = new Date();
            order = new OrderGift(
                    String.valueOf(snowflakeIdWorker.nextId()),    // 编号[非空]
                    param.getOrderNo(),    // 订单编号
                    DateUtils.convert(now),    // 单据日期
                    docType.getDocId(),    // 单据类型
                    null,    // 项目编号
                    null,    //
                    null,    // 调拨项目编号
                    null,    // 初始票据号
                    null,    // 票据号
                    null,    // 客户编号
                    null,    // 客户
                    null,    // 联系方式
                    null,    // 操作人员
                    null,    // 合计金额
                    null,    // 优惠率
                    null,    // 优惠金额
                    null,    // 销售或采购费用合计
                    null,    // 实付金额
                    null,    // 付款类型
                    null,    // 业务员
                    null,    // 结算天数
                    null,    // 邮费支付类型
                    null,    // 邮费
                    null,    // 付款时间
                    null,    // 发货时间
                    null,    // 物流名称
                    null,    // 物流单号
//                    2L,    // 订单状态
                    1L,    // 订单状态
                    1,    // 状态
                    userId,    // 添加人员
                    now,    // 添加时间
                    userId,    // 修改人员
                    now,    // 修改时间
                    null    // 备注
            );
            if (!orderGiftService.insert(order)) {
                throw new CoolException("保存订单主档失败");
            }
            // 单据明细档
            List<DetlDto> list = new ArrayList<>();
            List<StockOutParam.LocDetl> locDetls = param.getLocDetls();
            int i=0;
            for (StockOutParam.LocDetl locDetl : locDetls) {
                i++;
                Mat mat = matService.selectByMatnr(locDetl.getMatnr());
                if (Cools.isEmpty(mat)) {
                    throw new CoolException(locDetl.getMatnr() + "物料编码检索失败,请先添加商品");
                }
                OrderDetlGift orderDetl = new OrderDetlGift();
                orderDetl.sync(mat);
                orderDetl.setSuppCode(String.valueOf(i));  // 行号
                orderDetl.setManu(locDetl.getLocNo());  //库位号
                orderDetl.setBatch(locDetl.getBatch()); //木箱编码
                orderDetl.setAnfme(locDetl.getAnfme());//出库数量
                orderDetl.setModel(locDetl.getModel());//批次
                orderDetl.setSpecs(locDetl.getSpecs());//规格
                orderDetl.setBrand(locDetl.getBrand());//木箱类型
                orderDetl.setBarcode(locDetl.getZpallet());//木箱类型
                orderDetl.setWeight(locDetl.getWeight());
                orderDetl.setVolume(locDetl.getVolume());
                orderDetl.setPrice(locDetl.getPrice());
//                orderDetl.setWorkQty(locDetl.getAnfme());
                orderDetl.setWorkQty(0.0);
                orderDetl.setOrderId(order.getId());
                orderDetl.setOrderNo(order.getOrderNo());
                orderDetl.setOrigin(locDetl.getOrigin());
                orderDetl.setCreateBy(userId);
                orderDetl.setCreateTime(now);
                orderDetl.setUpdateBy(userId);
                orderDetl.setUpdateTime(now);
                orderDetl.setStatus(1);
                orderDetl.setQty(0.0D);
                orderDetl.setMemo(locDetl.getMemo());
                if (!orderDetlGiftService.insert(orderDetl)) {
                    throw new CoolException("生成单据明细失败,请联系管理员");
                }
            }
        } else {
            throw new CoolException("订单号重复,订单"+param.getOrderNo()+"已存在!!!");
        }
    }
    @Override
    @Transactional
    public void stockOut(BasDevp staNo, List<LocDetlDto> locDetlDtos, IoWorkType ioWorkType, Long userId) {
        Date now = new Date();
        Date nowPri = staNo.getModiTime();
        // 合并同类项
        Set<String> locNos = new HashSet<>();
        List<OutLocDto> dtos = new ArrayList<>();
@@ -210,10 +429,10 @@
            LocMast locMast = locMastService.selectById(dto.getLocNo());
            Integer outSta = staNo.getDevNo();
            //2号堆垛机全板出库站指定为204站,拣料站指定为202
            if(locMast.getCrnNo()==2){
                outSta = ioType == 101 ? 204 : 202;
            }
//            //2号堆垛机全板出库站指定为204站,拣料站指定为202
//            if(locMast.getCrnNo()==2){
//                outSta = ioType == 101 ? 204 : 202;
//            }
            // 获取路径
            StaDesc staDesc = staDescService.queryCrnStn(ioType, locMast.getCrnNo(), outSta);
@@ -224,8 +443,10 @@
            wrkMast.setWrkNo(workNo);
            wrkMast.setIoTime(now);
            wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID
            double pri = YyyyMmddUtils.convertPriD(nowPri);
            wrkMast.setIoType(ioType); // 入出库状态
            wrkMast.setIoPri(13D); // 优先级:13
            wrkMast.setIoPri(pri); // 优先级:13
            wrkMast.setCrnNo(locMast.getCrnNo());
            wrkMast.setSourceStaNo(staDesc.getCrnStn()); // 源站
            wrkMast.setStaNo(staDesc.getStnNo()); // 目标站
@@ -235,6 +456,10 @@
            wrkMast.setExitMk("N"); // 退出
            wrkMast.setEmptyMk("N"); // 空板
            wrkMast.setLinkMis("N");
            wrkMast.setSheetNo("0");
            if (staDesc.getStnNo()<118 || staDesc.getStnNo()>121){
                wrkMast.setSheetNo("3");
            }
            wrkMast.setBarcode(locMast.getBarcode());
            wrkMast.setAppeUser(userId); // 操作人员数据
            wrkMast.setAppeTime(now);
@@ -248,7 +473,7 @@
                if (detlDto.getCount()==null || detlDto.getCount() <= 0.0D) {continue;}
                WrkDetl wrkDetl = new WrkDetl();
                wrkDetl.sync(detlDto.getLocDetl());
                wrkDetl.setOrderNo(""); // 手动出库不需要带出库存中的单据编号
                wrkDetl.setOrderNo(detlDto.getOrderNo()); // 手动出库不需要带出库存中的单据编号
                wrkDetl.setWrkNo(workNo);
                wrkDetl.setIoTime(now);
                Double anfme = ioType==101?detlDto.getLocDetl().getAnfme():detlDto.getCount();
@@ -366,7 +591,7 @@
        BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true);
        // 检索库位
        LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo);
        StartupDto dto = commonService.getLocNo(DEFAULT_ROW_NO_TYPE, 10, devpNo, null, locTypeDto, 0);
        StartupDto dto = commonService.getLocNo(DEFAULT_ROW_NO_TYPE, 10, devpNo, null,null,null, locTypeDto);
        int workNo = dto.getWorkNo();
        Date now = new Date();
        // 生成工作档
@@ -431,6 +656,9 @@
            if (Cools.isEmpty(locMast)) {
                throw new CoolException(locNo+"库位不存在");
            }
            if (!locMast.getLocSts().equals("D")){
                throw new CoolException("所选库位存在状态不为D的库位,库位号:"+locMast.getLocNo()+" 、当前状态:"+locMast.getLocSts()+"-"+locMast.getLocSts$());
            }
            // 获取源站
            Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
                    .eq("type_no", 110)
@@ -448,7 +676,7 @@
            wrkMast.setIoTime(now);
            wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID
            wrkMast.setIoType(110); // 入出库状态: 110.空板出库
            wrkMast.setIoPri(10D);
            wrkMast.setIoPri(99999999D);
            wrkMast.setSourceStaNo(sourceStaNo); // 源站
            wrkMast.setStaNo(param.getOutSite()); // 目标站
            wrkMast.setCrnNo(locMast.getCrnNo());
@@ -510,7 +738,7 @@
            wrkMast.setIoTime(now);
            wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID
            wrkMast.setIoType(110); // 入出库状态: 110.空板出库
            wrkMast.setIoPri(10D);
            wrkMast.setIoPri(99999999D);
            wrkMast.setSourceStaNo(sourceStaNo); // 源站
            wrkMast.setStaNo(param.getOutSite()); // 目标站
            wrkMast.setCrnNo(locMast.getCrnNo());
@@ -552,12 +780,18 @@
        for (StockOutParam.LocDetl paramLocDetl : param.getLocDetls()) {
            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()));
                if (null != one) locDetlDtos.add(new LocDetlDto(one, paramLocDetl.getCount(),param.getOrderNo()));
            }
        }
        if (!locDetlDtos.isEmpty()) {
            // 启动出库开始 107.盘点出库
            stockOut(staNo, locDetlDtos, IoWorkType.CHECK_OUT, userId);
            LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", locDetlDtos.get(0).getLocDetl().getLocNo()));
            if (locMast.getLocSts().equals("F")){
                // 启动出库开始 107.盘点出库
                stockOut(staNo, locDetlDtos, IoWorkType.CHECK_OUT, userId);
            }else {
                throw new CoolException("所选库位存在状态不为F的库位,库位号:"+locMast.getLocNo()+" 、当前状态:"+locMast.getLocSts()+"-"+locMast.getLocSts$());
            }
        } else {
            throw new CoolException("库位物料不存在");
        }
@@ -574,6 +808,9 @@
        LocMast loc = locMastService.selectById(locNo);
        if (Cools.isEmpty(loc)){
            throw new CoolException("未找到库位");
        }
        if (!loc.getLocSts().equals("O") || (!sourceLoc.getLocSts().equals("F") && !sourceLoc.getLocSts().equals("D"))){
            throw new CoolException("库位状态已改变");
        }
        if (!sourceLoc.getCrnNo().equals(loc.getCrnNo())) {
            throw new CoolException("移转库位属于不同堆垛机");
@@ -658,14 +895,17 @@
        if (wrkMast.getWrkSts() < 4 || (wrkMast.getWrkSts() > 10 && wrkMast.getIoType()==11)) {
            wrkMast.setWrkSts(4L);
        // 出库
        } else if (wrkMast.getWrkSts() > 10) {
        } else if (wrkMast.getWrkSts() > 10 && wrkMast.getIoType()!=202) {
            wrkMast.setWrkSts(14L);
        }else if (wrkMast.getIoType()==202){
            wrkMast.setWrkSts(57L);
        }
        Date now = new Date();
        wrkMast.setCrnStrTime(DateUtils.calculate(now, 1L, TimeUnit.SECONDS, true));
        wrkMast.setCrnEndTime(now);
        wrkMast.setModiTime(now);
        wrkMast.setModiUser(userId);
        wrkMast.setSheetNo("3");
        // 完成操作人员记录
        wrkMast.setManuType("手动完成");
        if (!wrkMastService.updateById(wrkMast)) {
@@ -822,7 +1062,7 @@
                locMastService.updateById(locMast);
            }
        // 出库取消(修改源库位)
        } else if (wrkMast.getWrkSts() > 10 && wrkMast.getWrkSts() != 14) {
        } else if (wrkMast.getWrkSts() > 10 && wrkMast.getWrkSts() != 14 && wrkMast.getIoType()!=202) {
            locNo = wrkMast.getSourceLocNo();
            // 出库 ===>> F.在库
            if (wrkMast.getIoType() > 100 && wrkMast.getIoType() != 110) {
@@ -843,6 +1083,7 @@
                locMast.setModiUser(userId);
                locMastService.updateById(locMast);
            }
        } else if (wrkMast.getIoType()==202 || wrkMast.getIoType()==212){
        } else {
            throw new CoolException("当前工作状态无法取消");
        }
@@ -855,7 +1096,8 @@
                    waitPakin.setIoStatus("N");
                    waitPakin.setLocNo("");
                    waitPakinService.update(waitPakin, new EntityWrapper<WaitPakin>()
                            .eq("order_no", waitPakin.getOrderNo())
//                            .eq("order_no", waitPakin.getOrderNo())
                            .eq("zpallet",waitPakin.getZpallet())
                            .eq("matnr", waitPakin.getMatnr())
                            .eq("batch", waitPakin.getBatch()));
                }
@@ -928,6 +1170,9 @@
            }
            // 删除工作档明细
            boolean wrkDetlRes = wrkDetlService.delete(new EntityWrapper<WrkDetl>().eq("wrk_no", workNo));
        }
        if (wrkMast.getIoType()==202 || wrkMast.getIoType()==212){
            return;
        }
        // 修改库位状态
@@ -1106,4 +1351,31 @@
        return targetLoc.getLocNo();
    }
    @Override
    @Transactional
    public void turnMatLocDetl(EmptyPlateOutParam param, Long userId) {
        Mat mat = matService.selectOne(new EntityWrapper<Mat>().eq("id", param.getMatId()));
        if (Cools.isEmpty(mat)){
            throw new CoolException("目标库位商品编码有误!");
        }
        List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("matnr", param.getLocDetls().get(0).getMatnr()));
        if (Cools.isEmpty(locDetls) || locDetls.size()<1){
            throw new CoolException("待修改商品无库存,无需修改!  规格:"+param.getLocDetls().get(0).getMatnr());
        }
        try {
            locDetlService.updateMatTurn(param.getLocDetls().get(0).getMatnr(),mat.getMatnr());
        }catch (Exception e){
            throw new CoolException("对数据库修改出错!");
        }
        for (LocDetl locDetl:locDetls){
            // 保存调整记录
            AdjDetl adjDetl = new AdjDetl();
            adjDetl.setLocNo(locDetl.getLocNo());
            adjDetl.setMatnr(mat.getMatnr());
            adjDetl.setMatnrOld(param.getLocDetls().get(0).getMatnr());
            adjDetl.setAdjQty(locDetl.getAnfme());
            adjDetlService.save(adjDetl, userId);
        }
    }
}