From 9543a7a674e1bfefbea1e373f4f28cadc350d830 Mon Sep 17 00:00:00 2001 From: "castle.zang" Date: Fri, 7 Feb 2025 20:07:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=B1=E6=B1=95kitting=E6=8B=89=E5=8A=A8,?= =?UTF-8?q?=E6=8C=89=E5=A5=97=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../serviceimpl/base/MesWorkOrderService.java | 230 +++++++++++++++++++++ 1 file changed, 230 insertions(+) diff --git a/modules/i3plus-ext-mes-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/apiservice/serviceimpl/base/MesWorkOrderService.java b/modules/i3plus-ext-mes-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/apiservice/serviceimpl/base/MesWorkOrderService.java index de18e8a..8369f48 100644 --- a/modules/i3plus-ext-mes-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/apiservice/serviceimpl/base/MesWorkOrderService.java +++ b/modules/i3plus-ext-mes-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/apiservice/serviceimpl/base/MesWorkOrderService.java @@ -39,6 +39,7 @@ import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.map.CaseInsensitiveMap; import org.apache.commons.collections.map.HashedMap; +import org.python.antlr.ast.While; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; @@ -186,6 +187,21 @@ public class MesWorkOrderService extends BaseMesService implements @Autowired private MesPartProdGroupRepository mesPartProdGroupRao; + @Autowired + private MesPullingOrderInfoRepository mesPullingOrderInfoRao; + + @Autowired + private MesPartPullRepository partPullRao; + + @Autowired + private MesWorkCenterRepository workCenterRao; + + @Autowired + private MesPartPullDetailRepository partPullDetailRao; + + @Autowired + private MesBomRepository bomRao; + @Override public MesWorkOrder insert(MesWorkOrder bean) { // 数据校验 @@ -715,6 +731,220 @@ public class MesWorkOrderService extends BaseMesService implements } } + private void doCreateKitting(List mesWorkOrderList,String organizeCode) { + //todo 在工单点击发布时,也需要重新触发拉动单,工单关闭时,也需要关闭拉动单 + //1.拉动组获取 -- 根据拉动组类型获取kitting,需要判断是否生成是否生成拉动单开关 + DdlPackBean partPullPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.PART_PULL_ORDER_TYPE.KITTING_PULL.getValue(),"pullOrderType", partPullPackBean); + DdlPreparedPack.getNumEqualPack(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue(),"isAutoCreatePullOrder", partPullPackBean); + List mesPartPullList = partPullRao.findByHqlWhere(partPullPackBean); + //2.工单 过滤出未生成拉动单的工单pullingStatus,按照拉动组产线分组,每组按照工单序号排序 + Map> workOrderMap = mesWorkOrderList.stream().filter(item -> item.getPullingStatus() == MesExtEnumUtil.WORK_ORDER_PULLING_STATUS.NOTCREATE.getValue()).collect(Collectors.groupingBy(MesWorkOrder::getWorkCenterCode)); + + //3.查询2中所有的产线信息 ,判断生成拉动单的工单状态 generateStatus 与工单状态对比 是否生成拉动单 MesExtEnumUtil.GENERATE_STATUS需要和工单类型一致才生成拉动单 + List workOrderCenterList = new ArrayList<>(workOrderMap.keySet()); + DdlPackBean workCenterPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getInPackList(workOrderCenterList,"workCenterCode", workCenterPackBean); + List workCenterList = workCenterRao.findByHqlWhere(workCenterPackBean); + Map> workCenterMap = workCenterList.stream().collect(Collectors.groupingBy(MesWorkCenter::getWorkCenterCode)); + //4.遍历拉动组 + for (MesPartPull mesPartPull : mesPartPullList) { + String workCenterCode = mesPartPull.getWorkCenterCode(); + //按数量圆整 + if(mesPartPull.getRoundMethod() == MesExtEnumUtil.PART_PULL_ROUND_METHOD.ROUND_BY_QUANTITY.getValue()){ + List workOrderList = workOrderMap.get(workCenterCode); + //遍历工单,打散成bom 生成拉动单 + List mesWorkCenters = workCenterMap.get(workCenterCode); + if (CollectionUtils.isEmpty(workOrderList) || CollectionUtils.isEmpty(mesWorkCenters)) { + continue; + } + Map> orderMap = workOrderList.stream().collect(Collectors.groupingBy(MesWorkOrder::getPartNo)); + for (String producePartNoAndTime : orderMap.keySet()) { + List workOrderListNew = orderMap.get(producePartNoAndTime); + doCreateKittingOrder(workOrderListNew,mesPartPull,mesWorkCenters.get(0)); + } + //按成套圆整 + } else if (mesPartPull.getRoundMethod() == MesExtEnumUtil.PART_PULL_ROUND_METHOD.ROUND_DOOR_PANELS_NUMBER.getValue()) { + //按成套圆整 会是同一个拉动组 生成拉动单 + Map> groupCodeMap = workOrderMap.get(workCenterCode).stream().collect(Collectors.groupingBy(MesWorkOrder::getGroupCode)); + for (Long l : groupCodeMap.keySet()) { + List workOrderList = groupCodeMap.get(l); + List mesWorkCenters = workCenterMap.get(workCenterCode); + if (CollectionUtils.isEmpty(workOrderList) || CollectionUtils.isEmpty(mesWorkCenters)) { + continue; + } + doCreateGroupKittingOrder(workOrderList,mesPartPull,mesWorkCenters.get(0)); + } + + } + } + } + //按成套圆整 + private void doCreateGroupKittingOrder(List workOrderListNew,MesPartPull mesPartPull,MesWorkCenter mesWorkCenter){ + String organizeCode = mesPartPull.getOrganizeCode(); + List list = new ArrayList<>(); + //1.查询拉动组详情 + DdlPackBean pullPartDetailPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(mesPartPull.getPullCode(),"pullCode", pullPartDetailPackBean); + List mesPartPullDetailList = partPullDetailRao.findByHqlWhere(pullPartDetailPackBean); + if (CollectionUtils.isEmpty(mesPartPullDetailList)) { + return; + } + // 打散所有的工单的bom + List pullPartNoList = mesPartPullDetailList.stream().map(MesPartPullDetail::getPullPartNo).collect(Collectors.toList()); + Map pullDetailMap = mesPartPullDetailList.stream().collect(Collectors.toMap(MesPartPullDetail::getPullPartNo, Function.identity())); + for (MesWorkOrder mesWorkOrder : workOrderListNew) { + List bomList = getPlatBom(null, mesWorkOrder.getPartNo(), TimeTool.getNowTime(true), organizeCode); + List collect = bomList.stream().filter(item -> pullPartNoList.contains(item.getItemPartNo())).collect(Collectors.toList()); + collect.forEach(item -> item.setItemQty(item.getItemQty() * mesWorkOrder.getQty())); + list.addAll(collect); + } + + // 计算所有拉动单的数量,生成拉动单 + + String workOrderStr = workOrderListNew.stream().map(MesWorkOrder::getWorkOrderNo).collect(Collectors.joining("/r/n")); + String workOrderPartNoStr = workOrderListNew.stream().map(MesWorkOrder::getPartNo).collect(Collectors.joining("/r/n")); + String workOrderPartNameStr = workOrderListNew.stream().map(MesWorkOrder::getPartName).collect(Collectors.joining("/r/n")); + String custPartNo = workOrderListNew.stream().map(MesWorkOrder::getCustPartNo).collect(Collectors.joining("/r/n")); + MesPullingOrderInfo pullingOrder = new MesPullingOrderInfo(); + pullingOrder.setOrganizeCode(organizeCode); + pullingOrder.setPullingOrderNo("xxx"); //拉动单号 + 8位年月日 + 5位流水号 + pullingOrder.setPullOrderType(mesPartPull.getPullOrderType()); + pullingOrder.setPullGroupFid(mesPartPull.getId()); + pullingOrder.setWorkOrderNo(workOrderStr); + pullingOrder.setIsPrint(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()); + pullingOrder.setPrintStatus(MesExtEnumUtil.PRINT_STATUS.UNPRINT.getValue()); + pullingOrder.setPullOrderStatus(MesExtEnumUtil.PULL_ORDER_STATUS.PULL_ORDER_STATUS_10.getValue()); + pullingOrder.setWorkCenterCode(mesPartPull.getWorkCenterCode()); + pullingOrder.setPullCode(mesPartPull.getPullCode()); + pullingOrder.setPartNo(workOrderPartNoStr); + pullingOrder.setPartName(workOrderPartNameStr); + pullingOrder.setCustPartNo(custPartNo); + pullingOrder.setCarModelCode(workOrderListNew.get(0).getCarModelCode()); + pullingOrder.setOrderFlag(workOrderListNew.get(0).getOrderFlag()); + ConvertBean.serviceModelInitialize(pullingOrder, AuthUtil.getSessionUser().getUserName()); + + // 需要合并同类项 + Map> itemBomMap = list.stream().collect(Collectors.groupingBy(MesBom::getItemPartNo)); + for (String itemPartNo : itemBomMap.keySet()) { + List mesBoms = itemBomMap.get(itemPartNo); + double sum = mesBoms.stream().collect(Collectors.summarizingDouble(MesBom::getItemQty)).getSum(); + MesPullingOrderPartInfo detail = new MesPullingOrderPartInfo(); + detail.setOrganizeCode(organizeCode); + detail.setPullCode(pullingOrder.getPullCode()); + detail.setPullingOrderNo(pullingOrder.getPullingOrderNo()); + detail.setWorkOrderNo(pullingOrder.getWorkOrderNo()); + detail.setWorkOrderSeq(pullingOrder.getWorkOrderSeq()); + detail.setCustOrderNo(pullingOrder.getCustOrderNo()); + MesBom mesBom = mesBoms.get(0); + detail.setPartNo(mesBom.getItemPartNo()); + detail.setPartName(mesBom.getItemPartName()); + detail.setPullQty(sum); + detail.setCustOrderNo(pullingOrder.getCustOrderNo()); + detail.setWorkOrderSeq(pullingOrder.getWorkOrderSeq()); + detail.setWaterSeq(pullingOrder.getProductSeq()); + detail.setWorkCellCode(mesWorkCenter.getWorkCenterCode()); + detail.setStatus(MesExtEnumUtil.PULL_ORDER_PART_STATUS.UN_SENTED.getValue());///明细已送料为1,未送料为0 + detail.setCustPartNo(pullingOrder.getCustPartNo()); + detail.setCarSeries(pullDetailMap.get(itemPartNo) == null ? "" : pullDetailMap.get(itemPartNo).getCarSeries()); + detail.setOrderFlag(pullingOrder.getOrderFlag()); + ConvertBean.serviceModelInitialize(detail, AuthUtil.getSessionUser().getUserName()); + } + + } + private void doCreateKittingOrder(List workOrderListNew,MesPartPull mesPartPull,MesWorkCenter mesWorkCenter) { + String organizeCode = mesWorkCenter.getOrganizeCode(); + //1.查询拉动组详情 + DdlPackBean pullPartDetailPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(mesPartPull.getPullCode(),"pullCode", pullPartDetailPackBean); + List mesPartPullDetailList = partPullDetailRao.findByHqlWhere(pullPartDetailPackBean); + if (CollectionUtils.isEmpty(mesPartPullDetailList)) { + return; + } + //bom中对应的partNo列表 + List partNoList = mesPartPullDetailList.stream().map(MesPartPullDetail::getPartNo).collect(Collectors.toList()); + //深汕按照包装圆整 + if (mesPartPull.getRoundMethod() == MesExtEnumUtil.PART_PULL_ROUND_METHOD.ROUND_BY_QUANTITY.getValue()){ + int packRoundQty = Integer.parseInt(mesPartPull.getPackRoundQty()); + String partNo = workOrderListNew.get(0).getPartNo(); + //打散bom + List bomList = getPlatBom(null, partNo, TimeTool.getNowTime(true), organizeCode); + //需要生成拉动单的零件 + List bomPullList = bomList.stream().filter(item -> partNoList.contains(item.getItemPartNo())).collect(Collectors.toList()); + + + /** + * 满足一个拉动组就生成一个拉动单 + * 分类 + * 1.当前bom 子零件数量 * 工单需求数量 > packRoundQty multiple是多少,是否有余数 取模 + * 2.当前bom 子零件数量 * 工单需求数量 = packRoundQty 直接整除,看看是否大于1 ,大于1需要拆分多个拉动单 + * 3.当前bom 子零件数量 * 工单需求数量 < packRoundQty 需要增加一个工单来补充当前的数量,补不齐继续补充 + */ + Map partNoRemainder = new HashMap<>(); + for (int i = 0; i < workOrderListNew.size(); i++) { + MesWorkOrder mesWorkOrder = workOrderListNew.get(0); + Double qty = mesWorkOrder.getQty(); + bomPullList.forEach(item -> item.setItemQty(item.getItemQty() * qty)); + for (int j = 0; j < bomPullList.size(); j++) { + double m = bomPullList.get(j).getItemQty() % packRoundQty; + double n = bomPullList.get(j).getItemQty() / packRoundQty; + if (m == 0 && n != 0){ + //子零件数量 * 工单需求数量 = packRoundQty + //证明当前零件需要拉动的数量是圆整数量的倍数,需要拆分多个拉动单,或者一个拉动单就满足了 + + }else if (m != 0 && n == 0) { + //子零件数量 * 工单需求数量 < packRoundQty + //证明需要凑下一个工单的当前零件 + } else if (m !=0 && n > 0) { + //子零件数量 * 工单需求数量 > packRoundQty + //够一个拉动单以上的数据,还有余数给 + + } + } + } + + + } + } + + private List getPlatBom(MesBom mesBom,String partNo, String effectiveTime,String organizeCode) { + //MES汇报查询BOM是否携带结束查询条件 + MesConfig config = mesConfigService.getCfgValueByCode(organizeCode, MesExtConstWords.MES_REPORT_FIND_BOM_WITH_EFFENDTIME); + Boolean isWithEffEndTime = (null != config && !org.springframework.util.StringUtils.isEmpty(config.getCfgValue()) && config.getCfgValue().equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr())) ? true : false; + + if (mesBom == null) { + //首先根据虚结构的零件号查询出最新的一条bom信息作为bomCode + DdlPackBean bomCodePackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(partNo, MesExtConstWords.PART_NO, bomCodePackBean); + DdlPreparedPack.getStringSmallerPack(effectiveTime, MesExtConstWords.EFF_START_TIME, bomCodePackBean); + if (isWithEffEndTime) DdlPreparedPack.getStringBiggerPack(effectiveTime, MesExtConstWords.EFF_END_TIME, bomCodePackBean); + DdlPreparedPack.getOrderBy(MesExtConstWords.EFF_START_TIME, CommonEnumUtil.ASC_OR_DESC.DESC.getValue(), bomCodePackBean); + List bomList = bomRao.findByHqlTopWhere(bomCodePackBean, 1); + if (bomList == null || bomList.isEmpty()) { + return new ArrayList<>(); + } + mesBom = bomList.get(0); + } + List bomResultList = new ArrayList<>(); + DdlPackBean bomPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(mesBom.getBomCode(), "bomCode", bomPackBean); + DdlPreparedPack.getStringEqualPack(partNo, MesExtConstWords.PART_NO, bomPackBean); + DdlPreparedPack.getStringEqualPack(mesBom.getEffStartTime(), MesExtConstWords.EFF_START_TIME, bomPackBean); + List bomList = bomRao.findByHqlWhere(bomPackBean); + + for (MesBom bom : bomList) { + if (bom.getPartType() != null && bom.getPartType().equalsIgnoreCase("X")) { + getPlatBom(null,bom.getItemPartNo(), effectiveTime, organizeCode); + } else { + bom.setBomCode(bom.getBomCode().toLowerCase()); + bomResultList.add(bom); + } + + } + + return bomResultList; + } + private void checkData(List mesWorkOrderList, String organizeCode) { MesWorkOrder next = mesWorkOrderList.iterator().next(); String nowDate = TimeTool.getNowTime(true);