# ResequenceContextValueManagerImpl.java

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

    import com.fa.sesa.threadlocal.LocalContext;
    import com.mycim.framework.utils.lang.StringUtils;
    import com.mycim.framework.utils.lang.math.NumberUtils;
    import com.mycim.server.base.manager.NamedObjectManager;
    import com.mycim.server.ctx.exec.dao.ResequenceContextValueManagerDAO;
    import com.mycim.server.ctx.exec.manager.ResequenceContextValueManager;
    import com.mycim.server.ctx.manager.ContextValueManager;
    import com.mycim.valueobject.ObjectList;
    import com.mycim.valueobject.consts.ContextNames;
    import com.mycim.valueobject.prp.ContextValue;
    import com.mycim.valueobject.prp.ProcessFlowSeqDto;
    import com.mycim.valueobject.prp.ResequenceContextValue;
    import com.mycim.valueobject.wip.Lot;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;

    /**
     * @author Johnson.Wang
     * @version 6.0.0
     * @date 2019/9/1
     **/
    @Service
    @Transactional
    public class ResequenceContextValueManagerImpl implements ResequenceContextValueManager {

        private final NamedObjectManager namedObjectManager;

        private final ContextValueManager contextValueManager;

        private final ResequenceContextValueManagerDAO resequenceContextValueManagerDAO;

        public ResequenceContextValueManagerImpl(NamedObjectManager namedObjectManager,
                                                 ContextValueManager contextValueManager,
                                                 ResequenceContextValueManagerDAO resequenceContextValueManagerDAO) {
            this.namedObjectManager = namedObjectManager;
            this.contextValueManager = contextValueManager;
            this.resequenceContextValueManagerDAO = resequenceContextValueManagerDAO;
        }

        @Override
        public String getFlowSeq(Long processRrn, Integer processVersion, Long operationRrn, Long routeRrn) {
            ResequenceContextValue resequenceContextValue = new ResequenceContextValue();
            resequenceContextValue.setProcessRrn(processRrn);
            resequenceContextValue.setOperationRrn(operationRrn);
            resequenceContextValue.setRouteRrn(routeRrn);
            resequenceContextValue.setProcessVersion(processVersion);
            resequenceContextValue.setContextRrn(namedObjectManager.getNamedObjectRrn(resequenceContextValue.getContextId(),
                                                                                      LocalContext.getFacilityRrn(),
                                                                                      ObjectList.CONTEXT_KEY));

            ContextValue contextValue = contextValueManager.getContextValueNoFilter(resequenceContextValue);
            if (contextValue != null) {
                contextValue = contextValueManager.filterContextValueToId(contextValue);
                return contextValue.getResultValue1();
            }
            return StringUtils.EMPTY;
        }

        @Override
        public String getFlowSeqContainsAllStatus(Long processRrn, Integer processVersion, Long operationRrn,
                                                  Long routeRrn) {
            ResequenceContextValue resequenceContextValue = new ResequenceContextValue();
            resequenceContextValue.setProcessRrn(processRrn);
            resequenceContextValue.setOperationRrn(operationRrn);
            resequenceContextValue.setRouteRrn(routeRrn);
            resequenceContextValue.setProcessVersion(processVersion);
            resequenceContextValue.setContextRrn(namedObjectManager.getNamedObjectRrn(resequenceContextValue.getContextId(),
                                                                                      LocalContext.getFacilityRrn(),
                                                                                      ObjectList.CONTEXT_KEY));

            String flowSeq = resequenceContextValueManagerDAO.getFlowSeq(resequenceContextValue);
            return flowSeq == null ? StringUtils.EMPTY : flowSeq;
        }

        @Override
        public List<Map<String, Object>> flowSeqList(Long contextRrn, Long processRrn, Integer processVersion,
                                                     Long routeRrn, Long operationRrn, String status) {
            return resequenceContextValueManagerDAO
                    .flowSeqList(contextRrn, processRrn, processVersion, routeRrn, operationRrn, status);
        }

        @Override
        public boolean isActiveFlowSeqForLastVersion(Long contextRrn, Long processRrn, Integer processVersion,
                                                     Long routeRrn, Long operationRrn, String flowSeq) {
            return resequenceContextValueManagerDAO
                    .isActiveFlowSeqForLastVersion(contextRrn, processRrn, processVersion, routeRrn, operationRrn, flowSeq);
        }

        /**
         * Get Operation RRN And Route RRN by specifying the process version of Flow Seq
         *
         * @param processRrn
         * @param processVersion
         * @param flowSeq
         * @return {@code String[RouteRrn, OperationRrn]} the given flowSeq's Operation RRN and Route RRN
         */
        @Override
        public String[] getOperationAndRouteRrnInSpecifyVersionByFlowSeq(Long processRrn, Integer processVersion,
                                                                         String flowSeq) {
            ResequenceContextValue resequenceContextValue = buildNewResequenceContextValue(processRrn, processVersion,
                                                                                           flowSeq);

            List<ContextValue> contextValues = contextValueManager.getContextValuesByKeyAndValue(resequenceContextValue);
            if (!contextValues.isEmpty() && contextValues.size() == 1) {
                ContextValue contextValue = contextValues.iterator().next();
                return new String[]{contextValue.getContextKey3(), contextValue.getContextKey4()};
            }

            return new String[]{};
        }

        @Override
        public String buildContextValue4FlowSeq(Long facility, Lot lot) {
            String flowSeq = StringUtils.EMPTY;
            ResequenceContextValue flowSeqContextValue = new ResequenceContextValue();
            flowSeqContextValue.setProcessRrn(lot.getProcessRrn());
            flowSeqContextValue.setOperationRrn(lot.getOperationRrn());
            flowSeqContextValue.setRouteRrn(lot.getRouteRrn());
            flowSeqContextValue.setProcessVersion(lot.getProcessVersion());

            flowSeqContextValue.setContextRrn(namedObjectManager.getNamedObjectRrn(ContextNames.RESEQUENCE_CONTEXT,
                                                                                   namedObjectManager
                                                                                           .getNamedSpace(facility,
                                                                                                          ObjectList.CONTEXT_KEY),
                                                                                   ObjectList.CONTEXT_KEY));

            ContextValue contextValue = contextValueManager.getContextValueNoFilter(flowSeqContextValue);
            if (contextValue != null) {
                flowSeq = contextValue.getResultValue1();
            }
            return flowSeq;
        }

        @Override
        public List<ContextValue> getFlowSeqContextValueList(long processRrn, int processVersion) {
            long facilityRrn = LocalContext.getFacilityRrn();
            ResequenceContextValue resequenceContextValue = new ResequenceContextValue();
            resequenceContextValue.setContextRrn(namedObjectManager.getNamedObjectRrn(resequenceContextValue.getContextId(),
                                                                                      facilityRrn, ObjectList.CONTEXT_KEY));

            resequenceContextValue.setProcessRrn(processRrn);
            resequenceContextValue.setProcessVersion(processVersion);

            return contextValueManager.getContextValuesByContextKey(resequenceContextValue);
        }

        @Override
        public ResequenceContextValue buildNewResequenceContextValue() {
            ResequenceContextValue contextValue = new ResequenceContextValue();
            contextValue.setContextRrn(namedObjectManager.getNamedObjectRrn(contextValue.getContextId(),
                                                                            LocalContext.getFacilityRrn(),
                                                                            ObjectList.CONTEXT_KEY));
            return contextValue;
        }

        @Override
        public List<ProcessFlowSeqDto> getProcessFlowSeqsForProcess(Long processRrn, Integer processVersion) {
            List<ProcessFlowSeqDto> processFlowSeqs = new ArrayList<>();

            for (ContextValue contextValue : getFlowSeqContextValueList(processRrn, processVersion)) {
                ProcessFlowSeqDto processFlowSeq = new ProcessFlowSeqDto();

                processFlowSeq.setContextRrn(contextValue.getContextRrn());

                processFlowSeq.setProcessRrn(NumberUtils.toLong(contextValue.getContextKey1()));
                processFlowSeq.setProcessVersion(NumberUtils.toInt(contextValue.getContextKey2()));
                processFlowSeq.setRouteRrn(NumberUtils.toLong(contextValue.getContextKey3()));
                processFlowSeq.setOperationRrn(NumberUtils.toLong(contextValue.getContextKey4()));

                processFlowSeq.setFlowSeq(contextValue.getResultValue1());
                processFlowSeq.setStatus(contextValue.getStatus());

                processFlowSeqs.add(processFlowSeq);
            }

            return processFlowSeqs;
        }

        public ResequenceContextValue buildNewResequenceContextValue(Long processRrn, Integer processVersion,
                                                                     String flowSeq) {
            ResequenceContextValue resequenceContextValue = new ResequenceContextValue();
            resequenceContextValue.setContextRrn(namedObjectManager.getNamedObjectRrn(resequenceContextValue.getContextId(),
                                                                                      LocalContext.getFacilityRrn(),
                                                                                      ObjectList.CONTEXT_KEY));

            resequenceContextValue.setProcessRrn(processRrn);
            resequenceContextValue.setProcessVersion(processVersion);
            resequenceContextValue.setResultValue1(flowSeq);
            return resequenceContextValue;
        }

        @Override
        public String getFlowSeqForUnfrozen(Long processRrn, Integer processVersion, Long operationRrn, Long routeRrn) {
            ResequenceContextValue resequenceContextValue = new ResequenceContextValue();
            resequenceContextValue.setProcessRrn(processRrn);
            resequenceContextValue.setOperationRrn(operationRrn);
            resequenceContextValue.setRouteRrn(routeRrn);
            resequenceContextValue.setProcessVersion(processVersion);
            resequenceContextValue.setContextRrn(namedObjectManager.getNamedObjectRrn(resequenceContextValue.getContextId(),
                                                                                      LocalContext.getFacilityRrn(),
                                                                                      ObjectList.CONTEXT_KEY));

            ContextValue contextValue = contextValueManager.getContextValueNoFilterForUnfrozen(resequenceContextValue);
            if (contextValue != null) {
                contextValue = contextValueManager.filterContextValueToId(contextValue);
                return contextValue.getResultValue1();
            }
            return StringUtils.EMPTY;
        }
    }