Merge remote-tracking branch 'origin/mes-uat-changshu0609-temp-wj-250616-xisu-merge-nht' into uat-temp-nht-2506120000-jialiao

uat-temp-nht-2506120000-jialiao
jason 4 weeks ago
commit 8331a33cc7

@ -132,9 +132,15 @@ public interface IMesProductionCustomContextStepService {
MesWorkOrderCompleteQtyContext dispatchWorkOrderCompleteQtyContext(StationRequestBean reqBean, Boolean noCalcOrderQty, String workOrderNo, Double calcCompleteQty);
@ApiOperation(value = "可扣减条码的缓存key")
String getContainerSnAtomicityKey(String organizeCode, MesContainerPackageDetailContext context);
String getContainerPackageDetailAtomicityKey(String organizeCode, MesContainerPackageDetailContext context);
@ApiOperation(value = "获取缓存中的原料剩余数量,用于缓存扣减")
Double getContainerPackageDetailRemainQty(String organizeCode, String key);
@ApiOperation(value = "将可扣减的条码通过原子性的方式写到缓存, 并获取最新的实际库存")
void dispatchContainerSnAtomicity(String organizeCode, List<MesContainerPackageDetailContext> containerSnStationList);
List<MesContainerPackageDetailContext> dispatchContainerPackageDetailAtomicity(String organizeCode, List<MesContainerPackageDetailContext> containerPackageDetailContextList);
@ApiOperation(value = "重置原料条码的缓存库存")
void dispatchContainerPackageDetailContext(String organizeCode, Map<String, MesContainerPackageDetailContext> remainQtyMap2Cache);
}

@ -259,21 +259,22 @@ 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 = "获取站点用于扣料业务中进行LOCK")
Map<String, MesStation> getLockStationContext(StationRequestBean reqBean);
@ApiOperation(value = "保存站点用于后面扣料业务中进行LOCK")
void dispatchLockStationContext(StationRequestBean reqBean, Map<String, MesStation> stationMap2Lock);
@ApiOperation(value = "获取站点用于缺料时进行上料绑定的容器条码")
String getMatchStationFeedContainerSnContext(StationRequestBean reqBean);
@ApiOperation(value = "保存站点用于缺料时进行上料绑定的容器条码")
void dispatchMatchStationFeedContainerSnContext(StationRequestBean reqBean, String sn);
}

@ -1,10 +1,12 @@
package 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.MesProductionPsOutContext;
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 io.swagger.annotations.ApiOperation;
import java.util.List;
@ -25,7 +27,7 @@ public interface IMesStationContainerSnExtService {
List<MesContainerSnStation> getContainerSnStationListByStation(String organizeCode, List<String> stationList);
@ApiOperation(value = "获取容器条码上料明细表信息【可扣减】【根据 主表seq,主表createDatetime,明细表createDatetime 正序】")
List<MesContainerPackageDetailContext> getContainerSnStationContext(String organizeCode, List<MesStation> stationList);
List<MesContainerPackageDetailContext> getContainerPackageDetailContext(String organizeCode, List<MesStation> stationList);
@ApiOperation(value = "获取容器条码上料主表信息")
List<MesContainerPackage> getContainerPackageList(String organizeCode, List<MesContainerSnStation> containerSnStationList, Integer packageStatus);
@ -42,4 +44,10 @@ public interface IMesStationContainerSnExtService {
@ApiOperation(value = "获取容器条码的一条上料明细表信息【可扣减】")
Boolean checkIsExistContainerPackageDetail(String organizeCode, Long id);
@ApiOperation(value = "写入扣料记录")
void insertContainerPackageDetailFeeding(StationRequestBean reqBean, MesContainerPackageDetailContext containerPackageDetailContext, MesProductionPsOutContext productionPsOutContext);
@ApiOperation(value = "修改上料明细表信息状态")
void updateContainerPackageDetail(String organizeCode, String userInfo, Long id, Integer snStatus);
}

@ -2,19 +2,18 @@ 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.context.MesProductionPsOutContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
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.bean.*;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.repository.*;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
@ -46,6 +45,9 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx
@Autowired
private MesContainerPackageDetailRepository containerPackageDetailRepository;
@Autowired
private MesContainerPackageDetailFeedingRepository containerPackageDetailFeedingRepository;
//根据设备代码查询站点信息
@Override
public List<MesStation> getStationList(String organizeCode, String equipmentCode) {
@ -85,7 +87,7 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx
//获取容器条码上料明细表信息【可扣减】【根据 主表seq,主表createDatetime,明细表createDatetime 正序】
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public List<MesContainerPackageDetailContext> getContainerSnStationContext(String organizeCode, List<MesStation> stationList) {
public List<MesContainerPackageDetailContext> getContainerPackageDetailContext(String organizeCode, List<MesStation> stationList) {
//获取站点关联的容器条码, key = containerSn
Map<String, List<MesContainerSnStation>> containerSnStationMap = getContainerSnStationMap(organizeCode, stationList);
if (CollectionUtils.isEmpty(containerSnStationMap)) return null;
@ -96,12 +98,14 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx
//获取容器条码上料明细表信息
List<MesContainerPackageDetail> containerPackageDetailList = getContainerPackageDetailList(organizeCode, containerPackageList);
if (CollectionUtils.isEmpty(containerPackageDetailList)) return null;
//站点根据名称分组
Map<String, List<MesStation>> stationMap = stationList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesStation::getStation));
//封装容器条码对应的【可扣减】的上料明细表信息
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));
containerSnStationContextList.add(new MesContainerPackageDetailContext(containerPackageDetail).containerSnStation(containerSnStation).station(stationMap.get(containerSnStation.getStation()).get(0)));
}
//根据 主表seq,主表createDatetime,明细表createDatetime 正序
containerSnStationContextList = containerSnStationContextList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesContainerPackageDetailContext::getSeq)
@ -123,7 +127,7 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx
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);
else DdlPreparedPack.getInPackList(containerSnList, MesPcnExtConstWords.CONTAINER_SN, packBean);
DdlPreparedPack.getNumEqualPack(packageStatus, MesPcnExtConstWords.PACKAGE_STATUS, packBean);
return containerPackageRepository.findByHqlWhere(packBean);
}
@ -157,4 +161,28 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx
return containerPackageDetailRepository.isExitByHql(packBean);
}
//写入扣料记录
@Override
public void insertContainerPackageDetailFeeding(StationRequestBean reqBean, MesContainerPackageDetailContext containerPackageDetailContext, MesProductionPsOutContext productionPsOutContext) {
MesContainerPackageDetailFeeding containerPackageDetailFeeding = new MesContainerPackageDetailFeeding();
BeanUtils.copyProperties(containerPackageDetailContext, containerPackageDetailFeeding, MesPcnExtConstWords.BASE_BEAN_FIELDS);
containerPackageDetailFeeding.setQty(containerPackageDetailContext.getDeductionQty());
containerPackageDetailFeeding.setSourceId(containerPackageDetailContext.getId());
if (null != productionPsOutContext) {
containerPackageDetailFeeding.setProductSn(productionPsOutContext.getProductSn());
containerPackageDetailFeeding.setProductSnId(productionPsOutContext.getId());
}
ConvertBean.serviceModelInitialize(containerPackageDetailFeeding, reqBean.getUserInfo());
containerPackageDetailFeedingRepository.insert(containerPackageDetailFeeding);
}
@Override
public void updateContainerPackageDetail(String organizeCode, String userInfo, Long id, Integer snStatus) {
containerPackageDetailRepository.updateByProperties(
new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.ID},
new Object[]{organizeCode, id},
new String[]{MesPcnExtConstWords.SN_STATUS, MesPcnExtConstWords.MODIFY_USER, MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.SYSTEM_SYNC_STATUS, MesPcnExtConstWords.SYSTEM_SYNC_DATE_TIME},
new Object[]{snStatus, userInfo, TimeTool.getNowTime(true), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesPcnExtConstWords.EMPTY});
}
}

