Merge branch 'uat-temp-nht-2506240000-step-feeding' into uat-temp-nht-2506120000-jialiao

uat-temp-nht-2506120000-jialiao
jason 4 weeks ago
commit f51eb189e3

@ -131,4 +131,10 @@ public interface IMesProductionCustomContextStepService {
@ApiOperation(value = "根据noCalcOrderQty判断维度处理处理工单完成数上下文[保存]")
MesWorkOrderCompleteQtyContext dispatchWorkOrderCompleteQtyContext(StationRequestBean reqBean, Boolean noCalcOrderQty, String workOrderNo, Double calcCompleteQty);
@ApiOperation(value = "可扣减条码的缓存key")
String getContainerSnAtomicityKey(String organizeCode, MesContainerPackageDetailContext context);
@ApiOperation(value = "将可扣减的条码通过原子性的方式写到缓存, 并获取最新的实际库存")
void dispatchContainerSnAtomicity(String organizeCode, List<MesContainerPackageDetailContext> containerSnStationList);
}

@ -5,6 +5,7 @@ import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesWorkOrderCutDetailModel;
import cn.estsh.i3plus.pojo.mes.bean.MesPart;
import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPush;
import cn.estsh.i3plus.pojo.mes.bean.MesRawPartCharging;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingQueue;
import cn.estsh.i3plus.pojo.mes.model.StationKvBean;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
@ -258,4 +259,27 @@ public interface IMesProductionDispatchContextStepService {
@ApiOperation(value = "保存上下文推单队列信息")
Boolean dispatchSortQueuePushContext(StationRequestBean reqBean, List<MesQueueOrderPush> queueOrderPushList);
@ApiOperation(value = "获取弹框输入的工单数量")
Double getOrderQtyDialogContext(StationRequestBean reqBean);
@ApiOperation(value = "保存弹框输入的工单数量")
void dispatchOrderQtyDialogContext(StationRequestBean reqBean, String orderQty);
@ApiOperation(value = "获取站点用于缺料时进行上料绑定")
List<MesStation> getMatchStationContext(StationRequestBean reqBean);
@ApiOperation(value = "保存站点用于缺料时进行上料绑定")
void dispatchMatchStationContext(StationRequestBean reqBean, List<MesStation> stationList);
@ApiOperation(value = "获取站点用于缺料时进行上料扫描的条码")
String getMatchStationFeedScanSnContext(StationRequestBean reqBean);
@ApiOperation(value = "保存站点用于缺料时进行上料扫描的条码")
void dispatchMatchStationFeedScanSnContext(StationRequestBean reqBean, String sn);
@ApiOperation(value = "获取站点用于缺料时进行上料绑定的容器条码")
String getMatchStationFeedContainerSnContext(StationRequestBean reqBean);
@ApiOperation(value = "保存站点用于缺料时进行上料绑定的容器条码")
void dispatchMatchStationFeedContainerSnContext(StationRequestBean reqBean, String sn);
}

@ -179,4 +179,10 @@ public interface IMesProductionProcessContextStepService {
@ApiOperation(value = "处理切换发运RFID生产模式的标志")
Boolean disPatchChooseShippingRfidRouteMode(StationRequestBean reqBean);
@ApiOperation(value = "处理设备站点")
List<MesStation> dispatchEquipmentStationContext(StationRequestBean reqBean, String equipmentCode);
@ApiOperation(value = "处理设备站点")
List<MesStation> dispatchEquipmentStationContext(StationRequestBean reqBean, String equipmentCode, List<Integer> stationTypeList);
}

@ -0,0 +1,45 @@
package cn.estsh.i3plus.ext.mes.pcn.api.busi;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackage;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackageDetail;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerSnStation;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import java.util.Map;
public interface IMesStationContainerSnExtService {
@ApiOperation(value = "根据设备代码查询站点信息")
List<MesStation> getStationList(String organizeCode, String equipmentCode);
@ApiOperation(value = "获取站点关联的容器条码")
Map<String, List<MesContainerSnStation>> getContainerSnStationMap(String organizeCode, List<MesStation> stationList);
@ApiOperation(value = "获取站点关联的容器条码")
List<MesContainerSnStation> getContainerSnStationList(String organizeCode, List<MesStation> stationList);
@ApiOperation(value = "获取站点关联的容器条码")
List<MesContainerSnStation> getContainerSnStationListByStation(String organizeCode, List<String> stationList);
@ApiOperation(value = "获取容器条码上料明细表信息【可扣减】【根据 主表seq,主表createDatetime,明细表createDatetime 正序】")
List<MesContainerPackageDetailContext> getContainerSnStationContext(String organizeCode, List<MesStation> stationList);
@ApiOperation(value = "获取容器条码上料主表信息")
List<MesContainerPackage> getContainerPackageList(String organizeCode, List<MesContainerSnStation> containerSnStationList, Integer packageStatus);
@ApiOperation(value = "获取容器条码上料主表信息")
List<MesContainerPackage> getContainerPackageListByContainerSn(String organizeCode, List<String> containerSnList, Integer packageStatus);
@ApiOperation(value = "获取容器条码上料明细表信息【可扣减】")
List<MesContainerPackageDetail> getContainerPackageDetailList(String organizeCode, List<MesContainerPackage> containerPackageList);
@ApiOperation(value = "获取容器条码上料明细表信息【可扣减】")
List<MesContainerPackageDetail> getContainerPackageDetailListById(String organizeCode, List<Long> idList);
@ApiOperation(value = "获取容器条码的一条上料明细表信息【可扣减】")
Boolean checkIsExistContainerPackageDetail(String organizeCode, Long id);
}

@ -1,5 +1,6 @@
package cn.estsh.i3plus.ext.mes.pcn.api.busi;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import io.swagger.annotations.ApiOperation;
import java.util.Map;
@ -21,4 +22,7 @@ public interface IMesTimeEfficientCfgMatchService {
@ApiOperation(value = "时效性匹配")
Map<String, Object> checkSnTimeliness(String organizeCode, String productSn, Long sourceId, Integer dataSource);
@ApiOperation(value = "时效性匹配[容器条码]")
Map<String, Object> checkSnTimelinessContainerMatch(String organizeCode, MesContainerPackageDetailContext containerPackageDetailContext, Long sourceId);
}

