# ProcessSpecItemManagerImpl.java

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

    import com.mycim.framework.jdbc.Page;
    import com.mycim.framework.utils.beans.BeanUtils;
    import com.mycim.framework.utils.lang.StringUtils;
    import com.mycim.framework.utils.lang.collections.CollectionUtils;
    import com.mycim.framework.utils.lang.time.DateUtils;
    import com.mycim.server.spec.dao.ProcessSpecItemActiveDao;
    import com.mycim.server.spec.dao.ProcessSpecItemDao;
    import com.mycim.server.spec.dao.ProcessSpecItemHistoryDao;
    import com.mycim.server.spec.manager.ProcessSpecItemManager;
    import com.mycim.valueobject.bas.TransactionLog;
    import com.mycim.valueobject.consts.TransactionNames;
    import com.mycim.valueobject.consts.VersionStatus;
    import com.mycim.valueobject.prp.Ecn;
    import com.mycim.valueobject.prp.ProcessSpecItem;
    import com.mycim.valueobject.prp.ProcessSpecItemDto;
    import com.mycim.valueobject.prp.ProcessSpecItemHistory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.*;

    @Service
    @Transactional
    public class ProcessSpecItemManagerImpl implements ProcessSpecItemManager {

        @Autowired
        ProcessSpecItemDao processSpecItemDao;

        @Autowired
        ProcessSpecItemActiveDao processSpecItemActiveDao;

        @Autowired
        ProcessSpecItemHistoryDao processSpecItemHistoryDao;

        @Override
        public void insertProcessSpecItems(TransactionLog transactionLog, List<ProcessSpecItem> processSpecItems) {
            if (CollectionUtils.isEmpty(processSpecItems)) {
                return;
            }
            List<ProcessSpecItemHistory> processSpecItemHistories = new ArrayList<>();

            int transSequence =
                    transactionLog.getTransSequence() != null ? transactionLog.getTransSequence().intValue() : 0;
            for (ProcessSpecItem processSpecItem : processSpecItems) {
                processSpecItem.setStatus(VersionStatus.UNFROZEN_KEY);

                processSpecItem.setCreatedUser(transactionLog.getTransPerformedBy());
                processSpecItem.setCreatedTime(transactionLog.getTransStartTimestamp());

                processSpecItem.setUpdatedUser(transactionLog.getTransPerformedBy());
                processSpecItem.setUpdatedTime(transactionLog.getTransStartTimestamp());

                ProcessSpecItemHistory processSpecItemHistory = new ProcessSpecItemHistory();

                BeanUtils.copyProperties(processSpecItem, processSpecItemHistory);

                processSpecItemHistory.setTransRrn(transactionLog.getTransRrn());
                processSpecItemHistory.setTransId(transactionLog.getTransId());
                processSpecItemHistory.setTransSequence(++transSequence);
                processSpecItemHistory.setSubTransId(TransactionNames.CREATE_KEY);
                processSpecItemHistory.setTransTimestamp(transactionLog.getTransStartTimestamp());
                processSpecItemHistory.setTransPerformedBy(transactionLog.getTransPerformedBy());

                processSpecItemHistories.add(processSpecItemHistory);
            }
            processSpecItemDao.insertProcessSpecItems(processSpecItems);
            processSpecItemHistoryDao.insertProcessSpecItemHistories(processSpecItemHistories);

            transactionLog.setTransSequence((long) transSequence);
        }

        @Override
        public void deleteProcessSpecItems(TransactionLog transactionLog, List<ProcessSpecItem> processSpecItems) {
            if (CollectionUtils.isEmpty(processSpecItems)) {
                return;
            }
            List<ProcessSpecItemHistory> processSpecItemHistories = new ArrayList<>();

            int transSequence =
                    transactionLog.getTransSequence() != null ? transactionLog.getTransSequence().intValue() : 0;
            for (ProcessSpecItem processSpecItem : processSpecItems) {
                processSpecItem.setUpdatedUser(transactionLog.getTransPerformedBy());
                processSpecItem.setUpdatedTime(transactionLog.getTransStartTimestamp());

                ProcessSpecItemHistory processSpecItemHistory = new ProcessSpecItemHistory();

                BeanUtils.copyProperties(processSpecItem, processSpecItemHistory);

                processSpecItemHistory.setTransRrn(transactionLog.getTransRrn());
                processSpecItemHistory.setTransId(transactionLog.getTransId());
                processSpecItemHistory.setTransSequence(++transSequence);
                processSpecItemHistory.setSubTransId(TransactionNames.DELETE_KEY);
                processSpecItemHistory.setTransTimestamp(transactionLog.getTransStartTimestamp());
                processSpecItemHistory.setTransPerformedBy(transactionLog.getTransPerformedBy());

                processSpecItemHistories.add(processSpecItemHistory);
            }
            processSpecItemDao.deleteProcessSpecItems(processSpecItems);
            processSpecItemHistoryDao.insertProcessSpecItemHistories(processSpecItemHistories);

            transactionLog.setTransSequence((long) transSequence);
        }

        @Override
        public void updateProcessSpecItems(TransactionLog transactionLog, List<ProcessSpecItem> processSpecItems) {
            if (CollectionUtils.isEmpty(processSpecItems)) {
                return;
            }
            List<ProcessSpecItemHistory> processSpecItemHistories = new ArrayList<>();

            int transSequence =
                    transactionLog.getTransSequence() != null ? transactionLog.getTransSequence().intValue() : 0;
            for (ProcessSpecItem processSpecItem : processSpecItems) {
                processSpecItem.setStatus(VersionStatus.UNFROZEN_KEY);

                processSpecItem.setUpdatedUser(transactionLog.getTransPerformedBy());
                processSpecItem.setUpdatedTime(transactionLog.getTransStartTimestamp());

                ProcessSpecItemHistory processSpecItemHistory = new ProcessSpecItemHistory();

                BeanUtils.copyProperties(processSpecItem, processSpecItemHistory);

                processSpecItemHistory.setTransRrn(transactionLog.getTransRrn());
                processSpecItemHistory.setTransId(transactionLog.getTransId());
                processSpecItemHistory.setTransSequence(++transSequence);
                processSpecItemHistory.setSubTransId(TransactionNames.MODIFY_KEY);
                processSpecItemHistory.setTransTimestamp(transactionLog.getTransStartTimestamp());
                processSpecItemHistory.setTransPerformedBy(transactionLog.getTransPerformedBy());

                processSpecItemHistories.add(processSpecItemHistory);
            }
            processSpecItemDao.updateProcessSpecItems(processSpecItems);
            processSpecItemHistoryDao.insertProcessSpecItemHistories(processSpecItemHistories);

            transactionLog.setTransSequence((long) transSequence);
        }

        @Override
        public void updateStatusOfProcessSpecItems(TransactionLog transactionLog, List<ProcessSpecItem> processSpecItems,
                                                   Ecn ecn, String targetStatus) {
            if (CollectionUtils.isEmpty(processSpecItems)) {
                return;
            }
            List<ProcessSpecItemHistory> processSpecItemHistories = new ArrayList<>();

            int transSequence =
                    transactionLog.getTransSequence() != null ? transactionLog.getTransSequence().intValue() : 0;
            for (ProcessSpecItem processSpecItem : processSpecItems) {

                processSpecItem.setStatus(targetStatus);
                processSpecItem.setUpdatedTime(transactionLog.getTransStartTimestamp());
                processSpecItem.setUpdatedUser(transactionLog.getTransPerformedBy());

                if (ecn != null) {
                    processSpecItem.setEcnRrn(ecn.getInstanceRrn());
                    processSpecItem.setEffectiveTime(DateUtils.stringToTimestamp(ecn.getEffectiveDateFrom()));
                    processSpecItem.setTerminatedTime(DateUtils.stringToTimestamp(ecn.getEffectiveDateTo()));
                } else {
                    processSpecItem.setEcnRrn(null);
                    processSpecItem.setEffectiveTime(null);
                    processSpecItem.setTerminatedTime(null);
                }

                ProcessSpecItemHistory processSpecItemHistory = new ProcessSpecItemHistory();

                BeanUtils.copyProperties(processSpecItem, processSpecItemHistory);

                processSpecItemHistory.setTransRrn(transactionLog.getTransRrn());
                processSpecItemHistory.setTransId(transactionLog.getTransId());
                processSpecItemHistory.setTransSequence(++transSequence);
                processSpecItemHistory.setSubTransId(transactionLog.getTransId());
                processSpecItemHistory.setTransTimestamp(transactionLog.getTransStartTimestamp());
                processSpecItemHistory.setTransPerformedBy(transactionLog.getTransPerformedBy());

                processSpecItemHistories.add(processSpecItemHistory);
            }

            processSpecItemDao.updateProcessSpecItemsForStatus(processSpecItems);
            processSpecItemHistoryDao.insertProcessSpecItemHistories(processSpecItemHistories);

            if (StringUtils.equals(targetStatus, VersionStatus.ACTIVE_KEY)) {
                this.updateProcessSpecItemsForActive(processSpecItems);
            }

            transactionLog.setTransSequence((long) transSequence);
        }

        @Override
        public void saveProcessSpecItems(TransactionLog transactionLog,
                                         Map<String, List<ProcessSpecItem>> saveProcessSpecItemMap) {
            insertProcessSpecItems(transactionLog, saveProcessSpecItemMap.get("insertSpecItems"));
            updateProcessSpecItems(transactionLog, saveProcessSpecItemMap.get("updateSpecItems"));
            deleteProcessSpecItems(transactionLog, saveProcessSpecItemMap.get("deleteSpecItems"));
        }

        @Override
        public ProcessSpecItem getProcessSpecItemByPrimaryKey(Long processRrn, Integer processVersion, Long routeRrn,
                                                              Long operationRrn) {
            return processSpecItemDao.getProcessSpecItemByPrimaryKey(processRrn, processVersion, routeRrn, operationRrn);
        }

        @Override
        public List<ProcessSpecItem> getProcessSpecItems(Long processRrn, Integer processVersion) {
            List<ProcessSpecItem> result = processSpecItemDao.getProcessSpecItems(processRrn, processVersion);
            if (CollectionUtils.isEmpty(result)) {
                result = Collections.emptyList();
            }
            return result;
        }

        @Override
        public List<ProcessSpecItem> getProcessSpecItemsWithVariables(Long processRrn, Integer processVersion) {
            List<ProcessSpecItem> result = processSpecItemDao.getProcessSpecItemsWithVariables(processRrn, processVersion);
            if (CollectionUtils.isEmpty(result)) {
                result = Collections.emptyList();
            }
            return result;
        }

        @Override
        public List<ProcessSpecItem> getProcessSpecItems(Long processRrn, Integer processVersion, String status) {
            List<ProcessSpecItem> result = processSpecItemDao
                    .getProcessSpecItemsForStatus(processRrn, processVersion, status);
            if (CollectionUtils.isEmpty(result)) {
                result = Collections.emptyList();
            }
            return result;
        }

        @Override
        public Page queryProcessSpecItemHistories(Page page, String processId, Integer processVersion, Date queryStartTime,
                                                  Date queryEndTime) {
            return processSpecItemHistoryDao
                    .queryProcessSpecItemHistories(page, processId, processVersion, queryStartTime, queryEndTime);
        }

        @Override
        public List<ProcessSpecItem> getProcessSpecItemsForActive(Long processRrn, Integer processVersion) {
            List<ProcessSpecItem> result = processSpecItemActiveDao
                    .getProcessSpecItemsForActive(processRrn, processVersion);
            if (CollectionUtils.isEmpty(result)) {
                result = Collections.emptyList();
            }
            return result;
        }

        @Override
        public String getEqptGroupIds(Long processRrn, Integer processVersion, Long routeRrn, Long operationRrn) {
            return processSpecItemActiveDao.getEqptGroupIds(processRrn, processVersion, routeRrn, operationRrn);
        }

        @Override
        public String getEqptGroupRrns(Long processRrn, Integer processVersion, Long routeRrn, Long operationRrn) {
            return processSpecItemActiveDao.getEqptGroupRrns(processRrn, processVersion, routeRrn, operationRrn);
        }

        @Override
        public ProcessSpecItem getProcessSpecItemForActive(ProcessSpecItemDto processSpecItemDto) {
            return processSpecItemActiveDao.getProcessSpecItemForActive(processSpecItemDto);
        }

        @Override
        public String getFlipType(Long processRrn, Integer processVersion, Long routeRrn, Long operationRrn) {
            return processSpecItemActiveDao.getFlipType(processRrn, processVersion, routeRrn, operationRrn);
        }

        @Override
        public boolean checkFlipSetTogether(Long processRrn, Integer processVersion) {
            return processSpecItemDao.checkFlipSetTogether(processRrn, processVersion);
        }

        @Override
        public String getProcessLocation(Long processRrn, Integer processVersion, Long routeRrn, Integer routeVersion,
                                         Long operationRrn) {
            return processSpecItemActiveDao.getProcessLocation(processRrn, processVersion, routeRrn, routeVersion, operationRrn);
        }

        private void updateProcessSpecItemsForActive(List<ProcessSpecItem> processSpecItems) {
            if (CollectionUtils.isEmpty(processSpecItems)) {
                return;
            }

            List<ProcessSpecItem> tmp = getProcessSpecItemsForActive(processSpecItems.iterator().next().getProcessRrn(),
                                                                     processSpecItems.iterator().next()
                                                                                     .getProcessVersion());
            if (CollectionUtils.isEmpty(tmp)) {
                processSpecItemActiveDao.insertProcessSpecItemsForActive(processSpecItems);
            } else {
                processSpecItemActiveDao.updateProcessSpecItemsForActive(processSpecItems);
            }
        }

    }