@ -0,0 +1,92 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.station.function;
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.apiservice.serviceimpl.step.method.MesWorkOrderCheckCompleteQtyStepService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPartContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseSwsService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IShippingDispatchService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.function.IFsmModuleFunctionService;
import cn.estsh.i3plus.platform.common.util.MesPcnConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.model.ButtonDynamicModel;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @Description :
**/
@Service
public class MesFunctionDialogInputOrderQtyService extends BaseSwsService implements IFsmModuleFunctionService {
@Autowired
private IMesProductionProcessContextStepService productionProcessContextStepService;
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Autowired
private MesWorkOrderCheckCompleteQtyStepService workOrderCheckCompleteQtyStepService;
@Autowired
private IShippingDispatchService shippingDispatchService;
@Override
public Boolean doFunction(StationRequestBean reqBean, StationResultBean resultBean, ButtonDynamicModel buttonDynamicModel) {
this.sendMessage(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PICK.getValue()).scanInfo(buttonDynamicModel.getFunctionValue()),
String.format("生产线[%s]工位[%s]工单数量弹框提交成功,请等待验证!提交信息[%s]", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), buttonDynamicModel.getFunctionValue()),
MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
//获取上下文信息
MesProductionProcessContext productionProcessContext = productionProcessContextStepService.getProductionProcessContext(reqBean);
//获取上下文产出零件信息
List<MesProductionPartContext> productionPartContextList = productionDispatchContextStepService.getProductionPartContext(reqBean);
//用弹框输入的工单数量 虚拟产出零件信息
List<MesProductionPsOutContext> productionPsOutContextList = new ArrayList<>();
productionPartContextList.forEach(o -> {
MesProductionPsOutContext productionPsOutContext = new MesProductionPsOutContext().foreignKey(o.getForeignKey());
productionPsOutContext.setQty(new Double(buttonDynamicModel.getFunctionValue()));
productionPsOutContextList.add(productionPsOutContext);
});
StepResult stepResult = StepResult.getSuccessComplete();
//验证加工单完成数量
workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, null, productionPsOutContextList);
reqBean.setClientInfo(shippingDispatchService.getActorClientInfo(reqBean));
reqBean.setInterfaceType(MesPcnConstWords.SHIPPING);
reqBean.setBusiType(MesPcnEnumUtil.ACTOR_RECEIVE_STRATEGY.WS_CMD_DO_SCAN.getCode());
if (!stepResult.isCompleted()) reqBean.setTriggerAutoFsm(true);
else {
//获取上下文产品加工规则数据信息集合
List<MesProdRuleContext> prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean);
prodRuleContextList.stream().forEach(o -> o.eachCavityQty(buttonDynamicModel.getFunctionValue()));
productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList);
reqBean.setButtonCode(buttonDynamicModel.getButtonCode());
reqBean.setStepDialogStatus(true);
}
shippingDispatchService.sendScanQueueNextExec(reqBean);
return true;
}
}

@ -0,0 +1,45 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.station.function;
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.apiservice.serviceimpl.step.method.MesWorkOrderCheckCompleteQtyStepService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseSwsService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IShippingDispatchService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.function.IFsmModuleFunctionService;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.model.ButtonDynamicModel;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Description :
**/
@Service
public class MesFunctionDialogInputRawMixWeightService extends BaseSwsService implements IFsmModuleFunctionService {
@Autowired
private IMesProductionProcessContextStepService productionProcessContextStepService;
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Autowired
private MesWorkOrderCheckCompleteQtyStepService workOrderCheckCompleteQtyStepService;
@Autowired
private IShippingDispatchService shippingDispatchService;
@Override
public Boolean doFunction(StationRequestBean reqBean, StationResultBean resultBean, ButtonDynamicModel buttonDynamicModel) {
this.sendMessage(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PICK.getValue()).scanInfo(buttonDynamicModel.getFunctionValue()),
String.format("生产线[%s]工位[%s]原料调配弹框提交成功,请等待验证!提交信息[%s]", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), buttonDynamicModel.getFunctionValue()),
MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
return true;
}
}