@ -0,0 +1,160 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesStationContainerSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackage;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackageDetail;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerSnStation;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerPackageDetailRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerPackageRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerSnStationRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesStationRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
*
*/
@Service
public class MesStationContainerSnExtService implements IMesStationContainerSnExtService {
@Autowired
private MesStationRepository stationRepository;
@Autowired
private MesContainerSnStationRepository containerSnStationRepository;
@Autowired
private MesContainerPackageRepository containerPackageRepository;
@Autowired
private MesContainerPackageDetailRepository containerPackageDetailRepository;
//根据设备代码查询站点信息
@Override
public List<MesStation> getStationList(String organizeCode, String equipmentCode) {
if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(equipmentCode)) return null;
return stationRepository.findByProperty(
new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.EQUIPMENT_CODE},
new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), equipmentCode});
}
//获取站点关联的容器条码
@Override
public Map<String, List<MesContainerSnStation>> getContainerSnStationMap(String organizeCode, List<MesStation> stationList) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(stationList)) return null;
List<MesContainerSnStation> containerSnStationList = getContainerSnStationList(organizeCode, stationList);
return CollectionUtils.isEmpty(containerSnStationList) ? null :
containerSnStationList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesContainerSnStation::getContainerSn));
}
//获取站点关联的容器条码
@Override
public List<MesContainerSnStation> getContainerSnStationList(String organizeCode, List<MesStation> stationList) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(stationList)) return null;
List<String> stations = stationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getStation()))).map(MesStation::getStation).collect(Collectors.toList());
return getContainerSnStationListByStation(organizeCode, stations);
}
//获取站点关联的容器条码
@Override
public List<MesContainerSnStation> getContainerSnStationListByStation(String organizeCode, List<String> stationList) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(stationList)) return null;
DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
if (stationList.size() == 1) DdlPreparedPack.getStringEqualPack(stationList.get(0), MesPcnExtConstWords.STATION, packBean);
else DdlPreparedPack.getInPackList(stationList, MesPcnExtConstWords.STATION, packBean);
return containerSnStationRepository.findByHqlWhere(packBean);
}
//获取容器条码上料明细表信息【可扣减】【根据 主表seq,主表createDatetime,明细表createDatetime 正序】
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public List<MesContainerPackageDetailContext> getContainerSnStationContext(String organizeCode, List<MesStation> stationList) {
//获取站点关联的容器条码, key = containerSn
Map<String, List<MesContainerSnStation>> containerSnStationMap = getContainerSnStationMap(organizeCode, stationList);
if (CollectionUtils.isEmpty(containerSnStationMap)) return null;
//获取容器条码上料主表信息【已关箱】
List<MesContainerPackage> containerPackageList = getContainerPackageListByContainerSn(organizeCode,
new ArrayList<>(containerSnStationMap.keySet()), MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue());
if (CollectionUtils.isEmpty(containerPackageList)) return null;
//获取容器条码上料明细表信息
List<MesContainerPackageDetail> containerPackageDetailList = getContainerPackageDetailList(organizeCode, containerPackageList);
if (CollectionUtils.isEmpty(containerPackageDetailList)) return null;
//封装容器条码对应的【可扣减】的上料明细表信息
List<MesContainerPackageDetailContext> containerSnStationContextList = new ArrayList<>();
for (MesContainerPackageDetail containerPackageDetail : containerPackageDetailList) {
if (null == containerPackageDetail) continue;
MesContainerSnStation containerSnStation = containerSnStationMap.get(containerPackageDetail.getContainerSn()).get(0);
containerSnStationContextList.add(new MesContainerPackageDetailContext(containerPackageDetail).station(containerSnStation));
}
//根据 主表seq,主表createDatetime,明细表createDatetime 正序
containerSnStationContextList = containerSnStationContextList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesContainerPackageDetailContext::getSeq)
.thenComparing(MesContainerPackageDetailContext::getCreateDatetime2Package).thenComparing(MesContainerPackageDetailContext::getCreateDatetime)).collect(Collectors.toList());
return containerSnStationContextList;
}
//获取容器条码上料主表信息
@Override
public List<MesContainerPackage> getContainerPackageList(String organizeCode, List<MesContainerSnStation> containerSnStationList, Integer packageStatus) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(containerSnStationList)) return null;
List<String> containerSnList = containerSnStationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getContainerSn()))).map(MesContainerSnStation::getContainerSn).collect(Collectors.toList());
return getContainerPackageListByContainerSn(organizeCode, containerSnList, packageStatus);
}
//获取容器条码上料主表信息
@Override
public List<MesContainerPackage> getContainerPackageListByContainerSn(String organizeCode, List<String> containerSnList, Integer packageStatus) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(containerSnList)) return null;
DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
if (containerSnList.size() == 1) DdlPreparedPack.getStringEqualPack(containerSnList.get(0), MesPcnExtConstWords.CONTAINER_SN, packBean);
else DdlPreparedPack.getInPackList(containerSnList, MesPcnExtConstWords.STATION, packBean);
DdlPreparedPack.getNumEqualPack(packageStatus, MesPcnExtConstWords.PACKAGE_STATUS, packBean);
return containerPackageRepository.findByHqlWhere(packBean);
}
//获取容器条码上料明细表信息【可扣减】
@Override
public List<MesContainerPackageDetail> getContainerPackageDetailList(String organizeCode, List<MesContainerPackage> containerPackageList) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(containerPackageList)) return null;
List<Long> idList = containerPackageList.stream().filter(o -> null != o).map(MesContainerPackage::getId).collect(Collectors.toList());
return getContainerPackageDetailListById(organizeCode, idList);
}
//获取容器条码上料明细表信息【可扣减】
@Override
public List<MesContainerPackageDetail> getContainerPackageDetailListById(String organizeCode, List<Long> idList) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(idList)) return null;
DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
if (idList.size() == 1) DdlPreparedPack.getNumEqualPack(idList.get(0), MesPcnExtConstWords.PID, packBean);
else DdlPreparedPack.getInPackList(idList, MesPcnExtConstWords.PID, packBean);
DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.CONTAINER_BARCODE_STATUS.STATUS_10.getValue(), MesPcnExtConstWords.SN_STATUS, packBean);
return containerPackageDetailRepository.findByHqlWhere(packBean);
}
//获取容器条码的一条上料明细表信息【可扣减】
@Override
public Boolean checkIsExistContainerPackageDetail(String organizeCode, Long id) {
if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(id)) return null;
DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
DdlPreparedPack.getNumEqualPack(id, MesPcnExtConstWords.PID, packBean);
DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.CONTAINER_BARCODE_STATUS.STATUS_10.getValue(), MesPcnExtConstWords.SN_STATUS, packBean);
return containerPackageDetailRepository.isExitByHql(packBean);
}
}

