AttributeSetupManagerImpl.java

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

import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.server.base.manager.NamedObjectManager;
import com.mycim.server.ctx.exec.manager.ResequenceContextValueManager;
import com.mycim.server.ctx.manager.ContextManager;
import com.mycim.server.ctx.manager.ContextValueManager;
import com.mycim.server.spec.manager.AttributeSetupManager;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.consts.ActionPointList;
import com.mycim.valueobject.consts.ContextNames;
import com.mycim.valueobject.prp.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.Override;
import java.util.*;

/**
 * @author Qiansheng.Wang
 * @since 2020-09-15
 */
@Service
@Transactional
public class AttributeSetupManagerImpl implements AttributeSetupManager {

    @Autowired
    NamedObjectManager namedObjectManager;

    @Autowired
    ContextManager contextManager;

    @Autowired
    ContextValueManager contextValueManager;

    @Autowired
    ResequenceContextValueManager resequenceContextValueManager;

    @Override
    public void saveFlowSequenceToContextValue(Long facilityRrn, Ecn ecn, List<ProcessSpecItem> processSpecItems) {
        Map<String, Long> contextRrnMap = new HashMap<>();

        contextRrnMap.put(ContextNames.RESEQUENCE_CONTEXT, namedObjectManager
                .getNamedObjectRrn(ContextNames.RESEQUENCE_CONTEXT, facilityRrn, ObjectList.CONTEXT_KEY));

        List<ContextValue> contextValues = new ArrayList<>();

        for (ProcessSpecItem processSpecItem : processSpecItems) {
            contextValues.add(buildProcessFlowSeq(contextRrnMap, processSpecItem));
        }

        ProcessSpecItem processSpecItem = processSpecItems.get(0);

        List<ContextValue> resequenceContextValues = resequenceContextValueManager
                .getFlowSeqContextValueList(processSpecItem.getProcessRrn(), processSpecItem.getProcessVersion());

        List<ContextValue> deleteContextValues = new ArrayList<>();
        for (Iterator<ContextValue> iterator = contextValues.iterator(); iterator.hasNext(); ) {
            ContextValue contextValue = iterator.next();

            int index = resequenceContextValues.indexOf(contextValue);
            if (index >= 0) {
                ContextValue oldContextValue = resequenceContextValues.get(index);

                boolean needDelete = isNeedDelete(contextValue);
                boolean isModified = isModified(contextValue, oldContextValue);

                if (needDelete) {
                    // If the value is empty. The context value needs to be deleted.
                    deleteContextValues.add(contextValue);
                    iterator.remove();
                } else if (!isModified) {
                    iterator.remove();
                }
            }
        }

        saveContextValues(ecn, contextValues, deleteContextValues);
    }

    @Override
    public void saveProcessAttributeToContextValue(Long facilityRrn, Ecn ecn, List<ProcessSpecItem> processSpecItems) {
        Map<String, Long> contextRrnMap = contextManager.getContextRrns(facilityRrn);

        List<ContextValue> processContextValues = new ArrayList<>();

        for (ProcessSpecItem processSpecItem : processSpecItems) {
            processContextValues.add(buildProcessFlowSeq(contextRrnMap, processSpecItem));
            if (!ProductVariableEnum.isRecipeVariable(processSpecItem.getRecipeId())) {
                processContextValues.add(buildProcessRecipe(contextRrnMap, processSpecItem));
            }
            if (!ProductVariableEnum.isEdcPlanVariable(processSpecItem.getParameterSetId())) {
                processContextValues.add(buildProcessParameterSet(contextRrnMap, processSpecItem));
            }
            if (!ProductVariableEnum.isReticleGroupVariable(processSpecItem.getReticleFamilyId())) {
                processContextValues.add(buildProcessReticle(contextRrnMap, processSpecItem));
            }
            processContextValues.add(buildProcessStage(contextRrnMap, processSpecItem));
            processContextValues.add(buildProcessLocation(contextRrnMap, processSpecItem));
            processContextValues.add(buildProcessPollutionLevel(contextRrnMap, processSpecItem));
            processContextValues.add(buildProcessOperationDesc(contextRrnMap, processSpecItem));
            processContextValues.add(buildBankFlag(contextRrnMap, processSpecItem));
        }

        List<ContextValue> deleteContextValues = new ArrayList<>();

        for (Iterator<ContextValue> iterator = processContextValues.iterator(); iterator.hasNext(); ) {
            ContextValue contextValue = iterator.next();

            boolean needDelete = isNeedDelete(contextValue);

            if (needDelete) {
                // If the value is empty. The context value needs to be deleted.
                deleteContextValues.add(contextValue);
                iterator.remove();
            }
        }

        saveContextValues(ecn, processContextValues, deleteContextValues);
    }