@ -1,13 +1,11 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProduceSnExtService;
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.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.*;
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.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesProductionAssembly;
@ -18,6 +16,7 @@ import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.i3plus.pojo.mes.repository.MesProductionAssemblyRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesProductionAssemblyUniqueRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -54,6 +53,9 @@ public class MesAssemblySaveStepService extends BaseStepService {
@Autowired
private IMesProduceSnExtService produceSnExtService;
@Autowired
private IMesStationContainerSnExtService stationContainerSnExtService;
@Override
public StepResult execute(StationRequestBean reqBean) {
@ -124,58 +126,94 @@ public class MesAssemblySaveStepService extends BaseStepService {
if (null == productionAssemblyNosortContext) continue;
MesProductionAssembly productionAssembly = new MesProductionAssembly();
BeanUtils.copyProperties(productionAssemblyNosortContext, productionAssembly);
//容器匹配, 一个装配件信息可能对应多条原料条码
if (productionAssemblyNosortContext.getMatchType().compareTo(MesExtEnumUtil.ASSEMBLY_MATCH_TYPE.MATCH_TYPE_80.getValue()) == 0) {
insertMesProductionAssembly80(reqBean, productionProcessContext, cellEquipContext, prodRuleContext, productionPsOutContext, productionAssemblyNosortContext, scanMonitorContext, productSnIdList);
} else {
//一对一
insertProductionAssembly(reqBean, productionProcessContext, cellEquipContext, prodRuleContext, productionPsOutContext, productionAssemblyNosortContext, scanMonitorContext, productSnIdList);
}
}
productionAssembly.setIsOrigSn(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
}
productionAssembly.setAreaCode(reqBean.getAreaCode());
productionAssembly.setWorkCenterCode(reqBean.getWorkCenterCode());
productionAssembly.setWorkCellCode(reqBean.getWorkCellCode());
productionAssembly.setProcessCode(reqBean.getProcessCode());
//保存装配件绑定记录
private void insertProductionAssembly(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext, MesCellEquipContext cellEquipContext,
MesProdRuleContext prodRuleContext, MesProductionPsOutContext productionPsOutContext,
MesProductionAssemblyNosortContext productionAssemblyNosortContext, MesScanMonitorContext scanMonitorContext, List<Long> productSnIdList) {
MesProductionAssembly productionAssembly = new MesProductionAssembly();
BeanUtils.copyProperties(productionAssemblyNosortContext, productionAssembly);
productionAssembly.setProcessName(productionProcessContext.getProcessName());
productionAssembly.setCraftCode(productionProcessContext.getCraftCode());
productionAssembly.setCraftName(productionProcessContext.getCraftName());
productionAssembly.setIsOrigSn(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
productionAssembly.setEquipmentCode(cellEquipContext.getEquipmentCode());
productionAssembly.setAreaCode(reqBean.getAreaCode());
productionAssembly.setWorkCenterCode(reqBean.getWorkCenterCode());
productionAssembly.setWorkCellCode(reqBean.getWorkCellCode());
productionAssembly.setProcessCode(reqBean.getProcessCode());
productionAssembly.setProductionRecordId(prodRuleContext.getProductionRecordId());
productionAssembly.setMouldNo(prodRuleContext.getMouldNo());
productionAssembly.setProcessName(productionProcessContext.getProcessName());
productionAssembly.setCraftCode(productionProcessContext.getCraftCode());
productionAssembly.setCraftName(productionProcessContext.getCraftName());
if (null != productionPsOutContext) {
productionAssembly.setPartNo(productionPsOutContext.getPartNo());
productionAssembly.setPartName(productionPsOutContext.getPartName());
productionAssembly.setSerialNumber(productionPsOutContext.getSerialNumber());
productionAssembly.setProductSn(productionPsOutContext.getProductSn());
productionAssembly.setCustSn(productionPsOutContext.getCustSn());
}
productionAssembly.setEquipmentCode(cellEquipContext.getEquipmentCode());
if (null != scanMonitorContext) productionAssembly.setMouldRecordId(scanMonitorContext.getMouldRecordId());
productionAssembly.setProductionRecordId(prodRuleContext.getProductionRecordId());
productionAssembly.setMouldNo(prodRuleContext.getMouldNo());
productionAssembly.setFid(UUID.randomUUID().toString());
productionAssembly.setOrganizeCode(reqBean.getOrganizeCode());
ConvertBean.serviceModelInitialize(productionAssembly, reqBean.getUserInfo());
if (null != productionPsOutContext) {
productionAssembly.setPartNo(productionPsOutContext.getPartNo());
productionAssembly.setPartName(productionPsOutContext.getPartName());
productionAssembly.setSerialNumber(productionPsOutContext.getSerialNumber());
productionAssembly.setProductSn(productionPsOutContext.getProductSn());
productionAssembly.setCustSn(productionPsOutContext.getCustSn());
}
productionAssembly = productionAssemblyRepository.insert(productionAssembly);
if (null != scanMonitorContext) productionAssembly.setMouldRecordId(scanMonitorContext.getMouldRecordId());
saveProductionAssemblyUnique(productionAssembly);
productionAssembly.setFid(UUID.randomUUID().toString());
productionAssembly.setOrganizeCode(reqBean.getOrganizeCode());
ConvertBean.serviceModelInitialize(productionAssembly, reqBean.getUserInfo());
if (!StringUtils.isEmpty(productionAssemblyNosortContext.getProductSnId())) productSnIdList.add(productionAssemblyNosortContext.getProductSnId());
productionAssembly = productionAssemblyRepository.insert(productionAssembly);
if (productionAssemblyNosortContext.getIsRepeat().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 && productionAssemblyNosortContext.getIsRepeat2Cache().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0)
productionCustomContextStepService.dispatchRepeatAssemblySn(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), productionAssemblyNosortContext);
saveProductionAssemblyUnique(productionAssembly);
}
if (!StringUtils.isEmpty(productionAssemblyNosortContext.getProductSnId())) productSnIdList.add(productionAssemblyNosortContext.getProductSnId());
if (productionAssemblyNosortContext.getIsRepeat().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0 && productionAssemblyNosortContext.getIsRepeat2Cache().compareTo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) == 0)
productionCustomContextStepService.dispatchRepeatAssemblySn(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), productionAssemblyNosortContext);
}
private void saveProductionAssemblyUnique(MesProductionAssembly productionAssembly) {
if (productionAssembly.getMatchType().compareTo(MesExtEnumUtil.ASSEMBLY_MATCH_TYPE.MATCH_TYPE_30.getValue()) != 0 || StringUtils.isEmpty(productionAssembly.getAssemblySn())) return;
if (!MesExtEnumUtil.ASSEMBLY_MATCH_TYPE.checkUniqueRuleInDb(productionAssembly.getMatchType()) || StringUtils.isEmpty(productionAssembly.getAssemblySn())) return;
MesProductionAssemblyUnique productionAssemblyUnique = new MesProductionAssemblyUnique();
BeanUtils.copyProperties(productionAssembly, productionAssemblyUnique, MesPcnExtConstWords.ID);
productionAssemblyUnique.setPid(productionAssembly.getId());
productionAssemblyUniqueRepository.insert(productionAssemblyUnique);
}
//容器匹配, 一个装配件信息可能对应多条原料条码
private void insertMesProductionAssembly80(StationRequestBean reqBean, MesProductionProcessContext productionProcessContext, MesCellEquipContext cellEquipContext,
MesProdRuleContext prodRuleContext, MesProductionPsOutContext productionPsOutContext,
MesProductionAssemblyNosortContext productionAssemblyNosortContext, MesScanMonitorContext scanMonitorContext, List<Long> productSnIdList) {
//解析扣料信息
List<MesContainerPackageDetailContext> containerPackageDetailContextList = StringUtils.isEmpty(productionAssemblyNosortContext.getContainerSnData()) ? null : JSONObject.parseArray(productionAssemblyNosortContext.getContainerSnData(), MesContainerPackageDetailContext.class);
if (CollectionUtils.isEmpty(containerPackageDetailContextList)) return;
for (MesContainerPackageDetailContext containerPackageDetailContext : containerPackageDetailContextList) {
if (null == containerPackageDetailContext || StringUtils.isEmpty(containerPackageDetailContext.getBarCode())) continue;
//覆盖原料条码字段跟工序用量
productionAssemblyNosortContext.assemblySn(containerPackageDetailContext.getBarCode()).qty(containerPackageDetailContext.getDeductionQty());
//保存装配件绑定记录
insertProductionAssembly(reqBean, productionProcessContext, cellEquipContext, prodRuleContext, productionPsOutContext, productionAssemblyNosortContext, scanMonitorContext, productSnIdList);
//写入扣料记录
stationContainerSnExtService.insertContainerPackageDetailFeeding(reqBean, containerPackageDetailContext, productionPsOutContext);
//修改上料明细表信息状态【扣减完成】
if (MathOperation.compareTo(containerPackageDetailContext.getRemainQty(), new Double(0)) == 0) {
stationContainerSnExtService.updateContainerPackageDetail(reqBean.getOrganizeCode(), reqBean.getUserInfo(), containerPackageDetailContext.getId(), MesExtEnumUtil.CONTAINER_BARCODE_STATUS.STATUS_20.getValue());
}
}
}
}

@ -53,10 +53,16 @@ public class MesCustomDialogStepService extends BaseStepService {
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, true, MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "弹框会话关闭!");
}
//获取工步参数
Optional<Map<String, MesProdRouteOptParam>> stepParamMap = getStepParams(reqBean);
String customPageName = (null != stepParamMap && stepParamMap.isPresent() && stepParamMap.get().containsKey(MesPcnExtConstWords.CUSTOM_PAGE_NAME)) ? stepParamMap.get().get(MesPcnExtConstWords.CUSTOM_PAGE_NAME).getParamValue() : null;
String customPageName;
if (reqBean.getDataMap().containsKey(MesPcnExtConstWords.CUSTOM_PAGE_NAME)) {
//适配其他工步调用弹框工步 例如: 原料调配弹框输入重量 [CUSTOM_PAGE_NAME = FUNCTION_DIALOG_INPUT_RAW_MIX_WEIGHT]
customPageName = (String) reqBean.getDataMap().get(MesPcnExtConstWords.CUSTOM_PAGE_NAME);
reqBean.getDataMap().remove(MesPcnExtConstWords.CUSTOM_PAGE_NAME);
} else {
//获取工步参数
Optional<Map<String, MesProdRouteOptParam>> stepParamMap = getStepParams(reqBean);
customPageName = (null != stepParamMap && stepParamMap.isPresent() && stepParamMap.get().containsKey(MesPcnExtConstWords.CUSTOM_PAGE_NAME)) ? stepParamMap.get().get(MesPcnExtConstWords.CUSTOM_PAGE_NAME).getParamValue() : null;
}
if (StringUtils.isEmpty(customPageName)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("弹框会话工步未配置工步参数[%s]!", MesPcnExtConstWords.CUSTOM_PAGE_NAME));