@ -4,6 +4,7 @@ import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProduceSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionRecordService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesTimeEfficientCfgMatchService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesTimeEfficientCfgService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.pojo.mes.bean.MesProduceSn;
import cn.estsh.i3plus.pojo.mes.bean.MesProductionRecord;
@ -209,4 +210,36 @@ public class MesTimeEfficientCfgMatchService implements IMesTimeEfficientCfgMatc
}
}
@Override
public Map<String, Object> checkSnTimelinessContainerMatch(String organizeCode, MesContainerPackageDetailContext containerPackageDetailContext, Long sourceId) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put(MesPcnExtConstWords.RESULT, true);//校验成功
try {
//1.根据prodRuleNoSortId 获取 非排序加工规则的 时效性数据 --- 当前的条码需要完全匹配查询的规则
List<MesTimeEfficientCfg> timelinessList = timeEfficientCfgService.getTimeEfficientCfgList(organizeCode, sourceId);
//2.如果timelinessList为空 且 非装配件校验 直接返回true
if (CollectionUtils.isEmpty(timelinessList)) return resultMap;
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT);
for (MesTimeEfficientCfg timeliness : timelinessList) {
if (null == timeliness || StringUtils.isEmpty(timeliness.getPartNo()) || !timeliness.getPartNo().equals(containerPackageDetailContext.getPartNo())) continue;
Date productDateTime = sdf.parse(containerPackageDetailContext.getCreateDatetime());
//时差
int minDiff = (int) ((now.getTime() - productDateTime.getTime())/(60 * 1000));
if (!checkTimeliness(timeliness, minDiff)) return backResultMap(resultMap, String.format("原材料条码[%s]时效性零件号[%s]验证失败!", containerPackageDetailContext.getBarCode(), timeliness.getPartNo()));
}
return resultMap;
} catch (Exception e) {
return backResultMap(resultMap, String.format("原材料条码[%s]时效性验证异常:%s!", containerPackageDetailContext.getBarCode(), e.toString()));
}
}
}

@ -288,7 +288,7 @@ public class MesAssemblyMatchSortStepService extends BaseStepService {
//时效性验证
if (!StringUtils.isEmpty(filter.getProductSnId())) {
result = timeEfficientCfgMatchService.checkSnTimeliness(reqBean.getOrganizeCode(), equipVariableCollectContext.getEquipVariableValue(), filter.getSourceId(), MesExtEnumUtil.TIME_DATA_SOURCE.DATA_SOURCE10.getValue());
result = timeEfficientCfgMatchService.checkSnTimeliness(reqBean.getOrganizeCode(), equipVariableCollectContext.getEquipVariableValue(), filter.getPid(), MesExtEnumUtil.TIME_DATA_SOURCE.DATA_SOURCE10.getValue());
if (!(Boolean)result.get(MesPcnExtConstWords.RESULT)) {
stepResult.msg(String.format("%s%s", StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg(), result.get(MesPcnExtConstWords.MESSAGE)));

@ -0,0 +1,135 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesContainerSnBindService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesContainerPartsModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesContainerSnBindModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.platform.common.util.MesConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerPackageRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerSnPartRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerSnStationRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerTypePartRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.*;
/**
* @Description :
* @Author : jason.niu
**/
@Slf4j
@Service("mesStationFeedContainerPackageDetailStepService")
public class MesStationFeedContainerPackageDetailStepService extends BaseStepService {
@Autowired
private IMesProductionProcessContextStepService productionProcessContextStepService;
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Autowired
private MesContainerSnStationRepository containerSnStationRDao;
@Autowired
private MesContainerTypePartRepository containerTypePartRDao;
@Autowired
private MesContainerSnPartRepository containerSnPartRDao;
@Autowired
private IMesContainerSnBindService containerSnBindService;
@Autowired
private MesContainerPackageRepository containerPackageRDao;
@Override
public StepResult execute(StationRequestBean reqBean) {
StationResultBean resultBean = new StationResultBean();
StepResult stepResult = StepResult.getSuccessComplete();
//获取工位当前设备信息
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);
//配置错误 抛出异常
if (!productionProcessContext.getSuccess()) {
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
}
//获取站点用于缺料时进行上料绑定
List<MesStation> stationList = productionDispatchContextStepService.getMatchStationContext(reqBean);
if (CollectionUtils.isEmpty(stationList)) {
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "容器条码扣减装配件时验证设备未关联支持上料的站点");
}
final String organizeCode = reqBean.getOrganizeCode();
String barcode = productionDispatchContextStepService.getMatchStationFeedScanSnContext(reqBean);
final String lastFeedContainerSn = productionDispatchContextStepService.getMatchStationFeedContainerSnContext(reqBean);
if (!StringUtils.isEmpty(lastFeedContainerSn)) {
if (executeFeedPartSn(reqBean, lastFeedContainerSn, barcode)) {
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "零件条码上料成功!");
}
}
for (MesStation station : stationList) {
List<MesContainerSnStation> containerSnStations = getMesContainerSnStation(organizeCode, station.getStation());
if (CollectionUtils.isEmpty(containerSnStations)) {
continue;
}
for (MesContainerSnStation containerSnStation : containerSnStations) {
final String feedContainerSn = containerSnStation.getTopContainerSn();
if (Objects.equals(feedContainerSn, lastFeedContainerSn)) {
continue;
}
if (executeFeedPartSn(reqBean, feedContainerSn, barcode)) {
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "零件条码上料成功!");
}
}
}
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "零件条码上料成功!");
}
private List<MesContainerSnStation> getMesContainerSnStation(String organizeCode, String station) {
List<MesContainerSnStation> containerSnStations = containerSnStationRDao.findByProperty(new String[]{MesConstWords.ORGANIZE_CODE, MesConstWords.IS_VALID, MesConstWords.IS_DELETED, "station"},
new Object[]{organizeCode, CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), station});
containerSnStations.removeIf(temp -> !Objects.equals(temp.getContainerSn(), temp.getTopContainerSn()));
return containerSnStations;
}
private boolean executeFeedPartSn(StationRequestBean reqBean, String containerSn, String barcode) {
final String organizeCode = reqBean.getOrganizeCode();
MesContainerSnBindModel model = MesContainerSnBindModel.builder()
.organizeCode(organizeCode)
.userName(reqBean.getUserInfo())
.containerSn(containerSn)
.barCode(barcode)
.build();
try {
containerSnBindService.doScanBarcode(model);
final String lastFeedContainerSn = hasFullPackage(organizeCode, containerSn) ? "" : containerSn;
//加料后容器还未满,保存最近使用的站点
productionDispatchContextStepService.dispatchMatchStationFeedContainerSnContext(reqBean, lastFeedContainerSn);
} catch (Exception ignored) {
return false;
}
return true;
}
private boolean hasFullPackage(String organizeCode, String containerSn) {
MesContainerPackage containerPackage = containerPackageRDao.getByProperty(new String[]{MesConstWords.ORGANIZE_CODE, MesConstWords.IS_VALID, MesConstWords.IS_DELETED, "containerSn"},
new Object[]{organizeCode, CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), containerSn});
return containerPackage != null && Objects.equals(containerPackage.getPackageStatus(), MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue());
}
}