    @Override
    public void saveProductAttributeToContextValue(Long facilityRrn, Ecn ecn,
                                                   List<ProductAttributeItem> productAttributeItems) {
        Map<String, Long> contextRrnMap = contextManager.getContextRrns(facilityRrn);

        List<ContextValue> productContextValues = new ArrayList<>();

        for (ProductAttributeItem productAttributeItem : productAttributeItems) {

            if (ProductVariableEnum.isRecipeVariable(productAttributeItem.getAttributeName())) {
                productContextValues.add(buildProductRecipe(contextRrnMap, productAttributeItem));
            }
            if (ProductVariableEnum.isEdcPlanVariable(productAttributeItem.getAttributeName())) {
                productContextValues.add(buildProductParameterSet(contextRrnMap, productAttributeItem));
            }
            if (ProductVariableEnum.isReticleGroupVariable(productAttributeItem.getAttributeName())) {
                productContextValues.add(buildProductReticle(contextRrnMap, productAttributeItem));
            }
        }

        saveContextValues(ecn, productContextValues, new ArrayList<>());
    }

    private void saveContextValues(Ecn ecn, List<ContextValue> contextValues, List<ContextValue> deleteContextValues) {
        for (ContextValue newContextValue : contextValues) {
            newContextValue.setStatus(ecn.getEcnStatus());
            newContextValue.setEcnRrn(ecn.getInstanceRrn());
            newContextValue.setEffectiveDateFrom(ecn.getEffectiveDateFrom());
            newContextValue.setEffectiveDateTo(ecn.getEffectiveDateTo());
        }

        contextValueManager.saveContextValues(contextValues, ecn.getRequestBy());
        contextValueManager.deleteContextValues(deleteContextValues, ecn.getRequestBy());
    }

    /**
     * Check whether all the result values of the context value are empty.
     *
     * @param contextValue Inspection object
     * @return If all the result values are blank, return {@code true}.
     */
    private boolean isNeedDelete(ContextValue contextValue) {
        return StringUtils.isBlank(contextValue.getResultValue1()) &&
                StringUtils.isBlank(contextValue.getResultValue2()) &&
                StringUtils.isBlank(contextValue.getResultValue3()) &&
                StringUtils.isBlank(contextValue.getResultValue4()) &&
                StringUtils.isBlank(contextValue.getResultValue5()) &&
                StringUtils.isBlank(contextValue.getResultValue6()) &&
                StringUtils.isBlank(contextValue.getResultValue7()) &&
                StringUtils.isBlank(contextValue.getResultValue8()) &&
                StringUtils.isBlank(contextValue.getResultValue9()) &&
                StringUtils.isBlank(contextValue.getResultValue10()) &&
                StringUtils.isBlank(contextValue.getResultValue11()) &&
                StringUtils.isBlank(contextValue.getResultValue12()) &&
                StringUtils.isBlank(contextValue.getResultValue13()) &&
                StringUtils.isBlank(contextValue.getResultValue14()) &&
                StringUtils.isBlank(contextValue.getResultValue15());
    }