@ -14,6 +14,7 @@ import cn.estsh.i3plus.mes.pcn.api.iservice.busi.ISyncFuncService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.mes.pcn.util.StringUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.pojo.base.codemaker.SnowflakeIdMaker;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
@ -198,7 +199,10 @@ public class MesProductSnGenerateStepService extends BaseStepService {
produceSnClone.setSerialNumber(snowflakeIdMaker.nextId() + MesPcnExtConstWords.EMPTY);
}
produceSnClone.setQty(new Double(1));
//适配弹框输入的工单数量【每腔数量】
if (StringUtils.isEmpty(produceSnClone.getQty()) || MathOperation.compareTo(produceSnClone.getQty(), new Double(0)) == 0) {
produceSnClone.setQty(prodRuleContext.getEachCavityQty());
}
if (!StringUtils.isEmpty(prodRuleContext.getWorkOrderNo())) produceSnClone.setWorkOrderNo(prodRuleContext.getWorkOrderNo());

@ -121,7 +121,7 @@ public class MesProductionRecordGenerateStepService extends BaseStepService {
if (Objects.equal(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue(), workCell.getIsCountFinish())) {
// 保存班次加工数量上下文
MesProdShiftContext mesProdShiftKvBean = prodShiftRecordService.getMesProdShiftKvBean(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode());
Integer amount = productionCustomContextStepService.dispatchProductionStatisticsContext(reqBean, productionPsOutContextList.size(), mesProdShiftKvBean);
Integer amount = productionCustomContextStepService.dispatchProductionStatisticsContext(reqBean, getProductionStatisticsQty(productionPsOutContextList), mesProdShiftKvBean);
this.sendMessage(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), String.format("生产线[%s]工位[%s]当前累加数[%s]已累计加工数[%s]", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), productionPsOutContextList.size(), amount), MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
}
@ -129,6 +129,11 @@ public class MesProductionRecordGenerateStepService extends BaseStepService {
}
private Integer getProductionStatisticsQty(List<MesProductionPsOutContext> productionPsOutContextList) {
Double qty = productionPsOutContextList.stream().filter(o -> null != o).mapToDouble(MesProductionPsOutContext::getQty).sum();
return qty.intValue();
}
private void saveProductionRecordData(StationRequestBean reqBean, MesWorkCenter workCenter, MesScanMonitorContext scanMonitorContext, String mouldNo,
List<MesProdRuleContext> prodRuleContextList, MesProductionProcessContext productionProcessContext, MesProductionPsOutContext productionPsOutContext,
Map<Integer, MesProdRuleContext> prMap, MesCellEquipContext cellEquipContext, MesProductionPsInContext productionPsInContext, MesProductionPartContext productionPartContext) {

@ -0,0 +1,259 @@
package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;
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.api.busi.IMesProductionProcessContextStepService;
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.actor.shipping.dispatch.IFsmCommonService;
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 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.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Description :
* @Author : wangjie
**/
@Slf4j
@Service("mesStationDeductionAssemblyStepService")
public class MesStationDeductionAssemblyStepService extends BaseStepService {
@Autowired
private IMesProductionProcessContextStepService productionProcessContextStepService;
@Autowired
private IMesProductionDispatchContextStepService productionDispatchContextStepService;
@Autowired
private IMesProductionCustomContextStepService productionCustomContextStepService;
@Autowired
private IFsmCommonService fsmCommonService;
private final static Map<String, ReentrantLock> lockMap = new ConcurrentHashMap<>();
@Override
public StepResult init(StationRequestBean reqBean) {
StepResult stepResult = StepResult.getSuccessComplete();
String endlessLoopReadTimes = fsmCommonService.handleFsmWcpcMapDataForDoScanThenBackValue(reqBean, MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES);
if (StringUtils.isEmpty(endlessLoopReadTimes)) endlessLoopReadTimes = MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES_DEFAULT;
if (productionDispatchContextStepService.dispatchOverEndlessLoopReadTimes(reqBean, endlessLoopReadTimes)) {
stepThreadSleepAndSendTaskCompleteAndThrowEx(reqBean, new StationResultBean().isWs(false).writeDbLog().checkRepeat(),
stepResult.isCompleted(false).msg(String.format("当前未能执行完成站点扣减装配件超过[%s]次!", endlessLoopReadTimes)),
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
}
//发送工步内容
productionCustomContextStepService.sendStepContextMessage(reqBean);
return stepResult;
}
@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, "验证每腔不存在容器匹配的装配件,默认跳过站点扣减装配件!");
}
//获取站点用于扣料业务中进行LOCK
Map<String, MesStation> stationMap2Lock = productionDispatchContextStepService.getLockStationContext(reqBean);
List<String> stationNameList = CollectionUtils.isEmpty(stationMap2Lock) ? null : new ArrayList<>(stationMap2Lock.keySet());
if (CollectionUtils.isEmpty(stationNameList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "当前未获取到缓存的扣料站点信息,请重置工序解决!");
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
List<ReentrantLock> acquiredLocks = new ArrayList<>();
try {
if (!tryLock(acquiredLocks, stationNameList)) {
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, false,
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "站点扣减装配件扣减失败,即将重试!");
}
//用于重置原料条码的缓存库存
Map<String, MesContainerPackageDetailContext> remainQtyMap2Cache = new HashMap<>();
//执行容器装配件的缓存扣减
dispatchStationDeductionAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContextList, remainQtyMap2Cache);
if (!stepResult.isCompleted()) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), stepResult.getMsg());
//保存上下文产品加工规则信息集合
productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList);
//重置原料条码的缓存库存
productionCustomContextStepService.dispatchContainerPackageDetailContext(reqBean.getOrganizeCode(), remainQtyMap2Cache);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, false,
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "站点扣减装配件扣减异常,即将重试!");
} finally {
unLockAll(acquiredLocks);
}
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "站点扣减装配件验证成功!");
}
//执行容器装配件的缓存扣减
private void dispatchStationDeductionAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter,
List<MesProdRuleContext> prodRuleContextList, Map<String, MesContainerPackageDetailContext> remainQtyMap2Cache) {
for (MesProdRuleContext prodRuleContext : prodRuleContextList) {
if (null == prodRuleContext || StringUtils.isEmpty(prodRuleContext.getIsMatchContainer())) continue;
List<MesProductionAssemblyContext> productionAssemblyContextList = dispatchStationDeductionAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContext, remainQtyMap2Cache);
if (!stepResult.isCompleted()) break;
prodRuleContext.assemblyDataJson(productionAssemblyContextList);
}
}
//执行容器装配件的缓存扣减
private List<MesProductionAssemblyContext> dispatchStationDeductionAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter,
MesProdRuleContext prodRuleContext, Map<String, MesContainerPackageDetailContext> remainQtyMap2Cache) {
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;
//未匹配的工序用量
Double unMatchQty = MathOperation.mul(productionAssemblyContext.getQty(), prodRuleContext.getEachCavityQty());
//扣料原料条码信息
List<MesContainerPackageDetailContext> deductionContextList = null;
//用于给装配件清单赋值
List<String> barCodeList = null;
//解析前面预先匹配的能够进行扣减的原料条码
List<MesContainerPackageDetailContext> containerSnDataList = JSONObject.parseArray(productionAssemblyContext.getContainerSnData(), MesContainerPackageDetailContext.class);
for (MesContainerPackageDetailContext containerPackageDetailContext : containerSnDataList) {
if (StringUtils.isEmpty(containerPackageDetailContext)) continue;
//获取缓存中的原料剩余数量,用于缓存扣减
Double remainQtyCache;
if (!remainQtyMap2Cache.containsKey(containerPackageDetailContext.getRemainKey())) {
remainQtyCache = productionCustomContextStepService.getContainerPackageDetailRemainQty(reqBean.getOrganizeCode(), containerPackageDetailContext.getRemainKey());
remainQtyMap2Cache.put(containerPackageDetailContext.getRemainKey(), new MesContainerPackageDetailContext(containerPackageDetailContext).remainQtyCached(remainQtyCache).remainQty(remainQtyCache));
} else {
remainQtyCache = remainQtyMap2Cache.get(containerPackageDetailContext.getRemainKey()).getRemainQty();
}
//当前原料条码已经扣减完成
if (MathOperation.compareTo(remainQtyCache, new Double(0)) <= 0) continue;
//剩余未匹配的工序用量
Double remainQty = MathOperation.sub(remainQtyCache, unMatchQty);
//全部匹配完成
if (MathOperation.compareTo(remainQty, new Double(0)) >= 0) {
remainQtyMap2Cache.get(containerPackageDetailContext.getRemainKey()).remainQty(remainQty);
unMatchQty = new Double(0);
} else {
//未匹配完成, 0-负数=正数
remainQtyMap2Cache.get(containerPackageDetailContext.getRemainKey()).remainQty(new Double(0));
unMatchQty = MathOperation.sub(new Double(0), remainQty);
}
if (CollectionUtils.isEmpty(deductionContextList)) {
deductionContextList = new ArrayList<>();
barCodeList = new ArrayList<>();
}
deductionContextList.add(new MesContainerPackageDetailContext(containerPackageDetailContext)
.remainQty(remainQtyMap2Cache.get(containerPackageDetailContext.getRemainKey()).getRemainQty())
.deductionQty(MathOperation.sub(remainQtyCache, remainQtyMap2Cache.get(containerPackageDetailContext.getRemainKey()).getRemainQty()))
);
barCodeList.add(containerPackageDetailContext.getBarCode());
//如果存在未匹配的工序用量
if (MathOperation.compareTo(unMatchQty, new Double(0)) <= 0) break;
}
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;
} else {
productionAssemblyContext.setAssemblySn(barCodeList.get(0));
productionAssemblyContext.setContainerSnData(JSONObject.toJSONString(deductionContextList));
}
}
return productionAssemblyContextList;
}
private Boolean tryLock(List<ReentrantLock> acquiredLocks, List<String> stationNameList) throws InterruptedException {
Collections.sort(stationNameList);
long remaining = TimeUnit.MILLISECONDS.toNanos(3000);
long endTime = System.nanoTime() + remaining;
for (String stationName : stationNameList) {
if (StringUtils.isEmpty(stationName)) continue;
ReentrantLock lock = lockMap.computeIfAbsent(stationName, o -> new ReentrantLock());
if (!lock.tryLock(remaining, TimeUnit.NANOSECONDS)) return false;
acquiredLocks.add(lock);
remaining = endTime - System.nanoTime();
}
return true;
}
private void unLockAll(List<ReentrantLock> acquiredLocks) {
for (int i = acquiredLocks.size() - 1; i >= 0; i --) acquiredLocks.get(i).unlock();
}
}