@ -0,0 +1,123 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.platform.common.util.MesConstWords;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackage;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackageDetail;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerSnStation;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerPackageDetailRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerPackageRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerSnStationRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
/**
* @Description :
* @Author : jason.niu
**/
@Slf4j
@Service("mesStationFeedContainerSnStepService")
public class MesStationFeedContainerSnStepService extends BaseStepService {
@Autowired
private MesContainerSnStationRepository mesContainerSnStationRepository;
@Autowired
private MesContainerPackageRepository containerPackageRDao;
@Autowired
private MesContainerPackageDetailRepository packageDetailRDao;
@Autowired
private IMesProductionProcessContextStepService productionProcessContextStepService;
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Override
public StepResult execute(StationRequestBean reqBean) {
StationResultBean resultBean = new StationResultBean();
StepResult stepResult = StepResult.getSuccessComplete();
//获取工位当前设备信息
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);
//配置错误 抛出异常
if (!productionProcessContext.getSuccess()) {
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
}
//获取站点用于缺料时进行上料绑定
List<MesStation> stationList = productionDispatchContextStepService.getMatchStationContext(reqBean);
if (CollectionUtils.isEmpty(stationList)) {
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "容器条码扣减装配件时验证设备未关联支持上料的站点");
}
MesStation station = null;
MesStation mixStation = null;
for (MesStation st : stationList) {
if (Objects.equals(st.getStationType(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getValue()) ||
Objects.equals(st.getStationType(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_20.getValue())) {
station = st;
break;
}
if (mixStation == null && Objects.equals(st.getStationType(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue())) {
mixStation = st;
}
}
if (station == null) {
station = mixStation;
}
if (station == null) {
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "不存在站点类型为【原料站点】、【装配件站点】、【混料站点】的站点信息!");
}
String containerSn = productionDispatchContextStepService.getMatchStationFeedScanSnContext(reqBean);
final String organizeCode = reqBean.getOrganizeCode();
String topContainerSn = getTopContainerSn(organizeCode, containerSn);
if (!topContainerSn.equals(containerSn)) {
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("此容器已绑定容器条码【%s】请扫描容器条码【%s】!", containerSn, topContainerSn));
}
//校验容器条码的唯一性
DdlPackBean containerSnStationDdlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
DdlPreparedPack.getStringEqualPack(containerSn, "topContainerSn", containerSnStationDdlPackBean);
MesContainerSnStation containerSnStation = mesContainerSnStationRepository.getByProperty(containerSnStationDdlPackBean);
if (containerSnStation != null) {
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("容器条码【%s】已绑定站点【%s】!", containerSn, containerSnStation.getStation()));
}
checkContainerPackage(reqBean, resultBean, organizeCode, containerSn);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "容器条码扣减装配件验证成功!");
}
private void checkContainerPackage(StationRequestBean reqBean, StationResultBean resultBean, String organizeCode, String containerSn) {
MesContainerPackage containerPackage = containerPackageRDao.getByProperty(new String[]{MesConstWords.ORGANIZE_CODE, MesConstWords.IS_VALID, MesConstWords.IS_DELETED, "containerSn"},
new Object[]{organizeCode, CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), containerSn});
if (containerPackage == null) {
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("容器条码【%s】未绑定零件!", containerSn));
}
assert containerPackage != null;
if (!Objects.equals(containerPackage.getPackageStatus(), MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue())) {
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("容器条码【%s】未关箱!", containerSn));
}
}
private String getTopContainerSn(String organizeCode, String containerSn) {
MesContainerPackageDetail packageDetail = packageDetailRDao.getByProperty(new String[]{MesConstWords.ORGANIZE_CODE, MesConstWords.IS_VALID, MesConstWords.IS_DELETED, "barCode"},
new Object[]{organizeCode, CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), containerSn});
if (packageDetail != null) {
return getTopContainerSn(organizeCode, packageDetail.getContainerSn());
}
return containerSn;
}
}