    /**
     * Check whether the result value of the context value has been modified.
     *
     * @param newContextValue Modified object
     * @param oldContextValue Source object
     * @return If one of the result values is modified, return {@code true}.
     */
    private boolean isModified(ContextValue newContextValue, ContextValue oldContextValue) {
        return isModified(newContextValue.getResultValue1(), oldContextValue.getResultValue1()) ||
                isModified(newContextValue.getResultValue2(), oldContextValue.getResultValue2()) ||
                isModified(newContextValue.getResultValue3(), oldContextValue.getResultValue3()) ||
                isModified(newContextValue.getResultValue4(), oldContextValue.getResultValue4()) ||
                isModified(newContextValue.getResultValue5(), oldContextValue.getResultValue5()) ||
                isModified(newContextValue.getResultValue6(), oldContextValue.getResultValue6()) ||
                isModified(newContextValue.getResultValue7(), oldContextValue.getResultValue7()) ||
                isModified(newContextValue.getResultValue8(), oldContextValue.getResultValue8()) ||
                isModified(newContextValue.getResultValue9(), oldContextValue.getResultValue9()) ||
                isModified(newContextValue.getResultValue10(), oldContextValue.getResultValue10()) ||
                isModified(newContextValue.getResultValue11(), oldContextValue.getResultValue11()) ||
                isModified(newContextValue.getResultValue12(), oldContextValue.getResultValue12()) ||
                isModified(newContextValue.getResultValue13(), oldContextValue.getResultValue13()) ||
                isModified(newContextValue.getResultValue14(), oldContextValue.getResultValue14()) ||
                isModified(newContextValue.getResultValue15(), oldContextValue.getResultValue15());
    }

    private boolean isModified(String newResultValue, String oldResultValue) {
        return !StringUtils.equals(StringUtils.trimToEmpty(newResultValue), StringUtils.trimToEmpty(oldResultValue));
    }

    private ReticleFamilyContextValue buildProductReticle(Map<String, Long> contexts,
                                                          ProductAttributeItem productAttributeItem) {
        ReticleFamilyContextValue contextValue = new ReticleFamilyContextValue();

        contextValue.setContextRrn(MapUtils.getLongValue(contexts, contextValue.getContextId()));

        contextValue.setProductRrn(productAttributeItem.getProductRrn());
        contextValue.setProductVersion(productAttributeItem.getProductVersion());
        contextValue.setProcessRrn(productAttributeItem.getProcessRrn());
        contextValue.setProcessVersion(productAttributeItem.getProcessVersion());
        contextValue.setRouteRrn(productAttributeItem.getRouteRrn());
        contextValue.setOperationRrn(productAttributeItem.getOperationRrn());

        contextValue.setReticleFamilyRrn(productAttributeItem.getAttributeValueRrn());
        contextValue.setAttributeNameRrn(productAttributeItem.getAttributeNameRrn());

        return contextValue;
    }

    private EdcLotContextValue buildProductParameterSet(Map<String, Long> contexts,
                                                        ProductAttributeItem productAttributeItem) {
        EdcLotContextValue contextValue = new EdcLotContextValue();

        contextValue.setContextRrn(MapUtils.getLongValue(contexts, contextValue.getContextId()));

        contextValue.setProductRrn(productAttributeItem.getProductRrn());
        contextValue.setProductVersion(productAttributeItem.getProductVersion());
        contextValue.setProcessRrn(productAttributeItem.getProcessRrn());
        contextValue.setProcessVersion(productAttributeItem.getProcessVersion());
        contextValue.setRouteRrn(productAttributeItem.getRouteRrn());
        contextValue.setOperationRrn(productAttributeItem.getOperationRrn());

        contextValue.setActionPoint(ActionPointList.MOVEOUT_KEY);

        contextValue.setParameterSetRrn(productAttributeItem.getAttributeValueRrn());
        contextValue.setAttributeNameRrn(productAttributeItem.getAttributeNameRrn());

        return contextValue;
    }

    private RecipeContextValue buildProductRecipe(Map<String, Long> contexts,
                                                  ProductAttributeItem productAttributeItem) {
        RecipeContextValue contextValue = new RecipeContextValue();

        contextValue.setContextRrn(MapUtils.getLongValue(contexts, contextValue.getContextId()));

        contextValue.setProductRrn(productAttributeItem.getProductRrn());
        contextValue.setProductVersion(productAttributeItem.getProductVersion());
        contextValue.setProcessRrn(productAttributeItem.getProcessRrn());
        contextValue.setProcessVersion(productAttributeItem.getProcessVersion());
        contextValue.setRouteRrn(productAttributeItem.getRouteRrn());
        contextValue.setOperationRrn(productAttributeItem.getOperationRrn());

        contextValue.setRecipeRrn(productAttributeItem.getAttributeValueRrn());
        contextValue.setAttributeNameRrn(productAttributeItem.getAttributeNameRrn());

        return contextValue;
    }