@ -29,7 +29,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Description :
* @Description :
* @Author : wangjie
**/
@Slf4j
@ -51,9 +51,6 @@ public class MesStationMatchAssemblyStepService extends BaseStepService {
@Autowired
private IMesTimeEfficientCfgMatchService timeEfficientCfgMatchService;
@Autowired
private MesAssemblyShowNosortStepService assemblyShowNosortStepService;
@Override
public StepResult execute(StationRequestBean reqBean) {
@ -75,37 +72,41 @@ public class MesStationMatchAssemblyStepService extends BaseStepService {
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, "验证每腔不存在容器匹配的装配件,默认跳过容器条码扣减装配件!");
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(), "容器条码扣减装配件时验证设备未关联支持扣减的站点");
if (CollectionUtils.isEmpty(stationList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "站点匹配装配件时验证设备未关联支持扣减的站点");
//保存站点用于缺料时进行上料绑定
productionDispatchContextStepService.dispatchMatchStationContext(reqBean, stationList);
//获取容器条码上料明细表信息【可扣减】【根据 主表seq,主表createDatetime,明细表createDatetime 正序】
List<MesContainerPackageDetailContext> containerSnStationList = stationContainerSnExtService.getContainerSnStationContext(reqBean.getOrganizeCode(), stationList);
List<MesContainerPackageDetailContext> containerPackageDetailContextList = stationContainerSnExtService.getContainerPackageDetailContext(reqBean.getOrganizeCode(), stationList);
if (CollectionUtils.isEmpty(containerSnStationList)) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "容器条码扣减装配件时验证当前无可扣减的原材料信息!");
if (CollectionUtils.isEmpty(containerPackageDetailContextList)) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(),
stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), "站点匹配装配件时验证当前无可扣减的原材料信息!");
//将可扣减的条码进行原子性缓存, 并获取最新的实际库存
productionCustomContextStepService.dispatchContainerSnAtomicity(reqBean.getOrganizeCode(), containerSnStationList);
//获取弹框输入的工单数量, 未弹框默认 数量=1
Double orderQtyDialogContext = productionDispatchContextStepService.getOrderQtyDialogContext(reqBean);
productionCustomContextStepService.dispatchContainerPackageDetailAtomicity(reqBean.getOrganizeCode(), containerPackageDetailContextList);
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
//站点信息用于后面扣料业务中进行LOCK
Map<String, MesStation> stationMap2Lock = new HashMap<>();
//匹配装配件的工序用量
dispatchStationMatchAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContextList, containerSnStationList, orderQtyDialogContext);
dispatchStationMatchAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContextList, containerPackageDetailContextList, stationMap2Lock);
if (!stepResult.isCompleted()) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, stepResult.getMsg());
if (!stepResult.isCompleted()) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), stepResult.getMsg());
//保存上下文产品加工规则信息集合
productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList);
//保存站点用于后面扣料业务中进行LOCK
productionDispatchContextStepService.dispatchLockStationContext(reqBean, stationMap2Lock);
if (workCenter.getCenterType().compareTo(MesExtEnumUtil.WORK_CENTER_TYPE.NOSORT.getValue()) == 0)
((MesAssemblyShowNosortStepService) SpringContextsUtil.getBean("mesAssemblyShowNosortStepService")).showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList);
@ -113,15 +114,16 @@ public class MesStationMatchAssemblyStepService extends BaseStepService {
((MesAssemblyShowSortStepService) SpringContextsUtil.getBean("mesAssemblyShowSortStepService")).showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList, true, true);
return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "容器条码扣减装配件验证成功!");
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) {
List<MesProdRuleContext> prodRuleContextList, List<MesContainerPackageDetailContext> containerPackageDetailContextList,
Map<String, MesStation> stationMap2Lock) {
for (MesProdRuleContext prodRuleContext : prodRuleContextList) {
if (null == prodRuleContext || StringUtils.isEmpty(prodRuleContext.getIsMatchContainer())) continue;
List<MesProductionAssemblyContext> productionAssemblyContextList = dispatchStationMatchAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContext, containerSnStationList, orderQtyDialogContext);
List<MesProductionAssemblyContext> productionAssemblyContextList = dispatchStationMatchAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContext, containerPackageDetailContextList, stationMap2Lock);
if (!stepResult.isCompleted()) break;
prodRuleContext.assemblyDataJson(productionAssemblyContextList);
}
@ -129,7 +131,8 @@ public class MesStationMatchAssemblyStepService extends BaseStepService {
//匹配装配件的工序用量【遍历装配件】
private List<MesProductionAssemblyContext> dispatchStationMatchAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter,
MesProdRuleContext prodRuleContext, List<MesContainerPackageDetailContext> containerSnStationList, Double orderQtyDialogContext) {
MesProdRuleContext prodRuleContext, List<MesContainerPackageDetailContext> containerPackageDetailContextList,
Map<String, MesStation> stationMap2Lock) {
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;
@ -138,12 +141,14 @@ public class MesStationMatchAssemblyStepService extends BaseStepService {
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) {
Double unMatchQty = MathOperation.mul(productionAssemblyContext.getQty(), prodRuleContext.getEachCavityQty());
//支持被扣减的原料条码
List<MesContainerPackageDetailContext> containerSnDataList = null;
//用于给装配件清单赋值
List<String> barCodeList = null;
for (MesContainerPackageDetailContext containerPackageDetailContext : containerPackageDetailContextList) {
if (null == containerPackageDetailContext || StringUtils.isEmpty(containerPackageDetailContext.getPartNo())) continue;
if (!containerPackageDetailContext.getPartNo().equals(productionAssemblyContext.getPartNo()) || MathOperation.compareTo(containerPackageDetailContext.getRemainQty(), new Double(0)) <= 0) continue;
if (!containerPackageDetailContext.getPartNo().equals(productionAssemblyContext.getAssemblyPartNo()) || MathOperation.compareTo(containerPackageDetailContext.getRemainQty(), new Double(0)) <= 0) continue;
//验证时效性
Map<String, Object> result = timeEfficientCfgMatchService.checkSnTimelinessContainerMatch(reqBean.getOrganizeCode(), containerPackageDetailContext,
@ -167,10 +172,11 @@ public class MesStationMatchAssemblyStepService extends BaseStepService {
//将能够扣减的所有条码跟当前装配件关联
if (CollectionUtils.isEmpty(containerSnDataList)) {
containerSnDataList = new ArrayList<>();
containerSnList = new ArrayList<>();
barCodeList = new ArrayList<>();
}
containerSnDataList.add(productionCustomContextStepService.getContainerSnAtomicityKey(reqBean.getOrganizeCode(), containerPackageDetailContext));
containerSnList.add(containerPackageDetailContext.getContainerSn());
containerSnDataList.add(containerPackageDetailContext);
barCodeList.add(containerPackageDetailContext.getBarCode());
if (!stationMap2Lock.containsKey(containerPackageDetailContext.getStation())) stationMap2Lock.put(containerPackageDetailContext.getStation(), containerPackageDetailContext.getStationInfo());
}
if (MathOperation.compareTo(unMatchQty, new Double(0)) > 0) {
@ -179,14 +185,15 @@ public class MesStationMatchAssemblyStepService extends BaseStepService {
productionAssemblyContext.setAssemblySn(null);
productionAssemblyContext.setMatchDatetime(null);
}
stepResult.isCompleted(false).msg(String.format("容器条码扣减装配件时验证零件号[%s]当前缺料,请扫描上料条码!", productionAssemblyContext.getPartNo()));
stepResult.isCompleted(false).msg(String.format("站点匹配装配件时验证零件号[%s]当前缺料,请扫描上料条码!", productionAssemblyContext.getPartNo()));
break;
} else {
productionAssemblyContext.setAssemblyStatus(MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_10.getValue());
productionAssemblyContext.setAssemblySn(barCodeList.get(0));
productionAssemblyContext.setMatchDatetime((new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT_SSS)).format(new Date()));
productionAssemblyContext.setContainerSnData(JSONObject.toJSONString(containerSnDataList));
}
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;

@ -63,8 +63,8 @@ public class MesWorkOrderQueueAcceptStepService extends BaseStepService {
@Autowired
private IShippingDispatchService shippingDispatchService;
private static Map<String, String> lockTimeMap = new HashMap<>();
private static Map<String, ReentrantLock> lockMap = new ConcurrentHashMap<>();
private final static Map<String, String> lockTimeMap = new HashMap<>();
private final static Map<String, ReentrantLock> lockMap = new ConcurrentHashMap<>();
@Override
public void title(StationRequestBean reqBean) {
@ -79,7 +79,7 @@ public class MesWorkOrderQueueAcceptStepService extends BaseStepService {
String endlessLoopReadTimes = fsmCommonService.handleFsmWcpcMapDataForDoScanThenBackValue(reqBean, MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES);
if (StringUtils.isEmpty(endlessLoopReadTimes)) endlessLoopReadTimes = MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES_DEFAULT;
if (productionDispatchContextStepService.dispatchOverEndlessLoopReadTimes(reqBean, endlessLoopReadTimes)) {
stepThreadSleepAndSendTaskCompleteAndThrowEx(reqBean, new StationResultBean().isWs(false),
stepThreadSleepAndSendTaskCompleteAndThrowEx(reqBean, new StationResultBean().isWs(false).writeDbLog().checkRepeat(),
stepResult.isCompleted(false).msg(String.format("当前未获取到工位工单队列超过[%s]次!", endlessLoopReadTimes)),
MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
}

@ -114,14 +114,14 @@ public class MesWorkOrderSaveNosortStepService extends BaseStepService {
if (null == entry) continue;
//获取对应的加工规则
List<MesProductionPsOutContext> produceSnContextList = proMap.get(entry.getKey());
List<MesProductionPsOutContext> productionPsOutContextList2Order = proMap.get(entry.getKey());
//生产数量
Double calcCompleteQty = new Double(MesPcnExtConstWords.ZERO);
//遍历产出物料
for (MesProductionPsOutContext productionPsOutContext : produceSnContextList) {
for (MesProductionPsOutContext productionPsOutContext : productionPsOutContextList2Order) {
if (null == productionPsOutContext) continue;
//产出零件需要计算工单完成数量
if (productionPsOutContext.getIsCalcCompleteQty() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) calcCompleteQty = MathOperation.add(calcCompleteQty, new Double(MesPcnExtConstWords.ONE));
if (productionPsOutContext.getIsCalcCompleteQty() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) calcCompleteQty = MathOperation.add(calcCompleteQty, productionPsOutContext.getQty());
}
if (MathOperation.compareTo(calcCompleteQty, new Double(MesPcnExtConstWords.ZERO)) == 0) continue;
@ -192,7 +192,7 @@ public class MesWorkOrderSaveNosortStepService extends BaseStepService {
for (MesProductionPsOutContext productionPsOutContext : entry.getValue()) {
if (null == productionPsOutContext) continue;
//产出零件需要计算工单完成数量
if (productionPsOutContext.getIsCalcCompleteQty() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) calcCompleteQty = MathOperation.add(calcCompleteQty, new Double(MesPcnExtConstWords.ONE));
if (productionPsOutContext.getIsCalcCompleteQty() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) calcCompleteQty = MathOperation.add(calcCompleteQty, productionPsOutContext.getQty());
}
if (MathOperation.compareTo(calcCompleteQty, new Double(MesPcnExtConstWords.ZERO)) == 0) continue;

@ -396,26 +396,49 @@ public class MesProductionCustomContextStepService extends BaseStepService imple
return workOrderCompleteQtyContext;
}
//可扣减条码的缓存key
@Override
public String getContainerSnAtomicityKey(String organizeCode, MesContainerPackageDetailContext context) {
public String getContainerPackageDetailAtomicityKey(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())
.add(context.getContainerSn())
.add(new StringJoiner(MesPcnExtConstWords.AND).add(context.getBarCode()).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));
// });
public Double getContainerPackageDetailRemainQty(String organizeCode, String key) {
String remainQty = getFsmBusiData(organizeCode, key);
return StringUtils.isEmpty(remainQty) ? new Double(0) : new Double(remainQty);
}
//将可扣减的条码通过原子性的方式写到缓存, 并获取最新的实际库存
@Override
public List<MesContainerPackageDetailContext> dispatchContainerPackageDetailAtomicity(String organizeCode, List<MesContainerPackageDetailContext> containerPackageDetailContextList) {
if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(containerPackageDetailContextList)) return containerPackageDetailContextList;
containerPackageDetailContextList.stream().forEach(o -> {
String remainKey = getContainerPackageDetailAtomicityKey(organizeCode, o);
Boolean success = dispatchFsmBusiDataAtomicity(organizeCode, remainKey, o.getQty().toString(), MesPcnEnumUtil.EXPIRE_TIME.DEFAULT.getValue());
o.remainKey(remainKey);
if (success) {
o.remainQty(o.getQty());
} else {
o.remainQty(getFsmBusiData(organizeCode, remainKey));
}
});
return containerPackageDetailContextList;
}
@Override
public void dispatchContainerPackageDetailContext(String organizeCode, Map<String, MesContainerPackageDetailContext> remainQtyMap2Cache) {
for (Map.Entry<String, MesContainerPackageDetailContext> entry : remainQtyMap2Cache.entrySet()) {
if (null == entry) continue;
MesContainerPackageDetailContext containerPackageDetailContext = entry.getValue();
if (MathOperation.compareTo(containerPackageDetailContext.getRemainQtyCached(), containerPackageDetailContext.getRemainQty()) == 0) continue;
dispatchFsmBusiData(organizeCode, containerPackageDetailContext.getRemainKey(), containerPackageDetailContext.getRemainQty().toString(), MesPcnEnumUtil.EXPIRE_TIME.DEFAULT.getValue());
}
}
}

@ -589,24 +589,11 @@ 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);
return !StringUtils.isEmpty(stationContext) ? JSONObject.parseArray(stationContext, MesStation.class) : null;
}
//保存站点用于缺料时进行上料绑定
@ -616,14 +603,31 @@ public class MesProductionDispatchContextStepService extends BaseStepService imp
dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_CONTEXT, JSONObject.toJSONString(stationList));
}
//获取站点用于扣料业务中进行LOCK
@Override
public Map<String, MesStation> getLockStationContext(StationRequestBean reqBean) {
String stationContext = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.LOCK_STATION_CONTEXT);
return !StringUtils.isEmpty(stationContext) ? JSONObject.parseObject(stationContext, new TypeReference<Map<String, MesStation>>() {}) : null;
}
//保存站点用于后面扣料业务中进行LOCK
@Override
public void dispatchLockStationContext(StationRequestBean reqBean, Map<String, MesStation> stationMap2Lock) {
if (CollectionUtils.isEmpty(stationMap2Lock)) return;
dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.LOCK_STATION_CONTEXT, JSONObject.toJSONString(stationMap2Lock));
}
//获取站点用于缺料时进行上料绑定的容器条码
@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);
}
}