@ -0,0 +1,86 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesConfigService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.util.MesConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesConfig;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackage;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.i3plus.pojo.mes.repository.MesContainerPackageRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Objects;
/**
* @Description : //
* @Author : jason.niu
**/
@Slf4j
@Service("mesStationFeedScanSnStepService")
public class MesStationFeedScanSnStepService extends BaseStepService {
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Autowired
private IMesProductionCustomContextStepService productionCustomContextStepService;
@Autowired
private IMesConfigService configService;
@Autowired
private MesContainerPackageRepository containerPackageRDao;
@Override
public StepResult guide(StationRequestBean reqBean) {
productionCustomContextStepService.sendStepContextMessage(reqBean);
return stepSuccessCompleteAndSendGuideReturn(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描上料条码!");
}
@Override
public StepResult execute(StationRequestBean reqBean) {
StationResultBean resultBean = new StationResultBean();
StepResult stepResult = StepResult.getSuccessComplete();
//扫描信息置空
String scanInfo = reqBean.resetScanInfo(reqBean.getScanInfo());
if (StringUtils.isEmpty(scanInfo)) stepSendGuideAndThrowEx(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描装配件条码!");
// 判断是否为关箱条码
MesConfig mesConfig = configService.getCfgValueByCode(reqBean.getOrganizeCode(), MesPcnExtConstWords.MATCH_STATION_FEED_CLOSE_PACKAGE);
if (mesConfig != null && Objects.equals(scanInfo, mesConfig.getCfgValue())) {
String containerSn = productionDispatchContextStepService.getMatchStationFeedContainerSnContext(reqBean);
if (StringUtils.isEmpty(containerSn)) {
stepSendGuideAndThrowEx(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "不存在需要关箱的容器条码!");
}
MesContainerPackage containerPackage = containerPackageRDao.getByProperty(new String[]{MesConstWords.ORGANIZE_CODE, MesConstWords.IS_VALID, MesConstWords.IS_DELETED, "containerSn"},
new Object[]{reqBean.getOrganizeCode(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), containerSn});
if (containerPackage == null) {
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("容器条码【%s】未绑定零件!", containerSn));
}
assert containerPackage != null;
containerPackage.setPackageStatus(MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue());
ConvertBean.serviceModelUpdate(containerPackage, reqBean.getUserInfo());
containerPackageRDao.update(containerPackage);
}
//保存扫描条码用于缺料时进行上料绑定
productionDispatchContextStepService.dispatchMatchStationFeedScanSnContext(reqBean, scanInfo);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.SCAN.getValue()).scanInfo(scanInfo), stepResult,
String.format("当前扫描信息装配件条码[%s]", scanInfo));
}
}