    private ProcessOperationDescContextValue buildProcessOperationDesc(Map<String, Long> contexts,
                                                                       ProcessSpecItem processSpecItem) {
        ProcessOperationDescContextValue contextValue = new ProcessOperationDescContextValue();

        contextValue.setContextRrn(MapUtils.getLongValue(contexts, contextValue.getContextId()));

        contextValue.setProcessRrn(processSpecItem.getProcessRrn());
        contextValue.setProcessVersion(processSpecItem.getProcessVersion());
        contextValue.setRouteRrn(processSpecItem.getRouteRrn());
        contextValue.setOperationRrn(processSpecItem.getOperationRrn());

        if (StringUtils.isNotBlank(processSpecItem.getOperationDesc())) {
            contextValue.setOperationDesc(processSpecItem.getOperationDesc());
        }

        return contextValue;
    }

    private BankFlagContextValue buildBankFlag(Map<String, Long> contexts, ProcessSpecItem processSpecItem) {
        BankFlagContextValue contextValue = new BankFlagContextValue();

        contextValue.setContextRrn(MapUtils.getLongValue(contexts, contextValue.getContextId()));

        contextValue.setProcessRrn(processSpecItem.getProcessRrn());
        contextValue.setProcessVersion(processSpecItem.getProcessVersion());
        contextValue.setRouteRrn(processSpecItem.getRouteRrn());
        contextValue.setOperationRrn(processSpecItem.getOperationRrn());

        if (StringUtils.isNotBlank(processSpecItem.getBankFlag())) {
            contextValue.setBankFlag(processSpecItem.getBankFlag());
        }

        return contextValue;
    }

    private OperationDESCContextValue buildProcessPollutionLevel(Map<String, Long> contexts,
                                                                 ProcessSpecItem processSpecItem) {
        OperationDESCContextValue contextValue = new OperationDESCContextValue();

        contextValue.setContextRrn(MapUtils.getLongValue(contexts, contextValue.getContextId()));

        contextValue.setProcessRrn(processSpecItem.getProcessRrn());
        contextValue.setProcessVersion(processSpecItem.getProcessVersion());
        contextValue.setRouteRrn(processSpecItem.getRouteRrn());
        contextValue.setOperationRrn(processSpecItem.getOperationRrn());

        if (StringUtils.isNotBlank(processSpecItem.getPollutionLevel())) {
            contextValue.setPollutionLevel(processSpecItem.getPollutionLevel());
        }
        if (StringUtils.isNotBlank(processSpecItem.getOperationType())) {
            contextValue.setOperationType(processSpecItem.getOperationType());
        }
        if (StringUtils.isNotBlank(processSpecItem.getWorkArea())) {
            contextValue.setWorkArea(processSpecItem.getWorkArea());
        }

        return contextValue;
    }

    private ProcessLocationContextValue buildProcessLocation(Map<String, Long> contexts,
                                                             ProcessSpecItem processSpecItem) {
        ProcessLocationContextValue contextValue = new ProcessLocationContextValue();

        contextValue.setContextRrn(MapUtils.getLongValue(contexts, contextValue.getContextId()));

        contextValue.setProcessRrn(processSpecItem.getProcessRrn());
        contextValue.setProcessVersion(processSpecItem.getProcessVersion());
        contextValue.setRouteRrn(processSpecItem.getRouteRrn());
        contextValue.setOperationRrn(processSpecItem.getOperationRrn());

        if (StringUtils.isNotBlank(processSpecItem.getProcessLocation())) {
            contextValue.setProcessLocation(processSpecItem.getProcessLocation());
        }

        return contextValue;
    }

