# ResistManagerImpl.java

    package com.mycim.server.resist.manager.impl;

    import com.fa.sesa.exception.Assert;
    import com.fa.sesa.exception.Errors;
    import com.fa.sesa.threadlocal.LocalContext;
    import com.mycim.framework.jdbc.Page;
    import com.mycim.framework.oid.IDGenerators;
    import com.mycim.framework.oid.type.IDNames;
    import com.mycim.framework.oid.type.SequenceNames;
    import com.mycim.framework.utils.lang.StringUtils;
    import com.mycim.framework.utils.lang.collections.CollectionUtils;
    import com.mycim.framework.utils.lang.collections.MapUtils;
    import com.mycim.framework.utils.lang.time.DateUtils;
    import com.mycim.server.base.manager.EventManager;
    import com.mycim.server.base.manager.NamedObjectManager;
    import com.mycim.server.base.manager.TransactionLogManager;
    import com.mycim.server.ems.manager.EntityManager;
    import com.mycim.server.resist.dao.ResistDAO;
    import com.mycim.server.resist.manager.ResistManager;
    import com.mycim.server.resist.manager.ResistRcpMappingManager;
    import com.mycim.server.resist.manager.ResistStatusManager;
    import com.mycim.server.status.manager.StatusManager;
    import com.mycim.server.wip.manager.LotManager;
    import com.mycim.utils.CheckRegexUtils;
    import com.mycim.valueobject.ObjectList;
    import com.mycim.valueobject.bas.TransactionLog;
    import com.mycim.valueobject.consts.EventName;
    import com.mycim.valueobject.consts.TransactionNames;
    import com.mycim.valueobject.ems.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.*;
    import java.util.regex.Pattern;

    /**
     * @author yanbing.chen
     * @version 6.0.0
     * @date 2019/10/29
     **/
    @Service
    @Transactional
    public class ResistManagerImpl implements ResistManager {

        @Autowired
        ResistDAO resistDAO;

        @Autowired
        TransactionLogManager transactionLogManager;

        @Autowired
        NamedObjectManager namedObjectManager;

        @Autowired
        EntityManager entityManager;

        @Autowired
        StatusManager statusManager;

        @Autowired
        EventManager eventManager;

        @Autowired
        LotManager lotManager;

        @Autowired
        ResistRcpMappingManager resistRcpMappingManager;

        @Autowired
        ResistStatusManager resistStatusManager;

        @Override
        public Page qryResistByPage(Page page, Map<String, Object> argMap) {
            return resistDAO.qryResistByPage(page, argMap);
        }

        @Override
        public String buildResistErrorInfo(String recipeId, Equipment equipment) {
            StringBuilder sb = new StringBuilder();

            Map<String, Object> argMap = new HashMap<>();
            if (StringUtils.isBlank(equipment.getInstanceId()) || StringUtils.isBlank(recipeId)) {
                return StringUtils.EMPTY;
            }
            String mainEqpt = StringUtils.substringBeforeLast(equipment.getInstanceId(), "_");
            argMap.put("eqptId", mainEqpt);

            Page page = new Page(1, Long.MAX_VALUE);
            page = this.qryResistByPage(page, argMap);

            List<Resist> resistList = (List<Resist>) page.getResults();

            if (CollectionUtils.isNotEmpty(resistList)) {
                for (Resist resist : resistList) {
                    boolean recipeMatchFlag = false;
                    List<ResistRcpMapping> resistRcpMapping = getResistRcpMapping(resist.getResistNo());
                    for (ResistRcpMapping mapping : resistRcpMapping) {
                        String recipe = mapping.getRecipe();
                        if (StringUtils.isNotBlank(recipeId)) {
                            String regex = recipe
                                    .replaceAll(CheckRegexUtils.LOT_SAMPLING_SPLIT_KEY, CheckRegexUtils.REPLACE_SPLIT_KEY)
                                    .replaceAll(CheckRegexUtils.REGEX_KEY, CheckRegexUtils.LOT_SAMPLING_REPLACE_REGEX_KEY);

                            if ((Pattern
                                    .matches(CheckRegexUtils.REGEX_START + regex + CheckRegexUtils.REGEX_END, recipeId)) ||
                                    StringUtils.equals(CheckRegexUtils.SEARCH_MATCH_KEY, recipeId)) {
                                recipeMatchFlag = true;
                            }
                        }
                    }
                    if (recipeMatchFlag) {

                        //resist过期与EMPTY，HOLD的处理方式一致，expireFlag用于提示过期
                        boolean expireFlag = DateUtils.parse(resist.getActualExpireDate(), DateUtils.DATE_FORMAT4DATE)
                                                      .before(new Date());
                        if (!StringUtils.equalsIgnoreCase(resist.getCurrentEntityStatus(), ResistEnum.INUSE.getValue()) ||
                                expireFlag) {
                            sb.append("Resist: ").append(resist.getInstanceId());
                            sb.append(" the recipe is matched Resist Rcp Mapping!");
                            sb.append(" status is ").append(resist.getCurrentEntityStatus());
                            sb.append("!  ");
                            if (expireFlag) {
                                sb.append(" Resist reached expired time !");
                            }

                        }
                    }

                }
            }
            return sb.toString();
        }

        @Override
        public Boolean hasVendorBarodeReceived(String vendorBarcode) {
            return resistDAO.hasVendorBarodeReceived(vendorBarcode);
        }

        @Override
        public Boolean hasResistIdReceived(String resistId) {
            return resistDAO.hasResistIdReceived(resistId);
        }

        @Override
        public Long getMaxSerialNumber(String resistNo) {
            return resistDAO.getMaxSerialNumber(resistNo);
        }

        @Override
        public void addResist(Resist resist) {
            long instanceRrn = 0;

            // resist resist_h 以及状态初始
            TransactionLog transactionLog = transactionLogManager
                    .startTransactionLog(resist.getModifyBy(), TransactionNames.CREATE_KEY);
            instanceRrn = Long
                    .parseLong(IDGenerators.get(IDNames.SEQUENCE).generateId(SequenceNames.MODULE_SEQ_OBJECT_RRN));
            resist.setInstanceRrn(instanceRrn);
            resist.setMaskSize(StringUtils.EMPTY);

            resist.setPrevEntityStatus(StringUtils.EMPTY);

            resist.setTransRrn(transactionLog.getTransRrn());
            resist.setTransSequence(1);
            resist.setTransId(transactionLog.getTransId());
            resistDAO.addResist(resist);
            //初始化resist状态
            resistStatusManager.initResistStatus(EventName.INIT_RESIST, resist);
            ResistStatus resistStatus = new ResistStatus();
            resistStatus.setResistSysRrn(instanceRrn);
            ResistStatus resistStatusEnd = resistStatusManager.getResistStatus(resistStatus);
            resist.setCurrentEntityStatus(resistStatusEnd.getCurrentStatus());

            this.updateResistAvailability(resist, EventName.INIT_RESIST);
            //插入历史表
            addResistH(resist);

            transactionLogManager.markTransactionLog(transactionLog);
        }

        @Override
        public Resist getResistByResistId(String instanceId) {
            Resist resist = resistDAO.getResistByResistId(instanceId);

            if (resist != null && resist.getInstanceRrn() > 0) {
                ResistStatus resistStatus = new ResistStatus();
                resistStatus.setResistSysRrn(resist.getInstanceRrn());
                resist.setPrevEntityStatus(resistStatusManager.getPreResistStatus(resistStatus));// 释放的时候使用
            }

            return resist;
        }

        @Override
        public Resist getRecommendResist(Resist resist) {
            return resistDAO.getRecommendResist(resist);
        }

        @Override
        public void modifyResistExpireDate(Resist resist) {
            TransactionLog transactionLog = transactionLogManager
                    .startTransactionLog(resist.getModifyBy(), TransactionNames.MODIFY_KEY);
            resistDAO.modifyResistExpireDate(resist);
            ResistStatus resistStatus = new ResistStatus();
            resistStatus.setResistSysRrn(resist.getInstanceRrn());
            resistStatus = resistStatusManager.getResistStatus(resistStatus);
            resist.setPrevEntityStatus(resistStatus.getCurrentStatus());
            resist.setCurrentEntityStatus(resistStatus.getCurrentStatus());
            resist.setTransRrn(transactionLog.getTransRrn());
            resist.setTransSequence(1);
            resist.setTransId(transactionLog.getTransId());
            addResistH(resist);
            transactionLogManager.markTransactionLog(transactionLog);
        }

        @Override
        public void changeResistStatus(Map transMap) {
            Resist resist = (Resist) transMap.get("resist");
            String eventId = MapUtils.getString(transMap, "eventId");
            String comments = MapUtils.getString(transMap, "comments");
            TransactionLog transactionLog = transactionLogManager
                    .startTransactionLog(resist.getModifyBy(), TransactionNames.MODIFY_KEY);

            ResistStatus resistStatus = new ResistStatus();
            resistStatus.setResistSysRrn(resist.getInstanceRrn());
            resistStatus = resistStatusManager.getResistStatus(resistStatus);
            String currentStatus = resistStatus.getCurrentStatus();
            long transRrn = resistStatusManager.changeResistStatus(resist, ObjectList.RESIST_KEY, eventId, comments);
            ResistStatus targetStatus = resistStatusManager.getResistStatus(resistStatus);

            resistDAO.modifyResistExpireDate(resist);
            resist.setTransRrn(transRrn);
            resist.setTransSequence(1);
            resist.setPrevEntityStatus(currentStatus);
            resist.setCurrentEntityStatus(targetStatus.getCurrentStatus());
            resist.setComments(comments);
            resist.setTransId(transactionLog.getTransId());
            addResistH(resist);
            transactionLogManager.markTransactionLog(transactionLog);
        }

        @Override
        public void deleteResist(Resist resist) {
            TransactionLog transactionLog = transactionLogManager
                    .startTransactionLog(resist.getModifyBy(), TransactionNames.DELETE_KEY);

            //namedObjectExtManager.deleteNamedObjectExt(resist.getInstanceRrn());
            //entityManager.deleteEntity(new Entity(resist.getInstanceRrn()));
            resist.setTransRrn(transactionLog.getTransRrn());
            resist.setModifyTime(new Date());
            resist.setTransSequence(1);
            resist.setTransId(transactionLog.getTransId());
            //插入历史
            addResistH(resist);
            resistDAO.deleteResist(resist.getInstanceRrn());
            transactionLogManager.markTransactionLog(transactionLog);
        }

        @Override
        public void resistMoveInAndRemove(String eventId, Resist resist) {
            ResistStatus resistStatus = new ResistStatus();
            resistStatus.setResistSysRrn(resist.getInstanceRrn());
            resistStatus = resistStatusManager.getResistStatus(resistStatus);
            TransactionLog transactionLog = transactionLogManager
                    .startTransactionLog(resist.getModifyBy(), TransactionNames.MODIFY_KEY);
            Long transRrn = resistStatusManager
                    .changeResistStatus(resist, ObjectList.RESIST_KEY, eventId, resist.getComments());

            ResistStatus targetStatus = resistStatusManager.getResistStatus(resistStatus);

            resist.setTransRrn(transRrn);
            resist.setTransSequence(1);
            resist.setPrevEntityStatus(resistStatus.getCurrentStatus());
            resist.setCurrentEntityStatus(targetStatus.getCurrentStatus());
            resist.setTransId(transactionLog.getTransId());
            resistDAO.modifyResistEqptInfo(resist);
            addResistH(resist);
            transactionLogManager.markTransactionLog(transactionLog);
        }

        @Override
        public void resistExchange(Resist oldResist, Resist newResist, String targetEventIdForOld,
                                   String targetEventIdForNew) {
            ResistStatus resistStatus = new ResistStatus();
            resistStatus.setResistSysRrn(oldResist.getInstanceRrn());
            resistStatus = resistStatusManager.getResistStatus(resistStatus);
            TransactionLog transactionLog = transactionLogManager
                    .startTransactionLog(LocalContext.getUserId(), TransactionNames.MODIFY_KEY);

            String comments = "Exchange Old resist,new resist is: " + newResist.getInstanceId();
            Long transRrn = resistStatusManager
                    .changeResistStatus(oldResist, ObjectList.RESIST_KEY, targetEventIdForOld, comments);
            ResistStatus targetStatus = resistStatusManager.getResistStatus(resistStatus);

            oldResist.setTransRrn(transRrn);
            oldResist.setTransSequence(1);
            oldResist.setPrevEntityStatus(resistStatus.getCurrentStatus());
            oldResist.setCurrentEntityStatus(targetStatus.getCurrentStatus());
            oldResist.setComments(comments);
            oldResist.setTransId(transactionLog.getTransId());
            resistDAO.modifyResistEqptInfo(oldResist);
            addResistH(oldResist);

            resistStatus.setResistSysRrn(newResist.getInstanceRrn());
            resistStatus = resistStatusManager.getResistStatus(resistStatus);

            comments = "Exchange Old resist,old resist is: " + oldResist.getInstanceId();

            transRrn = resistStatusManager
                    .changeResistStatus(newResist, ObjectList.RESIST_KEY, targetEventIdForNew, comments);
            targetStatus = resistStatusManager.getResistStatus(resistStatus);
            newResist.setTransRrn(transRrn);
            newResist.setTransSequence(1);
            newResist.setPrevEntityStatus(resistStatus.getCurrentStatus());
            newResist.setCurrentEntityStatus(targetStatus.getCurrentStatus());
            newResist.setComments(comments);
            newResist.setTransId(transactionLog.getTransId());
            resistDAO.modifyResistEqptInfo(newResist);
            addResistH(newResist);
            transactionLogManager.markTransactionLog(transactionLog);
        }

        @Override
        public Page qryResistHistByPage(Map<String, Object> paramMap, Page page) {
            if (StringUtils.isNotBlank(MapUtils.getString(paramMap, "instanceId"))) {
                paramMap.put("instanceId",
                             StringUtils.replace(MapUtils.getString(paramMap, "instanceId"), "*", "%").toString());
            }

            if (StringUtils.isNotBlank(MapUtils.getString(paramMap, "resistNo"))) {
                paramMap.put("resistNo",
                             StringUtils.replace(MapUtils.getString(paramMap, "resistNo"), "*", "%").toString());
            }

            if (StringUtils.isNotBlank(MapUtils.getString(paramMap, "materialNo"))) {
                paramMap.put("materialNo",
                             StringUtils.replace(MapUtils.getString(paramMap, "materialNo"), "*", "%").toString());
            }

            if (StringUtils.isNotBlank(MapUtils.getString(paramMap, "resistName"))) {
                paramMap.put("resistName",
                             StringUtils.replace(MapUtils.getString(paramMap, "resistName"), "*", "%").toString());
            }

            if (StringUtils.isNotBlank(MapUtils.getString(paramMap, "eqptId"))) {
                paramMap.put("eqptId", StringUtils
                        .trimToUpperCase(StringUtils.replace(MapUtils.getString(paramMap, "eqptId"), "*", "%").toString()));
            }

            if (StringUtils.isNotBlank(MapUtils.getString(paramMap, "modifyBy"))) {
                paramMap.put("modifyBy",
                             StringUtils.replace(MapUtils.getString(paramMap, "modifyBy"), "*", "%").toString());
            }

            if (StringUtils.isNotBlank(MapUtils.getString(paramMap, "modifyStartDate"))) {
                paramMap.put("modifyStartDate",
                             StringUtils.replace(MapUtils.getString(paramMap, "modifyStartDate"), "*", "%").toString());
            }

            if (StringUtils.isNotBlank(MapUtils.getString(paramMap, "modifyEndDate"))) {
                paramMap.put("modifyEndDate",
                             StringUtils.replace(MapUtils.getString(paramMap, "modifyEndDate"), "*", "%").toString());
            }

            return resistDAO.qryResistHistByPage(paramMap, page);
        }

        @Override
        public void defrostAllResist() {
            Map<String, Object> argMap = new HashMap<String, Object>();
            argMap.put("resistStatus", Arrays.asList(new String[]{ResistEnum.DEFROSTING.getValue()}));

            Page page = new Page(1, Long.MAX_VALUE);
            page = this.qryResistByPage(page, argMap);

            Collection resistList = page.getResults();

            String eventId = EventName.RESIST_DEFROSTING_TO_READY;

            if (resistList != null && !resistList.isEmpty()) {

                Iterator<Resist> it = resistList.iterator();

                while (it.hasNext()) {

                    Resist resist = it.next();

                    if (resist.getCreateTime().getTime() + DateUtils.getSecondsTime(resist.getDefrostTime()) * 1000L <=
                            System.currentTimeMillis()) {
                        Map<String, Object> transMap = new HashMap<String, Object>();

                        resist.setModifyBy("SYSTEM");
                        transMap.put("resist", resist);
                        transMap.put("eventId", eventId);
                        transMap.put("comments", "Auto defrosting");
                        this.changeResistStatus(transMap);
                    }
                }
            }
        }

        @Override
        public void holdExpireResist() {
            Map<String, Object> argMap = new HashMap<String, Object>();
            argMap.put("resistStatus",
                       Arrays.asList(new String[]{ResistEnum.READY.getValue(), ResistEnum.INUSE.getValue()}));

            Page page = new Page(1, Long.MAX_VALUE);
            page = this.qryResistByPage(page, argMap);

            Collection resistList = page.getResults();

            String targetResistStatus = ResistEnum.HOLD.getValue();

            if (resistList != null && !resistList.isEmpty()) {
                Iterator<Resist> it = resistList.iterator();

                while (it.hasNext()) {
                    Resist resist = it.next();

                    if (DateUtils.parse(resist.getActualExpireDate(), DateUtils.DATE_FORMAT4DATE).before(new Date())) {
                        Map<String, Object> transMap = new HashMap<String, Object>();
                        Long facilityRrn = LocalContext.getFacilityRrn();
                        String targetEventId = getResistEventIdBy2Status(resist.getInstanceRrn(),
                                                                         resist.getCurrentEntityStatus(),
                                                                         targetResistStatus);

                        if (StringUtils.isNotEmpty(targetEventId)) {
                            resist.setModifyBy("SYSTEM");
                            transMap.put("facilityRrn", facilityRrn);
                            transMap.put("resist", resist);
                            transMap.put("eventId", targetEventId);
                            transMap.put("comments", "Auto hold expire resist");
                            resist.setComments("Auto hold expire resist");

                            this.changeResistStatus(transMap);

                            if (StringUtils
                                    .equalsIgnoreCase(resist.getCurrentEntityStatus(), ResistEnum.INUSE.getValue()) &&
                                    StringUtils.isNotBlank(resist.getEqptId())) {

                                Long entityRrn = namedObjectManager
                                        .getNamedObjectRrn(resist.getEqptId(), facilityRrn, ObjectList.ENTITY_KEY);

                                String currentStatus = entityManager.getEntityCurrentStatus(entityRrn);

                                String targetStatus = EventName.WAIT_ENG;

                                String eventId = eventManager
                                        .getEventIdBy2Status(facilityRrn, entityRrn, currentStatus, targetStatus);

                                // 表示需要从当前状态切换成wait eng
                                if (StringUtils.isNotBlank(eventId)) {

                                    statusManager
                                            .changePCDStatusByEvent(facilityRrn, "SYSTEM", entityRrn, ObjectList.ENTITY_KEY,
                                                                    eventId, "Resist: " + resist.getInstanceId() + " has " +
                                                                            "reached expire time,auto wait " + "eng");

                                    Map holdInfo = new HashMap();
                                    holdInfo.put("holdCode", "WAIT_ENG");
                                    holdInfo.put("holdReasons",
                                                 "Resist: " + resist.getInstanceId() + " has reached expire time,eqpt " +
                                                         "auto wait eng");
                                    holdInfo.put("userId", "SYSTEM");
                                    lotManager.holdRunningLotByEqpWaitENG(entityRrn, holdInfo);
                                }
                            }
                        }
                    }
                }
            }
        }

        @Override
        public void updateResistAvailability(Resist resist, String eventId) {
            long eventRrn = namedObjectManager.getNamedObjectRrn(eventId, resist.getNamedSpace(), ObjectList.EVENT_KEY);
            Assert.isFalse(eventRrn == 0, Errors.create().content("Event: {} not found").args(eventId).build());
            resistDAO.updateResistAvailability(eventRrn, resist.getInstanceRrn());
        }

        @Override
        public Resist getResistByResistRrn(long resistRrn) {
            return resistDAO.getResistByResistRrn(resistRrn);
        }

        @Override
        public void addResistH(Resist resist) {
            Resist addResistH = resistDAO.getResistByResistRrn(resist.getInstanceRrn());
            addResistH.buildExpireInfo();
            resist.setExpireDate(addResistH.getActualExpireDate());
            resistDAO.addResistH(resist);
        }

        @Override
        public String getResistEventIdBy2Status(long resistRrn, String currentStatus, String targetStatus) {
            List<Map> eventList = resistDAO.getResistEventIdBy2Status(resistRrn, currentStatus, targetStatus);
            if (CollectionUtils.isNotEmpty(eventList)) {
                for (Map<String, Object> eventMap : eventList) {
                    return MapUtils.getString(eventMap, "eventId", StringUtils.EMPTY);
                }
            }
            return StringUtils.EMPTY;
        }

        @Override
        public List<EventModel> getResistEventModels(long eventRrn, long resistRrn) {
            return resistDAO.getResistEventModels(eventRrn, resistRrn);
        }

        private List<ResistRcpMapping> getResistRcpMapping(String resistNo) {
            Page page = new Page(1, Long.MAX_VALUE);
            ResistRcpMapping resistRcpMapping = new ResistRcpMapping(resistNo, null);
            page = resistRcpMappingManager.qryResistRcpMappingByPage(resistRcpMapping, page);
            return (List<ResistRcpMapping>) page.getResults();
        }

    }