@ -0,0 +1,195 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionAssemblyContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Description :
* @Author : wangjie
**/
@Slf4j
@Service("mesStationMatchAssemblyStepService")
public class MesStationMatchAssemblyStepService extends BaseStepService {
@Autowired
private IMesProductionProcessContextStepService productionProcessContextStepService;
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Autowired
private IMesProductionCustomContextStepService productionCustomContextStepService;
@Autowired
private IMesStationContainerSnExtService stationContainerSnExtService;
@Autowired
private IMesTimeEfficientCfgMatchService timeEfficientCfgMatchService;
@Autowired
private MesAssemblyShowNosortStepService assemblyShowNosortStepService;
@Override
public StepResult execute(StationRequestBean reqBean) {
StationResultBean resultBean = new StationResultBean();
StepResult stepResult = StepResult.getSuccessComplete();
//获取工位当前设备信息
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);
//配置错误 抛出异常
if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());
//获取上下文产品加工规则数据信息集合
List<MesProdRuleContext> prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean);
if (CollectionUtils.isEmpty(prodRuleContextList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "当前不存在产品加工规则信息,请重置工序解决!");
//验证是否存在装配件容器匹配
Optional<MesProdRuleContext> optional = prodRuleContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getIsMatchContainer()))).findFirst();
if (null == optional || !optional.isPresent()) {
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true,
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "验证每腔不存在容器匹配的装配件,默认跳过容器条码扣减装配件!");
}
//处理设备站点【装配件站点&&混料站点】
List<MesStation> stationList = productionProcessContextStepService.dispatchEquipmentStationContext(reqBean, productionProcessContext.getCurCellEquip().getEquipmentCode(),
Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_20.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList()));
if (CollectionUtils.isEmpty(stationList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "容器条码扣减装配件时验证设备未关联支持扣减的站点");
//保存站点用于缺料时进行上料绑定
productionDispatchContextStepService.dispatchMatchStationContext(reqBean, stationList);
//获取容器条码上料明细表信息【可扣减】【根据 主表seq,主表createDatetime,明细表createDatetime 正序】
List<MesContainerPackageDetailContext> containerSnStationList = stationContainerSnExtService.getContainerSnStationContext(reqBean.getOrganizeCode(), stationList);
if (CollectionUtils.isEmpty(containerSnStationList)) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "容器条码扣减装配件时验证当前无可扣减的原材料信息!");
//将可扣减的条码进行原子性缓存, 并获取最新的实际库存
productionCustomContextStepService.dispatchContainerSnAtomicity(reqBean.getOrganizeCode(), containerSnStationList);
//获取弹框输入的工单数量, 未弹框默认 数量=1
Double orderQtyDialogContext = productionDispatchContextStepService.getOrderQtyDialogContext(reqBean);
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
//匹配装配件的工序用量
dispatchStationMatchAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContextList, containerSnStationList, orderQtyDialogContext);
if (!stepResult.isCompleted()) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, stepResult.getMsg());
productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList);
if (workCenter.getCenterType().compareTo(MesExtEnumUtil.WORK_CENTER_TYPE.NOSORT.getValue()) == 0)
((MesAssemblyShowNosortStepService) SpringContextsUtil.getBean("mesAssemblyShowNosortStepService")).showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList);
else
((MesAssemblyShowSortStepService) SpringContextsUtil.getBean("mesAssemblyShowSortStepService")).showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList, true, true);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "容器条码扣减装配件验证成功!");
}
//匹配装配件的工序用量【遍历加工规则】
private void dispatchStationMatchAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter,
List<MesProdRuleContext> prodRuleContextList, List<MesContainerPackageDetailContext> containerSnStationList, Double orderQtyDialogContext) {
for (MesProdRuleContext prodRuleContext : prodRuleContextList) {
if (null == prodRuleContext || StringUtils.isEmpty(prodRuleContext.getIsMatchContainer())) continue;
List<MesProductionAssemblyContext> productionAssemblyContextList = dispatchStationMatchAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContext, containerSnStationList, orderQtyDialogContext);
if (!stepResult.isCompleted()) break;
prodRuleContext.assemblyDataJson(productionAssemblyContextList);
}
}
//匹配装配件的工序用量【遍历装配件】
private List<MesProductionAssemblyContext> dispatchStationMatchAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter,
MesProdRuleContext prodRuleContext, List<MesContainerPackageDetailContext> containerSnStationList, Double orderQtyDialogContext) {
List<MesProductionAssemblyContext> productionAssemblyContextList = prodRuleContext.getAssemblyDataContext(workCenter);
for (MesProductionAssemblyContext productionAssemblyContext : productionAssemblyContextList) {
if (null == productionAssemblyContext || productionAssemblyContext.getMatchType().compareTo(MesExtEnumUtil.ASSEMBLY_MATCH_TYPE.MATCH_TYPE_80.getValue()) != 0) continue;
if (StringUtils.isEmpty(productionAssemblyContext.getPartNo()) || StringUtils.isEmpty(productionAssemblyContext.getQty()))
stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("当前产成对应的[%s]类型的装配件信息维护零件号或工序用量!", MesExtEnumUtil.ASSEMBLY_MATCH_TYPE.MATCH_TYPE_80.getDescription()));
//未匹配的工序用量
Double unMatchQty = MathOperation.mul(productionAssemblyContext.getQty(), orderQtyDialogContext);
List<String> containerSnDataList = null;
List<String> containerSnList = null;
for (MesContainerPackageDetailContext containerPackageDetailContext : containerSnStationList) {
if (null == containerPackageDetailContext || StringUtils.isEmpty(containerPackageDetailContext.getPartNo())) continue;
if (!containerPackageDetailContext.getPartNo().equals(productionAssemblyContext.getPartNo()) || MathOperation.compareTo(containerPackageDetailContext.getRemainQty(), new Double(0)) <= 0) continue;
//验证时效性
Map<String, Object> result = timeEfficientCfgMatchService.checkSnTimelinessContainerMatch(reqBean.getOrganizeCode(), containerPackageDetailContext,
workCenter.getCenterType().compareTo(MesExtEnumUtil.WORK_CENTER_TYPE.NOSORT.getValue()) == 0 ? productionAssemblyContext.getSourceId() : productionAssemblyContext.getPid());
if (!(Boolean)result.get(MesPcnExtConstWords.RESULT)) continue;
//如果存在未匹配的工序用量
if (MathOperation.compareTo(unMatchQty, new Double(0)) > 0) {
//剩余未匹配的工序用量
Double remainQty = MathOperation.sub(containerPackageDetailContext.getRemainQty(), unMatchQty);
//全部匹配完成
if (MathOperation.compareTo(remainQty, new Double(0)) >= 0) {
containerPackageDetailContext.remainQty(remainQty);
unMatchQty = new Double(0);
} else {
//未匹配完成, 0-负数=正数
containerPackageDetailContext.remainQty(new Double(0));
unMatchQty = MathOperation.sub(new Double(0), remainQty);
}
}
//将能够扣减的所有条码跟当前装配件关联
if (CollectionUtils.isEmpty(containerSnDataList)) {
containerSnDataList = new ArrayList<>();
containerSnList = new ArrayList<>();
}
containerSnDataList.add(productionCustomContextStepService.getContainerSnAtomicityKey(reqBean.getOrganizeCode(), containerPackageDetailContext));
containerSnList.add(containerPackageDetailContext.getContainerSn());
}
if (MathOperation.compareTo(unMatchQty, new Double(0)) > 0) {
if (!StringUtils.isEmpty(productionAssemblyContext.getAssemblySn())) {
productionAssemblyContext.setAssemblyStatus(MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_30.getValue());
productionAssemblyContext.setAssemblySn(null);
productionAssemblyContext.setMatchDatetime(null);
}
stepResult.isCompleted(false).msg(String.format("容器条码扣减装配件时验证零件号[%s]当前缺料,请扫描上料条码!", productionAssemblyContext.getPartNo()));
break;
}
productionAssemblyContext.setAssemblyStatus(MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_10.getValue());
productionAssemblyContext.setAssemblySn(containerSnList.get(0));
productionAssemblyContext.setMatchDatetime((new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT_SSS)).format(new Date()));
productionAssemblyContext.setContainerSnData(JSONObject.toJSONString(containerSnDataList));
}
return productionAssemblyContextList;
}
}

@ -396,4 +396,26 @@ public class MesProductionCustomContextStepService extends BaseStepService imple
return workOrderCompleteQtyContext;
}
@Override
public String getContainerSnAtomicityKey(String organizeCode, MesContainerPackageDetailContext context) {
return new StringJoiner(MesPcnExtConstWords.COLON)
.add(organizeCode)
.add(MesPcnExtConstWords.CONTAINER_SN_REMAIN_CONTEXT)
.add(context.getStation())
.add(new StringJoiner(MesPcnExtConstWords.AND).add(context.getContainerSn()).add(context.getId().toString()).toString())
.toString();
}
//将可扣减的条码通过原子性的方式写到缓存, 并获取最新的实际库存
@Override
public void dispatchContainerSnAtomicity(String organizeCode, List<MesContainerPackageDetailContext> containerSnStationList) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(containerSnStationList)) return;
// containerSnStationList.stream().forEach(o -> {
// String key = getContainerSnAtomicityKey(organizeCode, o);
// Boolean success = dispatchFsmBusiDataAtomicity(organizeCode, key, o.getQty().toString(), MesPcnEnumUtil.EXPIRE_TIME.DEFAULT.getValue());
// if (success) o.remainQty(o.getQty());
// else o.remainQty(getFsmBusiData(organizeCode, key));
// });
}
}

