SorterExecInqManagerImpl.java

package com.mycim.server.sorter.exec.manager.impl;

import com.fa.sesa.i18n.I18nUtils;
import com.fa.sesa.threadlocal.LocalContext;
import com.fa.sesa.threadlocal.LocalContextNames;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.CollectionUtils;
import com.mycim.server.carrier.manager.CarrierManager;
import com.mycim.server.ems.manager.EquipmentManager;
import com.mycim.server.sorter.exec.manager.SorterExecInqManager;
import com.mycim.server.sorter.manager.SorterManager;
import com.mycim.server.spec.manager.ProcessSpecItemManager;
import com.mycim.server.system.manager.ReferenceFileManager;
import com.mycim.server.wip.manager.LotInqManager;
import com.mycim.server.wip.manager.LotQueryManager;
import com.mycim.server.wip.manager.RunCardQueryManager;
import com.mycim.server.wip.manager.job.EquipmentCheckManager;
import com.mycim.utils.SorterUtils;
import com.mycim.utils.WipUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.consts.ReferenceDetailNames;
import com.mycim.valueobject.consts.ReferenceFileConst;
import com.mycim.valueobject.consts.SorterEnum;
import com.mycim.valueobject.ems.Carrier;
import com.mycim.valueobject.ems.Equipment;
import com.mycim.valueobject.runcard.util.RunCardUtils;
import com.mycim.valueobject.sorter.SorterModel;
import com.mycim.valueobject.sys.ReferenceFileDetail;
import com.mycim.valueobject.wip.Lot;
import com.mycim.valueobject.wip.LotRunCardStore;
import com.mycim.valueobject.wip.LotStatus;
import com.mycim.valueobject.wip.SRCLotSpecialStep;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.regex.Matcher;
import java.util.stream.Collectors;

@Service
@Transactional
public class SorterExecInqManagerImpl implements SorterExecInqManager {
    @Autowired
    SorterManager sorterManager;

    @Autowired
    EquipmentManager equipmentManager;

    @Autowired
    EquipmentCheckManager equipmentCheckManager;

    @Autowired
    CarrierManager carrierManager;

    @Autowired
    LotInqManager lotInqManager;

    @Autowired
    LotQueryManager lotQueryManager;

    @Autowired
    ProcessSpecItemManager processSpecItemManager;

    @Autowired
    ReferenceFileManager referenceFileManager;

    @Autowired
    RunCardQueryManager runCardQueryManager;

    @Override
    public SorterModel checkSorterModelAndCreateInLineSorterJob(Lot lot, String equipmentId, String targetCarrierId) {
        SorterModel sorterModel = checkSorterModel(lot.getCarrierId(), equipmentId);
        if (sorterModel.getCanCreate()) {
            sorterManager.createSorterJobByInLine(sorterModel, lot, targetCarrierId);
        }
        return sorterModel;
    }

    @Override
    public SorterModel checkSorterModel(String carrierId, String equipmentId) {
        SorterModel sorterModel = new SorterModel(SorterEnum.Type.OFFLINE.getName());
        // 公用check
        //1.先check设备是否为Sorter 设备
        Equipment equipment = equipmentManager.getEquipment(equipmentId, LocalContext.getFacilityRrn());
        String msg = SorterUtils.checkEqptSorterFlag(equipment);
        if (StringUtils.isNotEmptyTrim(msg)) {
            sorterModel.setMsg(msg);
        }
        //2.check Carrier
        if (StringUtils.isEmpty(carrierId)) {
            return sorterModel;
        }
        Carrier carrier = carrierManager.getCarrier(LocalContext.getFacilityRrn(), carrierId);
        //3.check Lot 状态
        //3.1 新增前置check,避免一个CST下多个Lot
        List<Lot> lots = lotInqManager.getLotListByCarrierRrn(carrier.getInstanceRrn());
        if (CollectionUtils.isEmpty(lots) || lots.size() > 1) {
            return sorterModel;
        }
        //3.2 check Lot 状态
        Lot lot = lotQueryManager.getLotByCarrierId(carrierId, LocalContext.getFacilityRrn());
        // MAINRC 转换
        if (LotStatus.isRunCardHold(lot.getLotStatus())) {
            lot = lotInqManager.getLot(RunCardUtils.buildMainRcLotId(lot.getLotId()));
        }
        if (!StringUtils.equalsIgnoreCase(lot.getLotStatus(), LotStatus.WAITING)) {
            return sorterModel;
        }
        //4.check Lot 当站是否在该设备可用
        if (StringUtils.isNotEmptyTrim(
                equipmentCheckManager.checkEqptJobByOperation(lot.getOperationRrn(), equipment.getInstanceRrn()))) {
            return sorterModel;
        }
        //5.check Eqpt 状态
        if (StringUtils.isNotEmptyTrim(equipmentCheckManager.checkEqptStatus(lot, equipment))) {
            return sorterModel;
        }
        //6. 预留不同的Job Type卡控
        //6.1.check Job Type
        if (isFlipSide(lot, sorterModel)) {
            return sorterModel;
        }

        if (isReadT7Code(lot, sorterModel)) {
            return sorterModel;
        }

        if (!StringUtils.isNotEmptyTrim(msg) && isExchange(lot, sorterModel)) {
            return sorterModel;
        }
        return sorterModel;
    }