    private StageContextValue buildProcessStage(Map<String, Long> contexts, ProcessSpecItem processSpecItem) {
        StageContextValue contextValue = new StageContextValue();

        contextValue.setContextRrn(MapUtils.getLongValue(contexts, contextValue.getContextId()));

        contextValue.setProcessRrn(processSpecItem.getProcessRrn());
        contextValue.setProcessVersion(processSpecItem.getProcessVersion());
        contextValue.setRouteRrn(processSpecItem.getRouteRrn());
        contextValue.setOperationRrn(processSpecItem.getOperationRrn());

        if (StringUtils.isNotBlank(processSpecItem.getStageId())) {
            contextValue.setStageId(processSpecItem.getStageId());
        }

        return contextValue;
    }

    private ReticleFamilyContextValue buildProcessReticle(Map<String, Long> contexts, ProcessSpecItem processSpecItem) {
        ReticleFamilyContextValue contextValue = new ReticleFamilyContextValue();

        contextValue.setContextRrn(MapUtils.getLongValue(contexts, contextValue.getContextId()));

        contextValue.setProcessRrn(processSpecItem.getProcessRrn());
        contextValue.setProcessVersion(processSpecItem.getProcessVersion());
        contextValue.setRouteRrn(processSpecItem.getRouteRrn());
        contextValue.setOperationRrn(processSpecItem.getOperationRrn());

        if (processSpecItem.getReticleFamilyRrn() != null && processSpecItem.getReticleFamilyRrn() > 0) {
            contextValue.setReticleFamilyRrn(processSpecItem.getReticleFamilyRrn());
        }

        return contextValue;
    }

    private EdcLotContextValue buildProcessParameterSet(Map<String, Long> contexts, ProcessSpecItem processSpecItem) {
        EdcLotContextValue contextValue = new EdcLotContextValue();

        contextValue.setContextRrn(MapUtils.getLongValue(contexts, contextValue.getContextId()));

        contextValue.setProcessRrn(processSpecItem.getProcessRrn());
        contextValue.setProcessVersion(processSpecItem.getProcessVersion());
        contextValue.setRouteRrn(processSpecItem.getRouteRrn());
        contextValue.setOperationRrn(processSpecItem.getOperationRrn());
        contextValue.setActionPoint(ActionPointList.MOVEOUT_KEY);

        if (processSpecItem.getParameterSetRrn() != null && processSpecItem.getParameterSetRrn() > 0) {
            contextValue.setParameterSetRrn(processSpecItem.getParameterSetRrn());
        }

        return contextValue;
    }

    private RecipeContextValue buildProcessRecipe(Map<String, Long> contexts, ProcessSpecItem processSpecItem) {
        RecipeContextValue contextValue = new RecipeContextValue();

        contextValue.setContextRrn(MapUtils.getLongValue(contexts, contextValue.getContextId()));

        contextValue.setProcessRrn(processSpecItem.getProcessRrn());
        contextValue.setProcessVersion(processSpecItem.getProcessVersion());
        contextValue.setRouteRrn(processSpecItem.getRouteRrn());
        contextValue.setOperationRrn(processSpecItem.getOperationRrn());

        if (processSpecItem.getRecipeRrn() != null && processSpecItem.getRecipeRrn() > 0) {
            contextValue.setRecipeRrn(processSpecItem.getRecipeRrn());
        }

        return contextValue;
    }

    private ResequenceContextValue buildProcessFlowSeq(Map<String, Long> contexts, ProcessSpecItem processSpecItem) {
        ResequenceContextValue contextValue = new ResequenceContextValue();

        contextValue.setContextRrn(MapUtils.getLongValue(contexts, contextValue.getContextId()));

        contextValue.setProcessRrn(processSpecItem.getProcessRrn());
        contextValue.setProcessVersion(processSpecItem.getProcessVersion());
        contextValue.setRouteRrn(processSpecItem.getRouteRrn());
        contextValue.setOperationRrn(processSpecItem.getOperationRrn());

        if (StringUtils.isNotBlank(processSpecItem.getFlowSeq())) {
            contextValue.setResequence(StringUtils.trimToEmpty(processSpecItem.getFlowSeq()));
        }

        return contextValue;
    }

}