@ -45,7 +45,17 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
//验证加工单完成数量, 验证的前提条件: 每腔均已匹配到加工规则;存在工单;
public List<MesWorkOrderCompleteQtyContext> dispatchWorkOrderCompleteQtyContext(StationRequestBean reqBean, StationResultBean resultBean,
StepResult stepResult, MesProductionProcessContext productionProcessContext,
List<MesProductionPartContext> productionPartContextList, List<MesProductionPsInContext> productionPsInContextList) {
List<MesProductionPartContext> productionPartContextList,
List<MesProductionPsInContext> productionPsInContextList) {
return dispatchWorkOrderCompleteQtyContext(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList, null);
}
//验证加工单完成数量, 验证的前提条件: 每腔均已匹配到加工规则;存在工单;
public List<MesWorkOrderCompleteQtyContext> dispatchWorkOrderCompleteQtyContext(StationRequestBean reqBean, StationResultBean resultBean,
StepResult stepResult, MesProductionProcessContext productionProcessContext,
List<MesProductionPartContext> productionPartContextList,
List<MesProductionPsInContext> productionPsInContextList,
List<MesProductionPsOutContext> productionPsOutContextList) {
//是否存在产成零件信息
if (!stepResult.isCompleted() || CollectionUtils.isEmpty(productionPartContextList)) return null;
@ -63,6 +73,9 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
//根据foreignkey分组进料零件条码
Map<Integer, MesProductionPsInContext> productionPsInContextMap = CollectionUtils.isEmpty(productionPsInContextList) ? null :
productionPsInContextList.stream().filter(o -> !StringUtils.isEmpty(o.getForeignKey())).collect(Collectors.toMap(MesProductionPsInContext::getForeignKey, o -> o));
//根据foreignkey分组产出零件条码
Map<Integer, MesProductionPsOutContext> productionPsOutContextMap = CollectionUtils.isEmpty(productionPsOutContextList) ? null :
productionPsOutContextList.stream().filter(o -> !StringUtils.isEmpty(o.getForeignKey())).collect(Collectors.toMap(MesProductionPsOutContext::getForeignKey, o -> o));
//生产线与工位信息
MesWorkCenter workCenter = productionProcessContext.getWorkCenter();
@ -76,7 +89,8 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
if (null == entry) continue;
//验证加工单完成数量
MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext = dispatchWorkOrderCompleteQty(reqBean, resultBean, stepResult, workCenter, noCalcOrderQty, entry.getValue(), productionPsInContextMap);
MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext = dispatchWorkOrderCompleteQty(
reqBean, resultBean, stepResult, workCenter, noCalcOrderQty, entry.getValue(), productionPsInContextMap, productionPsOutContextMap);
//验证失败直接退出
if (!stepResult.isCompleted()) break;
@ -102,15 +116,19 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
//验证加工单完成数量
private MesWorkOrderCompleteQtyContext dispatchWorkOrderCompleteQty(StationRequestBean reqBean, StationResultBean resultBean,
StepResult stepResult, MesWorkCenter workCenter, Boolean noCalcOrderQty,
List<MesProductionPartContext> productionPartContextList, Map<Integer, MesProductionPsInContext> productionPsInContextMap) {
List<MesProductionPartContext> productionPartContextList,
Map<Integer, MesProductionPsInContext> productionPsInContextMap,
Map<Integer, MesProductionPsOutContext> productionPsOutContextMap) {
Double calcCompleteQty = new Double(MesPcnExtConstWords.ZERO);
for (MesProductionPartContext productionPartContext : productionPartContextList) {
MesProductionPsInContext productionPsInContext = getProductionPsInContext(productionPsInContextMap, productionPartContext.getForeignKey());
MesProductionPsOutContext productionPsOutContext = getProductionPsOutContext(productionPsOutContextMap, productionPartContext.getForeignKey());
//验证进料零件与产出零件是否一致
Boolean isSamePart = isSamePart(productionPsInContext, productionPartContext, null);
//验证是否计数
Boolean isCalcCompleteQty = isCalcCompleteQty(isSamePart, productionPsInContext, productionPartContext);
if (isCalcCompleteQty) calcCompleteQty = MathOperation.add(calcCompleteQty, new Double(MesPcnExtConstWords.ONE));
if (isCalcCompleteQty) calcCompleteQty = MathOperation.add(calcCompleteQty, null != productionPsOutContext ? productionPsOutContext.getQty() : new Double(MesPcnExtConstWords.ONE));
}
//当前工单无须计算工单完成数
if (MathOperation.compareTo(calcCompleteQty, new Double(MesPcnExtConstWords.ZERO)) == 0) return null;
@ -166,6 +184,12 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService {
return productionPsInContextMap.get(foreignKey);
}
//根据数据关联键获取产出零件信息
private MesProductionPsOutContext getProductionPsOutContext(Map<Integer, MesProductionPsOutContext> productionPsOutContextMap, Integer foreignKey) {
if (CollectionUtils.isEmpty(productionPsOutContextMap) || StringUtils.isEmpty(foreignKey)) return null;
return productionPsOutContextMap.get(foreignKey);
}
//验证工单完成数
private void checkWorkOrderCompleteQty(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter,
MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext, Double calcCompleteQty, Boolean noCalcOrderQty) {

@ -3,6 +3,7 @@ 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 cn.estsh.i3plus.pojo.mes.bean.MesStation;
import io.swagger.annotations.ApiParam;
import lombok.Data;
import org.springframework.beans.BeanUtils;
@ -27,22 +28,51 @@ public class MesContainerPackageDetailContext extends MesContainerPackageDetail
@ApiParam(value = "主表创建日期")
private String createDatetime2Package;
@ApiParam("库存")
@ApiParam("库存数量")
private Double remainQty;
@ApiParam("库存KEY")
private String remainKey;
@ApiParam("缓存的库存数量")
private Double remainQtyCached;
@ApiParam("扣减数量")
private Double deductionQty;
@ApiParam(name = "设备代码")
private String equipmentCode;
@ApiParam(name = "站点类型")
private Integer stationType;
@ApiParam(name = "加工模式")
private Integer processMethod;
public MesContainerPackageDetailContext() {}
public MesContainerPackageDetailContext(MesContainerPackageDetail containerPackageDetail) {
BeanUtils.copyProperties(containerPackageDetail, this);
}
public MesContainerPackageDetailContext station(MesContainerSnStation containerSnStation) {
public MesContainerPackageDetailContext(MesContainerPackageDetailContext containerPackageDetailContext) {
BeanUtils.copyProperties(containerPackageDetailContext, this);
}
public MesContainerPackageDetailContext containerSnStation(MesContainerSnStation containerSnStation) {
this.station = containerSnStation.getStation();
this.seq = !StringUtils.isEmpty(containerSnStation.getSeq()) ? containerSnStation.getSeq() : MesPcnExtConstWords.ZERO;
this.createDatetime2Package = containerSnStation.getCreateDatetime();
return this;
}
public MesContainerPackageDetailContext station(MesStation station) {
this.equipmentCode = station.getEquipmentCode();
this.stationType = station.getStationType();
this.processMethod = station.getProcessMethod();
return this;
}
public MesContainerPackageDetailContext remainQty(String remainQty) {
return remainQty(!StringUtils.isEmpty(remainQty) ? new Double(remainQty) : new Double(MesPcnExtConstWords.ZERO));
}
@ -52,4 +82,27 @@ public class MesContainerPackageDetailContext extends MesContainerPackageDetail
return this;
}
public MesContainerPackageDetailContext remainQtyCached(Double remainQtyCached) {
this.remainQtyCached = remainQtyCached;
return this;
}
public MesContainerPackageDetailContext deductionQty(Double deductionQty) {
this.deductionQty = deductionQty;
return this;
}
public MesContainerPackageDetailContext remainKey(String remainKey) {
this.remainKey = remainKey;
return this;
}
public MesStation getStationInfo() {
MesStation station = new MesStation();
station.setEquipmentCode(this.equipmentCode);
station.setStationType(this.stationType);
station.setProcessMethod(this.processMethod);
return station;
}
}

@ -122,6 +122,13 @@ public class MesProdRuleContext implements Serializable {
@ApiParam(name = "是否存在装配件容器匹配")
private String isMatchContainer;
@ApiParam(name = "是否存在装配件原料调配")
private String isMatchRawMix;
//用于弹框输入工单数量
@ApiParam(name = "每腔数量")
private Double eachCavityQty = new Double(1);
public MesProdRuleContext() {}
public MesProdRuleContext(String organizeCode) {
@ -230,10 +237,22 @@ public class MesProdRuleContext implements Serializable {
return this;
}
public MesProdRuleContext eachCavityQty(String eachCavityQty) {
if (StringUtils.isEmpty(eachCavityQty)) return this;
return eachCavityQty(new Double(eachCavityQty));
}
public MesProdRuleContext eachCavityQty(Double eachCavityQty) {
if (StringUtils.isEmpty(eachCavityQty) || eachCavityQty.compareTo(new Double(0)) == 0) return this;
this.eachCavityQty = eachCavityQty;
return this;
}
public MesProdRuleContext assemblyDataJson(List<? extends MesProductionAssemblyContext> productionAssemblyContextList) {
if (CollectionUtils.isEmpty(productionAssemblyContextList)) return this;
this.assemblyDataJson = JSONObject.toJSONString(productionAssemblyContextList);
isMatchContainer(productionAssemblyContextList);
isMatchRawMix(productionAssemblyContextList);
return this;
}
@ -246,6 +265,15 @@ public class MesProdRuleContext implements Serializable {
return this;
}
//标记装配件是否需要进行原料调配
public MesProdRuleContext isMatchRawMix(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_90.getValue()) == 0)).findFirst();
if (null != optional && optional.isPresent()) this.isMatchRawMix = CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr();
return this;
}
//根据生产线类型返回装配件数据集合
public List<? extends MesProductionAssemblyContext> getProductionAssemblyContextList(MesWorkCenter workCenter) {
if (StringUtils.isEmpty(this.assemblyDataJson)) return null;

@ -87,6 +87,16 @@ public class MesProductionAssemblyNosortContext extends MesProductionAssemblyCon
return this;
}
public MesProductionAssemblyNosortContext assemblySn(String assemblySn) {
this.assemblySn = assemblySn;
return this;
}
public MesProductionAssemblyNosortContext qty(Double qty) {
this.qty = qty;
return this;
}
public MesProductionAssemblyNosortContext assemblySkip() {
this.assemblyStatus = MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_40.getValue();
this.isSkip = CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue();

@ -551,6 +551,8 @@ public class MesPcnExtConstWords {
public static final String NEXT_TRIGGER_EVENT_PRODUCT_SN = "PRODUCT_SN";
// 自定义触发事件: 产出零件
public static final String NEXT_TRIGGER_EVENT_PART_NO = "PART_NO";
// 自定义触发事件: 站点补料
public static final String NEXT_TRIGGER_EVENT_FEEDING = "FEEDING";
// 0
public static final String ZERO_STR = "0";
@ -740,10 +742,11 @@ 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";
// 用于扣料业务中进行LOCK
public static final String LOCK_STATION_CONTEXT = "LOCK_STATION_CONTEXT";
// 用于缺料时进行上料扫描上料条码
public static final String MATCH_STATION_FEED_SCAN_SN_CONTEXT = "MATCH_STATION_FEED_SCAN_SN_CONTEXT";
// 用于缺料时进行上料扫描上料绑定的容器条码

@ -34,7 +34,7 @@
<impp.framework.version>1.0.1-YZ</impp.framework.version>
<i3plus.pojo.version>1.0.0-yfai</i3plus.pojo.version>
<i3plus.platform.version>1.0.0.1-patch</i3plus.platform.version>
<i3plus.mes.pcn.version>1.0.3-yfai</i3plus.mes.pcn.version>
<i3plus.mes.pcn.version>1.0.4-yfai</i3plus.mes.pcn.version>
<log4j2.version>2.17.1</log4j2.version>
</properties>

Loading…
Cancel
Save