    private boolean isExchange(Lot lot, SorterModel sorterModel) {
        String transModule = LocalContext.get(LocalContextNames.TRANS_MODULE_KEY);
        // manual 不做exchange
        if (WipUtils.MANUAL.equalsIgnoreCase(transModule)) {
            return false;
        }

        //如果是runcard lot 暂时跳过
        if (RunCardUtils.checkLotIdIsRunCardLot(lot.getLotId())) {
           return false;
        }
        String processLocation = StringUtils.EMPTY;
        processLocation = getProcessLocationByProcess(lot);
        String carrierType = referenceFileManager.getRefFileValue(ReferenceDetailNames.PROCESS_LOCARION_CARRIER_TYPE,
                                                           processLocation, ReferenceFileConst.DATA_1_VALUE);
        Matcher mathcher = WipUtils.PCDPATERN.matcher(carrierType);
        Boolean match = mathcher.matches();
        if (match) {
            sorterModel.setSorterType(SorterEnum.Type.INLINE.getName());
            sorterModel.setJobType(SorterEnum.Constant.EXCHANGE);
            return true;
        }else {
            return false;
        }
    }

    private boolean isFlipSide(Lot lot, SorterModel sorterModel) {
        //判断lot
        String flipType;
        if (RunCardUtils.checkLotIdIsRunCardLot(lot.getLotId())) {
            flipType = getFlipTypeByRunCard(lot);
        } else {
            flipType = getFlipTypeByProcess(lot);
        }

        // check 是否需要翻面
        if (StringUtils.contains(flipType, '-')) {
            // check Flip 合法性
            checkFlipType(lot, flipType, sorterModel);
            sorterModel.setSorterType(SorterEnum.Type.INLINE.getName());
            sorterModel.setJobType(SorterEnum.Constant.FLIP_SIDE);
            return true;
        } else {
            return false;
        }
    }

    private void checkFlipType(Lot lot, String flipType, SorterModel sorterModel) {
        // 拿到所有Flip Type
        List<String> flipTypes = referenceFileManager.getRefFileValues(ReferenceDetailNames.SORTER_FLIP_TYPE,
                                                                       LocalContext.getFacilityRrn()).stream()
                                                     .map(ReferenceFileDetail::getKey1Value)
                                                     .collect(Collectors.toList());
        List<String> strList = StringUtils.splitAsList(flipType, "-");
        // 验证数量是否正确
        if (strList.size() != 2) {
            sorterModel.appendMsg(I18nUtils.getMessage(MessageIdList.SORTER_REFERENCE_FILE_ERROR,
                                                       "ReferenceFile:{} have error data exist. --> {}",
                                                       ReferenceDetailNames.SORTER_FLIP_TYPE, flipType));
            return;
        }

        // 验证两边Flip Type是否存在
        for (String s : strList) {
            if (!flipTypes.contains(s)) {
                sorterModel.appendMsg(
                        I18nUtils.getMessage(MessageIdList.SORTER_FLIP_TYPE_NOT_EXIST, "{} Flip Type not exist", s));
                return;
            }
        }

        //验证当前Lot的Flip Type是否与翻面的类型一致
        if (!StringUtils.equalsIgnoreCase(strList.get(0), lot.getFlipType())) {
            sorterModel.appendMsg(I18nUtils.getMessage(MessageIdList.SORTER_FLIP_TYPE_NOT_MATCH,
                                                       "The current Flip Type {} is inconsistent with the" + " " +
                                                               "expected Flip Type {} and cannot be done " + "Flip" +
                                                               " Side", lot.getFlipType(), strList.get(0)));
        }
    }

    private String getFlipTypeByRunCard(Lot lot) {
        //获取SRC中当前flip type
        LotRunCardStore lotStore = runCardQueryManager.getSplitRunCardLotStore(lot.getLotRrn());
        Long lotSpecialStepRrn = lotStore.getLotSpecialStepRrn();
        SRCLotSpecialStep lotSpecialStep = runCardQueryManager
                .getLotSplitRunCardSpecialStep(lotSpecialStepRrn, lotStore.getStepSequence());
        if (lotSpecialStep != null && lotSpecialStep.getLotSpecialStepRrn() > 0) {
            return StringUtils.isNotBlank(lotSpecialStep.getFlipType())? lotSpecialStep.getFlipType() : StringUtils.EMPTY;
        }
        return StringUtils.EMPTY;
    }

    private String getFlipTypeByProcess(Lot lot) {
        return processSpecItemManager.getFlipType(lot.getProcessRrn(), lot.getProcessVersion(), lot.getRouteRrn(),
                                                  lot.getOperationRrn());
    }

    private String getProcessLocationByProcess(Lot lot) {
        return processSpecItemManager.getProcessLocation(lot.getProcessRrn(), lot.getProcessVersion(),
                                                         lot.getRouteRrn(), lot.getRouteVersion(), lot.getOperationRrn());
    }

    private boolean isReadT7Code(Lot lot, SorterModel sorterModel) {
        //check step是否在类表$$INLINE_READ_T7CODE中存在
        List<String> stepIds = referenceFileManager.getRefFileValues(ReferenceDetailNames.READ_CUSTOMER_T7CODE_STEP,
                                                                     LocalContext.getFacilityRrn()).stream()
                                                   .map(ReferenceFileDetail::getKey1Value).collect(Collectors.toList());

        if (stepIds.contains(lot.getOperationId())) {
            sorterModel.setSorterType(SorterEnum.Type.INLINE.getName());
            sorterModel.setJobType(SorterEnum.Constant.READ_T7CODE);
            return true;
        } else {
            return false;
        }

    }


}