@ -9,6 +9,7 @@ import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesPart;
import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPush;
import cn.estsh.i3plus.pojo.mes.bean.MesRawPartCharging;
import cn.estsh.i3plus.pojo.mes.bean.MesStation;
import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingQueue;
import cn.estsh.i3plus.pojo.mes.model.StationKvBean;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
@ -588,4 +589,54 @@ public class MesProductionDispatchContextStepService extends BaseStepService imp
return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.QUEUE_PUSH_CONTEXT, JSONObject.toJSONString(queueOrderPushList));
}
//获取弹框输入的工单数量
@Override
public Double getOrderQtyDialogContext(StationRequestBean reqBean) {
String orderQty = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.ORDER_QTY_DIALOG_CONTEXT);
return StringUtils.isEmpty(orderQty) ? new Double(0) : new Double(orderQty);
}
//获取弹框输入的工单数量
@Override
public void dispatchOrderQtyDialogContext(StationRequestBean reqBean, String orderQty) {
dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.ORDER_QTY_DIALOG_CONTEXT, orderQty);
}
//获取站点用于缺料时进行上料绑定
@Override
public List<MesStation> getMatchStationContext(StationRequestBean reqBean) {
String stationContext = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_CONTEXT);
return StringUtils.isEmpty(stationContext) ? null : JSONObject.parseArray(stationContext, MesStation.class);
}
//保存站点用于缺料时进行上料绑定
@Override
public void dispatchMatchStationContext(StationRequestBean reqBean, List<MesStation> stationList) {
if (CollectionUtils.isEmpty(stationList)) return;
dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_CONTEXT, JSONObject.toJSONString(stationList));
}
//获取站点用于缺料时进行上料绑定
@Override
public String getMatchStationFeedScanSnContext(StationRequestBean reqBean) {
return getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_FEED_SCAN_SN_CONTEXT);
}
//保存站点用于缺料时进行上料绑定
@Override
public void dispatchMatchStationFeedScanSnContext(StationRequestBean reqBean, String sn) {
if (StringUtils.isEmpty(sn)) return;
dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_FEED_SCAN_SN_CONTEXT, sn);
}
@Override
public String getMatchStationFeedContainerSnContext(StationRequestBean reqBean) {
return getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_FEED_CONTAINER_SN_CONTEXT);
}
@Override
public void dispatchMatchStationFeedContainerSnContext(StationRequestBean reqBean, String sn) {
if (StringUtils.isEmpty(sn)) return;
dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_FEED_CONTAINER_SN_CONTEXT, sn);
}
}

@ -4,6 +4,7 @@ import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesEquipmentExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesProdOrgExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesQueueOrderPushService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesStationContainerSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.actor.shipping.dispatch.IFsmRouteDataService;
@ -55,6 +56,9 @@ public class MesProductionProcessContextStepService extends BaseStepService impl
@Autowired
private SnowflakeIdMaker snowflakeIdMaker;
@Autowired
private IMesStationContainerSnExtService stationContainerSnExtService;
private String getContextKey(StationRequestBean reqBean) {
return getFsmBusikey(reqBean, new StringJoiner(MesPcnExtConstWords.COLON).add(MesPcnExtConstWords.PRODUCTION_PROCESS_CONTEXT).add(MesPcnExtConstWords.BASE_DATA_CONTEXT).toString());
}
@ -687,4 +691,22 @@ public class MesProductionProcessContextStepService extends BaseStepService impl
return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.CHOOSE_SHIPPING_RFID_ROUTE_MODE, CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr());
}
//处理设备站点
@Override
public List<MesStation> dispatchEquipmentStationContext(StationRequestBean reqBean, String equipmentCode) {
String station = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.EQUIPMENT_STATION_CONTEXT);
if (!StringUtils.isEmpty(station)) return JSONObject.parseArray(station, MesStation.class);
List<MesStation> stationList = stationContainerSnExtService.getStationList(reqBean.getOrganizeCode(), equipmentCode);
if (!CollectionUtils.isEmpty(stationList)) dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.EQUIPMENT_STATION_CONTEXT, JSONObject.toJSONString(stationList));
return stationList;
}
//处理设备站点
@Override
public List<MesStation> dispatchEquipmentStationContext(StationRequestBean reqBean, String equipmentCode, List<Integer> stationTypeList) {
List<MesStation> stationList = dispatchEquipmentStationContext(reqBean, equipmentCode);
return CollectionUtils.isEmpty(stationList) ? null :
stationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getStationType()) && stationTypeList.contains(o.getStationType()))).collect(Collectors.toList());
}
}

@ -0,0 +1,55 @@
package cn.estsh.i3plus.ext.mes.pcn.pojo.context;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackageDetail;
import cn.estsh.i3plus.pojo.mes.bean.MesContainerSnStation;
import io.swagger.annotations.ApiParam;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;
import java.io.Serializable;
/**
* -
*/
@Data
public class MesContainerPackageDetailContext extends MesContainerPackageDetail implements Serializable {
private static final long serialVersionUID = 3519172978836073435L;
@ApiParam(name = "站点")
private String station;
@ApiParam("顺序号")
private Integer seq;
@ApiParam(value = "主表创建日期")
private String createDatetime2Package;
@ApiParam("库存")
private Double remainQty;
public MesContainerPackageDetailContext() {}
public MesContainerPackageDetailContext(MesContainerPackageDetail containerPackageDetail) {
BeanUtils.copyProperties(containerPackageDetail, this);
}
public MesContainerPackageDetailContext station(MesContainerSnStation containerSnStation) {
this.station = containerSnStation.getStation();
this.seq = !StringUtils.isEmpty(containerSnStation.getSeq()) ? containerSnStation.getSeq() : MesPcnExtConstWords.ZERO;
this.createDatetime2Package = containerSnStation.getCreateDatetime();
return this;
}
public MesContainerPackageDetailContext remainQty(String remainQty) {
return remainQty(!StringUtils.isEmpty(remainQty) ? new Double(remainQty) : new Double(MesPcnExtConstWords.ZERO));
}
public MesContainerPackageDetailContext remainQty(Double remainQty) {
this.remainQty = remainQty;
return this;
}
}

