package com.zy.asrs.service.impl; import com.alibaba.excel.util.DateUtils; import com.alibaba.excel.util.StringUtils; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.core.common.SnowflakeIdWorker; import com.core.exception.CoolException; import com.zy.asrs.entity.*; import com.zy.asrs.entity.mes.*; import com.zy.asrs.entity.param.CombParam; import com.zy.asrs.entity.param.EmptyPlateOutParam; import com.zy.asrs.entity.rcs.*; import com.zy.asrs.mapper.AgvInfoMapper; import com.zy.asrs.mapper.MatItemBarcodeMapper; import com.zy.asrs.service.*; import com.zy.asrs.utils.OrderInAndOutUtil; import com.zy.common.model.DetlDto; import com.zy.common.model.enums.WorkNoType; import com.zy.common.service.CommonService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.text.ParseException; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; import java.util.stream.Stream; @Slf4j @Service public class MesServiceImpl implements MesService { @Value("${mes.url}") public String MES_URL; @Value("${wms.currentName}") public String WMS_CURRENT_NAME; @Value("${wms.wmsTransStartStation1}") public String WMS_TRANS_START_STATION_1; @Value("${wms.wmsTransStartStation2}") public String WMS_TRANS_START_STATION_2; @Value("${wms.wmsTransStartStation3}") public String WMS_TRANS_START_STATION_3; @Value("${mes.defaultUserId}") public long defaultUserId; @Value("${wms.zpalletId}") public String WMS_ZPALLET_ID; @Resource private RcsService rcsService; @Resource private MatService matService; @Resource private TagService tagService; @Resource private OrderPakinService orderPakinService; @Resource private OrderDetlPakinService orderDetlPakinService; @Resource private OrderPakoutService orderPakoutService; @Resource private OrderDetlPakoutService orderDetlPakoutService; @Resource private WaitPakinService waitPakinService; @Resource private TaskService taskService; @Resource private TaskDetlService taskDetlService; @Resource private SnowflakeIdWorker snowflakeIdWorker; @Resource private CommonService commonService; @Resource private AgvInfoMapper agvInfoMapper; @Resource private WorkService workService; @Resource private MatItemBarcodeMapper matItemBarcodeMapper; @Resource private LocMastService locMastService; @Resource private LocDetlService locDetlService; @Resource private MobileService mobileService; // region MES接口 /** * 物料信息同步,MES->WMS * 功能:同步物料信息->生成入库单 * 后续流程:入库时,需要实时调用recvFeedback返回入库数量 * * @param matRecvForm * @return */ @Transactional(rollbackFor = Exception.class) public MesReturn matInfoAndInBound(MesMatRecvForm matRecvForm) throws CoolException { MesReturn mesReturn = new MesReturn(); // 1、物料信息同步 int matSuccess = 0; for (MesMatInfo mesMatInfo : matRecvForm.getItemdata()) { if (synMatInfo(mesMatInfo) == 1) { matSuccess++; } else { throw new CoolException("同步物料信息失败"); } } // 2、生成入库单 if (inBoundOrder_List(matRecvForm) == 1) { mesReturn.setSuccess("1"); mesReturn.setMessage(""); } else { throw new CoolException("同步物料信息,生成入库单失败"); } return mesReturn; } /** * 新增、修改物料信息 * * @param mesMatInfo * @return 1 成功;-1 保存物料类型失败;-2 保存物料失败; * @throws ParseException */ public int synMatInfo(MesMatInfo mesMatInfo) { // 规则定义:默认第2层为库名(如:加工库),第3层为同步的物料类型 long secondPath = 2; String secondParentName = WMS_CURRENT_NAME; Date now = new Date(); // 物料类型更新 long tagId = 0; EntityWrapper wrapper = new EntityWrapper<>(); wrapper.eq("name", mesMatInfo.getItemType()); Tag tag = tagService.selectByName(mesMatInfo.getItemType(), 3); if (tag == null || StringUtils.isEmpty(tag.getName())) { Tag newTag = new Tag(); newTag.setName(mesMatInfo.getItemType()); newTag.setParentId(secondPath); newTag.setParentName(secondParentName); newTag.setPath("2"); newTag.setPathName(secondParentName); newTag.setLevel(3); newTag.setStatus(1); newTag.setCreateBy(defaultUserId); newTag.setCreateTime(now); newTag.setUpdateBy(defaultUserId); newTag.setUpdateTime(now); if (!tagService.insert(newTag)) return -1; tagId = newTag.getId(); } else { tagId = tag.getId(); } // 物料更新 if (tagId > 0) { // tagId = tagService.selectByName(mesMatInfo.getItem_type(), 3).getId(); Mat mat = matService.selectByMatnr(mesMatInfo.getItemNo()); Mat newMat = new Mat(); newMat.setMatnr(mesMatInfo.getItemNo()); newMat.setMaktx(mesMatInfo.getDescription()); newMat.setTagId(tagId); newMat.setLocType(tagId); //locType newMat.setSpecs(mesMatInfo.getSpecification()); newMat.setUnit(mesMatInfo.getUnitOfMeasure()); newMat.setModel(mesMatInfo.getClassificationCode()); newMat.setMemo(JSONObject.toJSONString(mesMatInfo)); newMat.setCreateBy(defaultUserId); newMat.setCreateTime(now); newMat.setUpdateBy(defaultUserId); newMat.setUpdateTime(now); newMat.setStatus(1); if (mat == null) { if (!matService.insert(newMat)) return -2; } else { JSONObject dbMemo = JSONObject.parseObject(mat.getMemo()); dbMemo.remove("OrderNo"); dbMemo.remove("qty"); dbMemo.remove("ItemBarcode"); JSONObject newMemo = JSONObject.parseObject(newMat.getMemo()); newMemo.remove("OrderNo"); newMemo.remove("qty"); dbMemo.remove("ItemBarcode"); if (!dbMemo.equals(newMemo)) { newMat.setId(mat.getId()); if (!matService.updateById(newMat)) return -2; } } } else { return -1; } return 1; } /** * 物料同步入库单,按OrderNo生成多个订单 * * * @param matRecvForm * @return */ public int inBoundOrder_List(MesMatRecvForm matRecvForm){ long docType = 4; // docType根据库类型确定 long settle = 1; Date now = new Date(); // 按OrderNo分组,然后再生成入库单 List mesInApply = matRecvForm.getItemdata(); Map> map = mesInApply.stream().collect(Collectors.groupingBy(MesMatInfo::getOrderNo)); for (Map.Entry> entry : map.entrySet()) { List list = entry.getValue(); // 校验订单是否重复 OrderPakin order = orderPakinService.selectByNo(entry.getKey()); if (order != null && !StringUtils.isEmpty(order.getOrderNo())) { return -1; } // 生成订单 JSONObject newMemo = new JSONObject(); newMemo.put("sourceNo", matRecvForm.getSourceNo()); newMemo.put("sourceName", matRecvForm.getSourceName()); newMemo.put("operuser", matRecvForm.getOperuser()); newMemo.put("itemdata", list); OrderPakin orderPakin = new OrderPakin(); orderPakin.setUuid(String.valueOf(snowflakeIdWorker.nextId())); orderPakin.setOrderNo(entry.getKey()); orderPakin.setOrderTime(com.core.common.DateUtils.convert(now)); orderPakin.setDocType(docType); orderPakin.setSettle(settle); orderPakin.setStatus(1); orderPakin.setCreateBy(defaultUserId); orderPakin.setCreateTime(now); orderPakin.setUpdateBy(defaultUserId); orderPakin.setUpdateTime(now); orderPakin.setMemo(newMemo.toJSONString()); //为领料入库完成反馈保存 JSONObject.toJSONString(matRecvForm) orderPakin.setPakinPakoutStatus(1); if (!orderPakinService.insert(orderPakin)) { log.error("MES保存入库订单主档失败"); throw new CoolException("保存入库订单主档失败"); } // 生成明细 for (MesMatInfo mesMat : list) { Mat mat = matService.selectByMatnr(mesMat.getItemNo()); OrderDetlPakin orderDetlPakin = new OrderDetlPakin(); orderDetlPakin.setOrderId(orderPakin.getId()); orderDetlPakin.setOrderNo(orderPakin.getOrderNo()); orderDetlPakin.setAnfme(Double.valueOf(mesMat.getQty())); orderDetlPakin.setQty(0.0); orderDetlPakin.setMatnr(mat.getMatnr()); orderDetlPakin.setMaktx(mat.getMaktx()); orderDetlPakin.setSpecs(mat.getSpecs()); orderDetlPakin.setModel(mat.getModel()); orderDetlPakin.setStandby1(JSONObject.toJSONString(mesMat.getItemBarcode())); // 零件二维码 orderDetlPakin.setStandby2("1"); //保存齐套性检查标识,1 检查;0 不检查; orderDetlPakin.setCreateBy(defaultUserId); orderDetlPakin.setCreateTime(now); orderDetlPakin.setUpdateBy(defaultUserId); orderDetlPakin.setUpdateTime(now); orderDetlPakin.setStatus(1); orderDetlPakin.setPakinPakoutStatus(1); if (!orderDetlPakinService.insert(orderDetlPakin)) { log.error("MES保存入库订单明细档失败1"); throw new CoolException("保存入库订单明细档失败1"); } } } return 1; } /** * 领料入库反馈 * 触发条件:物料同步接口入库单,入库后 * 推送时机:当订单中有物料入库后(应该在每托入库完成后,可以在更新OrderDetlPakin之后)则推送,不等全部订单完成 * * @param orderNo * @param zapplet * @return */ public int recvFeedback(String orderNo, String zapplet) { OrderPakin order = orderPakinService.selectByNo(orderNo); if (order != null && !StringUtils.isEmpty(order.getOrderNo())) { List list = new ArrayList<>(); JSONObject dbMemo = JSONObject.parseObject(order.getMemo()); // 从组托信息中查询入库的信息 EntityWrapper waitPakinEntityWrapper = new EntityWrapper<>(); waitPakinEntityWrapper.eq("zpallet", zapplet); List zpalletMat = waitPakinService.selectList(waitPakinEntityWrapper); EntityWrapper wrapper = new EntityWrapper<>(); wrapper.eq("order_no", orderNo); List orderDetlPakins = orderDetlPakinService.selectList(wrapper); if (orderDetlPakins != null && !orderDetlPakins.isEmpty()) { for (OrderDetlPakin orderDetl : orderDetlPakins) { for (WaitPakin zMat : zpalletMat) { if (orderDetl.getMatnr().equals(zMat.getMatnr())) { MesRecvFeedback.MesRecvFeedbackItem item = new MesRecvFeedback.MesRecvFeedbackItem(); item.setItemNo(orderDetl.getMatnr()); item.setOrderNo(orderNo); item.setQty(orderDetl.getAnfme().intValue()); item.setRealQty(zMat.getAnfme().intValue()); // 回传托盘绑定的零件二维码 EntityWrapper matItemBarcodeEntityWrapper = new EntityWrapper<>(); matItemBarcodeEntityWrapper.eq("zapplet", zapplet).eq("status", 1); List barcodes = matItemBarcodeMapper.selectList(matItemBarcodeEntityWrapper); if (barcodes != null) { List itemBarcode = new ArrayList<>(); for (MatItemBarcode barcode : barcodes) { itemBarcode.add(barcode.getItemBarcode()); } item.setItemBarcode(itemBarcode); list.add(item); } } } } } MesRecvFeedback mesRecvFeedback = new MesRecvFeedback(); mesRecvFeedback.setSourceNo(dbMemo.getString("sourceNo")); mesRecvFeedback.setOperuser(dbMemo.getString("operuser")); mesRecvFeedback.setItemdata(list); String url = MES_URL + "MaterialReceiptAndReturn"; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesRecvFeedback)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { return 1; } } } return 0; } /** * 出库申请,加工库、刀具库 * 出库后需要自动呼叫AGV送货 * 出库规则:需要按零件二维码(一件一码)出库,整托出库,该托上有其他物料也一起出库,他们后期会再入库 * * @param mesOutApply * @return 1 成功;-1 订单重复; */ public int outBoundOrder(MesOutApply mesOutApply){ // 空托出库 if (StringUtils.isEmpty(mesOutApply.getOrderNo()) && "01".equals(mesOutApply.getTransType())) { // 生成空托出库任务 mobileService.callEmptyBinOutBound(WMS_TRANS_START_STATION_1,"1",defaultUserId); try { if (!StringUtils.isEmpty(mesOutApply.getTaskno()) && !StringUtils.isEmpty(mesOutApply.getStationId())) { TransTask transTask = new TransTask(); transTask.setTaskno(mesOutApply.getTaskno()); transTask.setTaskname(mesOutApply.getTaskname()); transTask.setOrderNo(mesOutApply.getOrderNo()); transTask.setTransType(mesOutApply.getTransType()); transTask.setCurStationId(WMS_TRANS_START_STATION_1); transTask.setNextProcess(mesOutApply.getProductLineId()); transTask.setNextStationId(mesOutApply.getStationId()); transTask.setItemno(WMS_ZPALLET_ID); // 固定为空托的编码 transTask.setQty(1); // 空托只出1个 transTask.setProductLineId(mesOutApply.getProductLineId()); transTask.setOperateType(1); transTask.setAgvFactory(1); JSONObject sendAgvTask = submitTask(transTask); if (!"1".equals(sendAgvTask.getString("Success"))) { log.error("出库下发agv运输任务失败:{}", JSONObject.toJSONString(transTask)); } } } catch (Exception e) { log.error("下发AGV运输任务失败", e); } return 1; } else { // 毛坯(物料)出库 // docType根据库类型确定 long docType = 7; long settle = 1; // 校验订单是否重复 OrderPakout order = orderPakoutService.selectByNo(mesOutApply.getOrderNo()); if (order != null && !StringUtils.isEmpty(order.getOrderNo())) { log.error("出库订单号重复:{}",mesOutApply.getOrderNo()); return -1; } // 生成订单 Date now = new Date(); OrderPakout orderPakout = new OrderPakout(); orderPakout.setUuid( String.valueOf(snowflakeIdWorker.nextId())); orderPakout.setOrderNo(mesOutApply.getOrderNo()); orderPakout.setOrderTime(com.core.common.DateUtils.convert(now)); orderPakout.setDocType(docType); orderPakout.setSettle(settle); orderPakout.setStatus(1); orderPakout.setCreateBy(defaultUserId); orderPakout.setCreateTime(now); orderPakout.setUpdateBy(defaultUserId); orderPakout.setUpdateTime(now); orderPakout.setMemo(JSONObject.toJSONString(mesOutApply)); orderPakout.setPakinPakoutStatus(2); if (!orderPakoutService.insert(orderPakout)) { log.error("MES保存出库订单主档失败"); throw new CoolException("保存出库订单主档失败"); } // 生成明细 Mat mat = matService.selectByMatnr(mesOutApply.getItemno()); OrderDetlPakout orderDetlPakout = new OrderDetlPakout(); orderDetlPakout.setOrderId(orderPakout.getId()); orderDetlPakout.setOrderNo(orderPakout.getOrderNo()); orderDetlPakout.setAnfme(Double.valueOf(mesOutApply.getQty())); orderDetlPakout.setQty(0.0); orderDetlPakout.setMatnr(mat.getMatnr()); orderDetlPakout.setMaktx(mat.getMaktx()); orderDetlPakout.setSpecs(mat.getSpecs()); orderDetlPakout.setModel(mat.getModel()); orderDetlPakout.setStandby1(barCodeListToStr(mesOutApply.getItemBarcode())); orderDetlPakout.setCreateBy(defaultUserId); orderDetlPakout.setCreateTime(now); orderDetlPakout.setUpdateBy(defaultUserId); orderDetlPakout.setUpdateTime(now); orderDetlPakout.setStatus(1); orderDetlPakout.setPakinPakoutStatus(2); if (!orderDetlPakoutService.insert(orderDetlPakout)) { log.error("MES保存出库订单明细档失败"); throw new CoolException("保存出库订单明细档失败"); } // TODO:若AGV和输送线没有安全交互,则要保证立库出货完成后再呼叫AGV。 // 立库生成订单后,自动调度AGV运送到站点,目前多托生成多个。 try { if (!StringUtils.isEmpty(mesOutApply.getTaskno()) && !StringUtils.isEmpty(mesOutApply.getStationId())) { // 按零件二维码查询有几个托,多托生成多个任务,每托对应零件二维码 String barCode = barCodeListToStr(mesOutApply.getItemBarcode()); EntityWrapper matItemBarcodeEntityWrapper = new EntityWrapper<>(); matItemBarcodeEntityWrapper.in("item_barcode", barCode); List barcodes = matItemBarcodeMapper.selectList(matItemBarcodeEntityWrapper); if (barcodes != null) { Map> map = barcodes.stream().collect(Collectors.groupingBy(MatItemBarcode::getZapplet)); for (Map.Entry> entry : map.entrySet()) { List list = entry.getValue(); List codes = new ArrayList<>(); for (MatItemBarcode zapllet : list) { codes.add(zapllet.getItemBarcode()); } TransTask transTask = new TransTask(); transTask.setTaskno(mesOutApply.getTaskno()); transTask.setTaskname(mesOutApply.getTaskname()); transTask.setOrderNo(mesOutApply.getOrderNo()); transTask.setTransType(mesOutApply.getTransType()); transTask.setCurStationId(WMS_TRANS_START_STATION_3); transTask.setNextProcess(mesOutApply.getProductLineId()); transTask.setNextStationId(mesOutApply.getStationId()); transTask.setItemno(mesOutApply.getItemno()); transTask.setQty(list.size()); transTask.setProductLineId(mesOutApply.getProductLineId()); transTask.setItemBarcode(codes); transTask.setTuoPanId(entry.getKey()); transTask.setOperateType(1); transTask.setAgvFactory(1); JSONObject sendAgvTask = submitTask(transTask); if (!"1".equals(sendAgvTask.getString("Success"))) { log.error("出库下发agv运输任务失败", JSONObject.toJSONString(transTask)); } } } } } catch (Exception e) { log.error("下发AGV运输任务失败", e); } } return 1; } /** * 入库申请 * 收到入库申请后自动呼叫AGV取货 * * @param mesInApply */ @Transactional public int inBoundOrder(MesInApply mesInApply){ // 空托回库 if (StringUtils.isEmpty(mesInApply.getOrderNo()) && StringUtils.isEmpty(mesInApply.getItemno())) { if (!StringUtils.isEmpty(mesInApply.getTaskno()) && !StringUtils.isEmpty(mesInApply.getStationID())) { TransTask transTask = new TransTask(); transTask.setTaskno(mesInApply.getTaskno()); transTask.setTaskname(mesInApply.getTaskname()); transTask.setOrderNo(mesInApply.getOrderNo()); transTask.setTransType(mesInApply.getTransType()); transTask.setCurProcess(mesInApply.getProductLineId()); transTask.setCurStationId(mesInApply.getStationID()); transTask.setNextStationId(WMS_TRANS_START_STATION_2); transTask.setItemno(WMS_ZPALLET_ID); // 固定为空托的编码 transTask.setQty(1); // 空托只回1个 transTask.setProductLineId(mesInApply.getProductLineId()); transTask.setOperateType(1); transTask.setAgvFactory(1); JSONObject sendAgvTask = submitTask(transTask); if (!"1".equals(sendAgvTask.getString("Success"))) { log.error("出库下发agv运输任务失败,{}", JSONObject.toJSONString(transTask)); return 2; } } else { log.error("无任务号:{},或无物料编码:{}",mesInApply.getTaskno(),mesInApply.getItemno() ); return 2; } return 1; } else { // 毛坯、成品回库 // docType根据库类型确定 long docType = 3; long settle = 1; // 校验订单是否重复 OrderPakin order = orderPakinService.selectByNo(mesInApply.getOrderNo()); if (order != null && !StringUtils.isEmpty(order.getOrderNo())) { log.error("订单重复:{}", mesInApply.getOrderNo()); return 2; } // 生成订单 Date now = new Date(); OrderPakin orderPakin = new OrderPakin(); orderPakin.setUuid(String.valueOf(snowflakeIdWorker.nextId())); orderPakin.setOrderNo(mesInApply.getOrderNo()); orderPakin.setOrderTime(com.core.common.DateUtils.convert(now)); orderPakin.setDocType(docType); orderPakin.setSettle(settle); orderPakin.setStatus(1); orderPakin.setCreateBy(defaultUserId); orderPakin.setCreateTime(now); orderPakin.setUpdateBy(defaultUserId); orderPakin.setUpdateTime(now); orderPakin.setMemo(JSONObject.toJSONString(mesInApply)); //为出库完成反馈保存 orderPakin.setPakinPakoutStatus(1); orderPakinService.insert(orderPakin); // 生成明细 Mat mat = matService.selectByMatnr(mesInApply.getItemno()); OrderDetlPakin orderDetlPakin = new OrderDetlPakin(); orderDetlPakin.setOrderId(orderPakin.getId()); orderDetlPakin.setOrderNo(orderPakin.getOrderNo()); orderDetlPakin.setAnfme(Double.valueOf(mesInApply.getQty())); orderDetlPakin.setQty(0.0); orderDetlPakin.setMatnr(mat.getMatnr()); orderDetlPakin.setMaktx(mat.getMaktx()); orderDetlPakin.setSpecs(mat.getSpecs()); orderDetlPakin.setModel(mat.getModel()); if (mesInApply.getProductInfo() != null) { orderDetlPakin.setStandby1(JSONObject.toJSONString(mesInApply.getProductInfo())); //零件详情存在1 } orderDetlPakin.setStandby2("0"); //保存齐套性检查标识,1 检查;0 不检查; orderDetlPakin.setCreateBy(defaultUserId); orderDetlPakin.setCreateTime(now); orderDetlPakin.setUpdateBy(defaultUserId); orderDetlPakin.setUpdateTime(now); orderDetlPakin.setStatus(1); orderDetlPakin.setPakinPakoutStatus(1); orderDetlPakinService.insert(orderDetlPakin); // 生成入库通知档 WaitPakin waitPakin = new WaitPakin(); BeanUtils.copyProperties(mat, waitPakin); // waitPakin.sync(mat); waitPakin.setOrderNo(orderPakin.getOrderNo()); // 单据编号 waitPakin.setOrderId(orderPakin.getId()); waitPakin.setZpallet(mesInApply.getTuoPanId()); // 托盘码 waitPakin.setIoStatus("N"); // 入出状态 waitPakin.setAnfme(orderDetlPakin.getAnfme()); // 数量 waitPakin.setStatus("Y"); // 状态 waitPakin.setAppeUser(defaultUserId); waitPakin.setAppeTime(now); waitPakin.setModiUser(defaultUserId); waitPakin.setModiTime(now); List itemBarcode = mesInApply.getProductInfo().stream().map(MesInApply.ProductInfo::getItemBarcode).collect(Collectors.toList()); waitPakin.setStandby1(barCodeListToStr(itemBarcode)); waitPakinService.insert(waitPakin); OrderInAndOutUtil.increaseWorkQty(Boolean.TRUE, orderPakin.getId(), orderDetlPakin.getMatnr(), orderDetlPakin.getBatch(), orderDetlPakin.getBrand(), orderDetlPakin.getStandby1(), orderDetlPakin.getStandby2(), orderDetlPakin.getStandby3(), orderDetlPakin.getBoxType1(), orderDetlPakin.getBoxType2(), orderDetlPakin.getBoxType3(), orderDetlPakin.getAnfme()); OrderInAndOutUtil.updateOrder(Boolean.TRUE, orderPakin.getId(), 2L, defaultUserId); // 呼叫AGV从产线运回立库 try { if (!StringUtils.isEmpty(mesInApply.getTaskno())) { TransTask transTask = new TransTask(); transTask.setTaskno(mesInApply.getTaskno()); transTask.setTaskname(mesInApply.getTaskname()); transTask.setOrderNo(mesInApply.getOrderNo()); transTask.setTransType(mesInApply.getTransType()); transTask.setCurProcess(mesInApply.getProductLineId()); transTask.setCurStationId(mesInApply.getStationID()); transTask.setNextStationId(WMS_TRANS_START_STATION_2); transTask.setItemno(mesInApply.getItemno()); transTask.setQty(mesInApply.getQty()); transTask.setProductLineId(mesInApply.getProductLineId()); transTask.setItemBarcode(itemBarcode); transTask.setTuoPanId(mesInApply.getTuoPanId()); transTask.setOperateType(1); transTask.setAgvFactory(1); JSONObject sendAgvTask = submitTask(transTask); if (!"1".equals(sendAgvTask.getString("Success"))) { log.error("出库下发agv运输任务失败:{}", JSONObject.toJSONString(transTask)); } } } catch (Exception e) { log.error("下发AGV运输任务失败", e); } } return 1; } /** * 出库完成 * 出库后,按托推送,非整个订单 * * @param orderNo * @return */ public int outFeedbackByTuo(String orderNo, Task agvTask) { int success = 0; OrderPakout order = orderPakoutService.selectByNo(orderNo); if (order != null && !StringUtils.isEmpty(order.getOrderNo())) { JSONObject dbMemo = JSONObject.parseObject(order.getMemo()); // TODO:出库完成后,若未解绑托盘和物料,则执行托盘解绑 // TODO:出库完成后,若未清除零件二维码,则执行清除,也可以在AGV送货完成后清除 // EntityWrapper wrapper = new EntityWrapper<>(); // wrapper.eq("order_no", orderNo); // List orderDetlPakouts = orderDetlPakoutService.selectList(wrapper); // if (orderDetlPakouts != null && !orderDetlPakouts.isEmpty()) { // for (OrderDetlPakout orderDetl : orderDetlPakouts) { // StringBuilder palletId = new StringBuilder(); // EntityWrapper wrapper2 = new EntityWrapper<>(); // wrapper2.eq("order_no", orderDetl.getOrderNo()); // List waitPakins = waitPakinService.selectList(wrapper2); // if (waitPakins != null && waitPakins.size() > 0) { // for (WaitPakin waitPakin : waitPakins) { // palletId.append(waitPakin.getZpallet()).append(","); // } // } // // MesOutFeedback mesOutFeedback = new MesOutFeedback(); // mesOutFeedback.setTaskno(dbMemo.getString("taskno")); // mesOutFeedback.setTaskname(dbMemo.getString("taskname")); // mesOutFeedback.setProductLineId(dbMemo.getString("ProductLineId")); // mesOutFeedback.setStationId(dbMemo.getString("StationID")); // mesOutFeedback.setItemno(orderDetl.getMatnr()); // mesOutFeedback.setTuoPanId(zpalletId); // mesOutFeedback.setQty(orderDetl.getQty().intValue()); // if (!StringUtils.isEmpty(dbMemo.getString("ItemBarcode"))) { // mesOutFeedback.setItemBarcode(barCodeStrToList(dbMemo.getString("ItemBarcode"))); // } // mesOutFeedback.setOrderNo(orderNo); // } // } EntityWrapper entityWrapper = new EntityWrapper<>(); entityWrapper.eq("wrk_no", agvTask.getWrkNo()); TaskDetl taskDetl = taskDetlService.selectOne(entityWrapper); String zpalletId = taskDetl.getZpallet(); List itemBarCode = new ArrayList<>(); JSONArray array = JSONArray.parseArray(taskDetl.getMemo()); for (Object one : array) { itemBarCode.add(one.toString()); // TODO:入库时存储零件码(ItemBarCode),并绑定托盘,出库后这里考虑解绑 } MesOutFeedback mesOutFeedback = new MesOutFeedback(); mesOutFeedback.setTaskno(agvTask.getTaskNo()); mesOutFeedback.setTaskname(dbMemo.getString("taskname")); mesOutFeedback.setProductLineId(dbMemo.getString("ProductLineId")); mesOutFeedback.setStationId(dbMemo.getString("StationId")); mesOutFeedback.setItemno(dbMemo.getString("Itemno")); mesOutFeedback.setTuoPanId(zpalletId); if (itemBarCode != null && itemBarCode.size() > 0) { mesOutFeedback.setQty(itemBarCode.size()); mesOutFeedback.setItemBarcode(itemBarCode); } mesOutFeedback.setOrderNo(orderNo); String url = MES_URL + "issueComplete"; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesOutFeedback)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { success = 1; } } } return success; } /** * 入库完成 * 入库后,按托推送,非整个订单 * * @param orderNo * @param zapplet * @return */ public int inFeedbackByTuo(String orderNo, String zapplet) { int success = 0; OrderPakin order = orderPakinService.selectByNo(orderNo); if (order != null && !StringUtils.isEmpty(order.getOrderNo())) { List list = new ArrayList<>(); // 从托盘绑定的零件二维码中查询信息 EntityWrapper matItemBarcodeEntityWrapper = new EntityWrapper<>(); matItemBarcodeEntityWrapper.eq("zapplet", zapplet).eq("status", 1); List barcodes = matItemBarcodeMapper.selectList(matItemBarcodeEntityWrapper); for (MatItemBarcode barcode : barcodes) { MesInApply.ProductInfo productInfo = new MesInApply.ProductInfo(); productInfo.setItemBarcode(barcode.getItemBarcode()); productInfo.setQualityStatus(barcode.getQualityStatus()); list.add(productInfo); } MesInApply result = JSONObject.parseObject(order.getMemo(), MesInApply.class); result.setProductInfo(list); result.setQty(list.size()); String url = MES_URL + "loadComplete"; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(result)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { success = 1; } } } return success; } /** * 零件二维码,数组转string * * @param list * @return */ public static String barCodeListToStr(List list) { StringBuilder stringBuilder = new StringBuilder(); for (String str : list) { stringBuilder.append(str).append(","); } String result = stringBuilder.toString(); return result.endsWith(",") ? result.substring(0, result.length() - 1) : result; } /** * 零件二维码,string转数组 * * @param str * @return */ public static List barCodeStrToList(String str) { String[] array = str.split(","); return Arrays.asList(array); } /** * 入库完成 * 入库单完成后,整单推送 * * @param orderNo * @return */ public int inFeedback(String orderNo) { int success = 0; OrderPakin order = orderPakinService.selectByNo(orderNo); if (order != null && !StringUtils.isEmpty(order.getOrderNo())) { EntityWrapper wrapper = new EntityWrapper<>(); wrapper.eq("order_no", orderNo); List orderDetlPakins = orderDetlPakinService.selectList(wrapper); if (orderDetlPakins != null && !orderDetlPakins.isEmpty()) { for (OrderDetlPakin orderDetl : orderDetlPakins) { MesInApply result = JSONObject.parseObject(order.getMemo(), MesInApply.class); result.setQty(orderDetl.getQty().intValue()); String url = MES_URL + "loadComplete"; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(result)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { success++; } } } if (success == orderDetlPakins.size()) { success = 1; } else { success = 0; } } } return success; } /** * (备份)出库订单完成 * * @param orderNo * @return */ public int outFeedback(String orderNo) { int success = 0; OrderPakout order = orderPakoutService.selectByNo(orderNo); if (order != null && order.getSettle() == 4) { // 校验是否完成 JSONObject dbMemo = JSONObject.parseObject(order.getMemo()); EntityWrapper wrapper = new EntityWrapper<>(); wrapper.eq("order_no", orderNo); List orderDetlPakouts = orderDetlPakoutService.selectList(wrapper); if (orderDetlPakouts != null && !orderDetlPakouts.isEmpty()) { for (OrderDetlPakout orderDetl : orderDetlPakouts) { StringBuilder palletId = new StringBuilder(); EntityWrapper wrapper2 = new EntityWrapper<>(); wrapper2.eq("order_no", orderDetl.getOrderNo()); List waitPakins = waitPakinService.selectList(wrapper2); if (waitPakins != null && waitPakins.size() > 0) { for (WaitPakin waitPakin : waitPakins) { palletId.append(waitPakin.getZpallet()).append(","); } } MesOutFeedback mesOutFeedback = new MesOutFeedback(); mesOutFeedback.setTaskno(dbMemo.getString("taskno")); mesOutFeedback.setTaskname(dbMemo.getString("taskname")); mesOutFeedback.setProductLineId(dbMemo.getString("ProductLineId")); mesOutFeedback.setStationId(dbMemo.getString("StationID")); mesOutFeedback.setItemno(orderDetl.getMatnr()); if (!StringUtils.isEmpty(palletId.toString())) { mesOutFeedback.setTuoPanId(palletId.substring(0, palletId.length() - 1)); } mesOutFeedback.setQty(orderDetl.getQty().intValue()); if (!StringUtils.isEmpty(dbMemo.getString("ItemBarcode"))) { mesOutFeedback.setItemBarcode(barCodeStrToList(dbMemo.getString("ItemBarcode"))); } mesOutFeedback.setOrderNo(orderNo); // TODO:备注:出库完成后解绑托盘和物料,若前面未解绑,此处需要解绑 String url = MES_URL + "issueComplete"; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(mesOutFeedback)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { success++; } } } if (success == orderDetlPakouts.size()) { success = 1; // TODO:立库出库后自动调度AGV运送到站点 String taskNo = dbMemo.getString("taskno"); if (!StringUtils.isEmpty(taskNo)) { TransTask transTask = new TransTask(); transTask.setTaskno(dbMemo.getString("taskno")); transTask.setTaskname(dbMemo.getString("taskname")); transTask.setOrderNo(dbMemo.getString("OrderNo")); transTask.setTransType(dbMemo.getString("TransType")); // transTask.setCurProcess(); transTask.setCurStationId(WMS_TRANS_START_STATION_1); transTask.setNextProcess(dbMemo.getString("ProductLineId")); transTask.setNextStationId(dbMemo.getString("StationId")); transTask.setItemno(dbMemo.getString("Itemno")); transTask.setQty(dbMemo.getInteger("Qty")); transTask.setProductLineId(dbMemo.getString("ProductLineId")); transTask.setItemBarcode(barCodeStrToList(dbMemo.getString("ItemBarcode"))); transTask.setOperateType(1); transTask.setAgvFactory(1); JSONObject sendAgvTask = submitTask(transTask); if (!"1".equals(sendAgvTask.getString("Success"))) { log.error("出库下发agv运输任务失败", JSONObject.toJSONString(transTask)); } } } else { success = 0; } } } return success; } /** * 出库申请(叫料),装配库、滑块库 * * @param mesCallOutApply * @return */ public int callOutBoundOrder(MesCallOutApply mesCallOutApply){ // docType根据库类型确定 long docType = 7; long settle = 1; // 校验订单是否重复 OrderPakout order = orderPakoutService.selectByNo(mesCallOutApply.getOrderNo()); if (order != null && !StringUtils.isEmpty(order.getOrderNo())) { return -1; } // 生成订单 Date now = new Date(); OrderPakout orderPakout = new OrderPakout(); orderPakout.setUuid(String.valueOf(snowflakeIdWorker.nextId())); orderPakout.setOrderNo(mesCallOutApply.getOrderNo()); orderPakout.setOrderTime(com.core.common.DateUtils.convert(now)); orderPakout.setDocType(docType); orderPakout.setSettle(settle); orderPakout.setStatus(1); orderPakout.setCreateBy(defaultUserId); orderPakout.setCreateTime(now); orderPakout.setUpdateBy(defaultUserId); orderPakout.setUpdateTime(now); orderPakout.setMemo(JSONObject.toJSONString(mesCallOutApply)); orderPakout.setPakinPakoutStatus(2); if (!orderPakoutService.insert(orderPakout)) { log.error("MES保存出库订单(叫料)主档失败"); throw new CoolException("保存出库订单(叫料)主档失败"); } // 生成明细 if (mesCallOutApply.getItemdata() != null && !mesCallOutApply.getItemdata().isEmpty()) { for (MesCallOutApply.MesOutApplyItem mesOutApplyItem : mesCallOutApply.getItemdata()) { Mat mat = matService.selectByMatnr(mesOutApplyItem.getItemno()); OrderDetlPakout orderDetlPakout = new OrderDetlPakout(); orderDetlPakout.setOrderId(orderPakout.getId()); orderDetlPakout.setOrderNo(orderPakout.getOrderNo()); orderDetlPakout.setAnfme(Double.valueOf(mesOutApplyItem.getQty())); orderDetlPakout.setQty(0.0); orderDetlPakout.setMatnr(mat.getMatnr()); orderDetlPakout.setMaktx(mat.getMaktx()); orderDetlPakout.setSpecs(mat.getSpecs()); orderDetlPakout.setModel(mat.getModel()); orderDetlPakout.setThreeCode(mesOutApplyItem.getItemBarcode()); orderDetlPakout.setStandby1(mesOutApplyItem.getTrayid()); //保存配盘号,非托盘号 orderDetlPakout.setCreateBy(defaultUserId); orderDetlPakout.setCreateTime(now); orderDetlPakout.setUpdateBy(defaultUserId); orderDetlPakout.setUpdateTime(now); orderDetlPakout.setStatus(1); orderDetlPakout.setPakinPakoutStatus(2); if (!orderDetlPakoutService.insert(orderDetlPakout)) { log.error("MES保存出库订单(叫料)明细档失败"); throw new CoolException("保存出库订单(叫料)明细档失败"); } } } return 1; } // endregion // region 搬运任务调度 // route转发3个WCS任务 /** * 9.1下发运输任务 * TODO:其他库的任务全部转到滑块库统一调度 * * @param transTask * @return */ @Transactional public JSONObject submitTask(TransTask transTask) { JSONObject result = new JSONObject(); result.put("taskno", transTask.getTaskno()); // 重复性校验 EntityWrapper wrapper = new EntityWrapper<>(); wrapper.eq("task_no", transTask.getTaskno()); List tasks = taskService.selectList(wrapper); if (tasks != null && !tasks.isEmpty()) { log.error("agv任务号重复:{}", transTask.getTaskno()); result.put("Success", "2"); result.put("Message", "agv任务号重复:" + transTask.getTaskno()); return result; } // 下发给RCS RcsTaskSubmit rcsTaskSubmit = new RcsTaskSubmit(); rcsTaskSubmit.setRobotTaskCode(transTask.getTaskno()); rcsTaskSubmit.setInitPriority(10); //默认10 List targetRouteList = new ArrayList<>(); RcsTaskTargetRoute startRoute = new RcsTaskTargetRoute(); startRoute.setSeq(0); startRoute.setCode(transTask.getCurStationId()); startRoute.setOperation("COLLECT"); targetRouteList.add(startRoute); RcsTaskTargetRoute endRoute = new RcsTaskTargetRoute(); endRoute.setSeq(1); endRoute.setCode(transTask.getNextStationId()); endRoute.setOperation("DELIVERY"); targetRouteList.add(endRoute); rcsTaskSubmit.setTargetRoute(targetRouteList); // 转发给海康或华晓RCS // int success = rcsService.submitTask(rcsTaskSubmit, transTask.getAgvFactory()); int success = 1; if (success == 1) { int workNo = commonService.getWorkNo(WorkNoType.OTHER.type); Date now = new Date(); Task task = new Task(); task.setWrkNo(workNo); task.setTaskType("AGV"); task.setWrkSts(301L); task.setIoType(3); task.setIoPri(10.00); task.setWrkDate(now); task.setSourceStaNo(transTask.getCurStationId()); task.setStaNo(transTask.getNextStationId()); task.setBarcode(transTask.getTuoPanId()); task.setModiUser(defaultUserId); task.setModiTime(now); task.setAppeUser(defaultUserId); task.setAppeTime(now); task.setTaskNo(transTask.getTaskno()); task.setMemo(JSONObject.toJSONString(transTask)); taskService.insert(task); Mat mat = matService.selectByMatnr(transTask.getItemno()); TaskDetl taskDetl = new TaskDetl(); taskDetl.setWrkNo(task.getWrkNo()); taskDetl.setIoTime(task.getIoTime()); taskDetl.setMatnr(transTask.getItemno()); taskDetl.setAnfme(0.0); taskDetl.setStandby1(String.valueOf(transTask.getQty())); taskDetl.setMaktx(mat.getMaktx()); taskDetl.setSpecs(mat.getSpecs()); taskDetl.setOrderNo(transTask.getOrderNo()); taskDetl.setZpallet(transTask.getTuoPanId()); taskDetl.setMemo(JSONObject.toJSONString(transTask.getItemBarcode())); taskDetl.setModiUser(defaultUserId); taskDetl.setModiTime(now); taskDetl.setAppeUser(defaultUserId); taskDetl.setAppeTime(now); taskDetlService.insert(taskDetl); result.put("Success", "1"); result.put("Message", "任务接收成功"); } else { result.put("Success", "2"); result.put("Message", "任务下发给RCS失败"); } return result; } /** * 9.2返回任务执行结果 * * @param rcsReporterTask * @return */ public int reporterTask(RcsReporterTask rcsReporterTask) { // 结果汇总 boolean completed = true; EntityWrapper wrapper = new EntityWrapper<>(); wrapper.eq("task_no", rcsReporterTask.getRobotTaskCode()); List tasks = taskService.selectList(wrapper); if (tasks != null && !tasks.isEmpty()) { for (Task task : tasks) { if (task.getWrkSts() != 304) { // TODO:确认完成,可能存在多盘任务 completed = false; } } } if (completed) { TransTaskFeedback transTaskFeedback = new TransTaskFeedback(); transTaskFeedback.setTaskno(rcsReporterTask.getRobotTaskCode()); // transTaskFeedback.setTaskname(); transTaskFeedback.setResult(1); String url = MES_URL + "api/task/reporter"; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(transTaskFeedback)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { return 1; } } } return 0; } /** * 9.8申请华晓AGV进入生产线 * * @param apply * @return */ public String applyInLine(TransParent apply) { String url = MES_URL + "api/apply/inLine"; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ JSONObject jsonObject = JSONObject.parseObject(response); if("1".equals(jsonObject.getString("Success"))) { return jsonObject.getJSONObject("Data").getString("status"); } } return "N"; } /** * 入站请求:转发AGV->入站请求->给MES * * @param apply * @return */ public int applyInStation(TransParent apply) { String path = ("LL").equals(apply.getProductLineId()) ? "AGVTransportPalletNotice" : "AprsAGVTransportPalletNotice"; String url = MES_URL + path; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { return 1; } } return 0; } /** * 入站允许:转发MES->允许入站->给AGV * * @param allow * @return */ public MesReturn allowInStation(TransInOutStationAllow allow) { MesReturn mesReturn = new MesReturn(); mesReturn.setSuccess("1"); if ("Y".equals(allow.getStatus())) { RcsTaskContinue rcsTaskContinue = new RcsTaskContinue(); rcsTaskContinue.setRobotTaskCode(allow.getTaskno()); rcsTaskContinue.setTriggerType("TASK"); rcsTaskContinue.setTriggerCode(allow.getTaskno()); // rcsTaskContinue.setTriggerType("ROBOT"); // rcsTaskContinue.setTriggerCode(allow.getAgvCode()); int success = rcsService.continueTask(rcsTaskContinue, checkRcsFactory(allow.getAgvCode())); mesReturn.setSuccess(success == 1 ? "1" : "2"); mesReturn.setMessage(success == 1 ? "" : "转发给RCS失败"); } return mesReturn; } /** * 到站完成:转发AGV->到站完成->给MES * * @param arrivalStation * @return */ public int arriveOnStation(TransArrivalStation arrivalStation) { if ("01".equals(arrivalStation.getDaotype())) { arrivalStation.setItemno(null); arrivalStation.setItemBarcode(new ArrayList<>()); arrivalStation.setOrderNo(null); } String url = MES_URL + "AGVArrivalCompleted"; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(arrivalStation)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { return 1; } } return 0; } /** * 离站请求:转发AGV->离站请求->给MES * * @param apply * @return */ public int applyOutStation(TransParent apply) { String url = MES_URL + "api/apply/outStation"; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { return 1; } } return 0; } /** * 离站允许:转发MES->允许离站->给AGV * * @param allow * @return */ public MesReturn allowOutStation(TransInOutStationAllow allow) { MesReturn mesReturn = new MesReturn(); mesReturn.setSuccess("1"); if ("Y".equals(allow.getStatus())) { RcsTaskContinue rcsTaskContinue = new RcsTaskContinue(); rcsTaskContinue.setRobotTaskCode(allow.getTaskno()); rcsTaskContinue.setTriggerType("TASK"); rcsTaskContinue.setTriggerCode(allow.getTaskno()); int success = rcsService.continueTask(rcsTaskContinue, checkRcsFactory(allow.getAgvCode())); mesReturn.setSuccess(success == 1 ? "1" : "2"); mesReturn.setMessage(success == 1 ? "" : "转发给RCS失败"); } return mesReturn; } /** * 离站完成:转发AGV->离站完成->给MES * * @param apply * @return */ public int outStation(TransParent apply) { String url = MES_URL + "AGVDepartureCompleted"; String response = RcsServiceImpl.sendPost(url, JSONObject.toJSONString(apply)); if (!StringUtils.isEmpty(response) && response.contains("Success")){ MesReturn mesReturn = JSONObject.parseObject(response, MesReturn.class); if("1".equals(mesReturn.getSuccess())) { return 1; } } return 0; } @Override public MesReturn queryInventory(String itemno,String orderNo) { MesReturn mesReturn = new MesReturn(); mesReturn.setSuccess("1"); List locDetls = locDetlService.selectList(new EntityWrapper().eq("matnr", itemno).eq("order_no",orderNo)); int count = 0; for(LocDetl locDetl:locDetls) { count += locDetl.getAnfme(); } mesReturn.setMessage(String.valueOf(count)); return mesReturn; } // endregion /** * 查询Rcs地址 * * @param agvNo * @return 1 海康;2 华晓 */ private int checkRcsFactory(String agvNo) { AgvInfo agvInfo = agvInfoMapper.selectById(agvNo); return agvInfo.getAgvFactory(); } }