@ -1,5 +1,6 @@
package cn.estsh.i3plus.ext.mes.pcn.pojo.context;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesProdRuleNosortCfg;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
@ -14,6 +15,7 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
@ -117,6 +119,9 @@ public class MesProdRuleContext implements Serializable {
@ApiParam(name = "平行 工位/工艺顺序号")
private String parallelInfo;
@ApiParam(name = "是否存在装配件容器匹配")
private String isMatchContainer;
public MesProdRuleContext() {}
public MesProdRuleContext(String organizeCode) {
@ -226,7 +231,18 @@ public class MesProdRuleContext implements Serializable {
}
public MesProdRuleContext assemblyDataJson(List<? extends MesProductionAssemblyContext> productionAssemblyContextList) {
this.assemblyDataJson = !CollectionUtils.isEmpty(productionAssemblyContextList) ? JSONObject.toJSONString(productionAssemblyContextList) : null;
if (CollectionUtils.isEmpty(productionAssemblyContextList)) return this;
this.assemblyDataJson = JSONObject.toJSONString(productionAssemblyContextList);
isMatchContainer(productionAssemblyContextList);
return this;
}
//标记装配件是否需要进行匹配容器条码进行扣减
public MesProdRuleContext isMatchContainer(List<? extends MesProductionAssemblyContext> productionAssemblyContextList) {
if (CollectionUtils.isEmpty(productionAssemblyContextList)) return this;
Optional<MesProductionAssemblyContext> optional = (Optional<MesProductionAssemblyContext>) productionAssemblyContextList.stream()
.filter(o -> (null != o && !StringUtils.isEmpty(o.getMatchType()) && o.getMatchType().compareTo(MesExtEnumUtil.ASSEMBLY_MATCH_TYPE.MATCH_TYPE_80.getValue()) == 0)).findFirst();
if (null != optional && optional.isPresent()) this.isMatchContainer = CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr();
return this;
}

@ -127,6 +127,12 @@ public class MesProductionAssemblyContext implements Serializable {
@ApiParam("匹配时间")
public String matchDatetime;
@ApiParam(value = "工序用量")
public Double qty;
@ApiParam("容器匹配信息")
public String containerSnData;
public String repeatKeyToString() {
if (StringUtils.isEmpty(this.equipmentCode) || StringUtils.isEmpty(this.matchType) || (StringUtils.isEmpty(this.matchRule) && StringUtils.isEmpty(this.assemblyPartNo))) return null;
return String.format("%s:%s&%s:%s&%s:%s&%s:%s",

@ -33,9 +33,6 @@ public class MesProductionAssemblyNosortContext extends MesProductionAssemblyCon
@ApiParam(value = "是否忽略回车")
private Integer isIgnoreEntry;
@ApiParam(value = "工序用量")
private Double qty;
@ApiParam(name = "产成品图")
private String outPartNoPic;

@ -389,6 +389,12 @@ public class MesPcnExtConstWords {
public static final String ENUM_CODE = "enumCode";
//计划开始时间
public static final String PLAN_START_TIME = "planStartTime";
//站点名称
public static final String STATION = "station";
//容器条码
public static final String CONTAINER_SN = "containerSn";
//容器条码上料状态
public static final String PACKAGE_STATUS = "packageStatus";
//BaseBean字段不包含工厂, 用于对象复制剔除属性BeanUtils.copyProperties(Object source, Object target, String... ignoreProperties)
@ -685,6 +691,10 @@ public class MesPcnExtConstWords {
public static final String SHIPPING_RFID_ROUTE_MODE_CONTEXT = "SHIPPING_RFID_ROUTE_MODE_CONTEXT";
// 选择发运RFID生产模式
public static final String CHOOSE_SHIPPING_RFID_ROUTE_MODE = "CHOOSE_SHIPPING_RFID_ROUTE_MODE";
// 设备站点
public static final String EQUIPMENT_STATION_CONTEXT = "EQUIPMENT_STATION_CONTEXT";
// 容器条码扣减剩余上下文
public static final String CONTAINER_SN_REMAIN_CONTEXT = "CONTAINER_SN_REMAIN_CONTEXT";
// 上下文: 展示组件数据
public static final String MODULE_CONTENT_CONTEXT = "MODULE_CONTENT_CONTEXT";
@ -730,6 +740,16 @@ public class MesPcnExtConstWords {
public static final String PROD_TEMP_DATA_CONTEXT = "PROD_TEMP_DATA_CONTEXT";
// 上下文: 发运队列
public static final String SHIPPING_QUEUE_CONTEXT = "SHIPPING_QUEUE_CONTEXT";
// 上下文: 获取弹框输入的工单数量
public static final String ORDER_QTY_DIALOG_CONTEXT = "ORDER_QTY_DIALOG_CONTEXT";
// 用于缺料时进行上料绑定的站点
public static final String MATCH_STATION_CONTEXT = "MATCH_STATION_CONTEXT";
// 用于缺料时进行上料扫描上料条码
public static final String MATCH_STATION_FEED_SCAN_SN_CONTEXT = "MATCH_STATION_FEED_SCAN_SN_CONTEXT";
// 用于缺料时进行上料扫描上料绑定的容器条码
public static final String MATCH_STATION_FEED_CONTAINER_SN_CONTEXT = "MATCH_STATION_FEED_CONTAINER_SN_CONTEXT";
// 工步上料关箱码
public static final String MATCH_STATION_FEED_CLOSE_PACKAGE = "MATCH_STATION_FEED_CLOSE_PACKAGE";
//OPC_API_PARAM

Loading…
Cancel
Save