# PodManagerImpl.java

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

    import com.fa.sesa.exception.Assert;
    import com.fa.sesa.exception.Errors;
    import com.fa.sesa.exception.SystemIllegalArgumentException;
    import com.mycim.framework.utils.lang.StringUtils;
    import com.mycim.framework.utils.lang.collections.MapUtils;
    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.carrier.dao.PodDAO;
    import com.mycim.server.carrier.manager.PcdManager;
    import com.mycim.server.carrier.manager.PodManager;
    import com.mycim.server.ems.manager.EntityManager;
    import com.mycim.server.status.manager.StatusManager;
    import com.mycim.valueobject.MessageIdList;
    import com.mycim.valueobject.ObjectList;
    import com.mycim.valueobject.bas.NamedObject;
    import com.mycim.valueobject.bas.TransactionLog;
    import com.mycim.valueobject.consts.PcdStatus;
    import com.mycim.valueobject.consts.TransactionNames;
    import com.mycim.valueobject.ems.POD;
    import com.mycim.valueobject.ems.PcdAssembly;
    import com.mycim.valueobject.ems.PcdClean;
    import com.mycim.valueobject.wip.TransReason;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    /**
     * @author yanbing.chen
     * @date 2019/10/10
     * @since 1.8
     **/
    @Service
    @Transactional
    public class PodManagerImpl implements PodManager {

        @Autowired
        PodDAO podDao;

        @Autowired
        TransactionLogManager transactionLogManager;

        @Autowired
        StatusManager statusManager;

        @Autowired
        EventManager eventManager;

        @Autowired
        PcdManager pcdManager;

        @Autowired
        NamedObjectManager namedObjectManager;

        @Autowired
        EntityManager entityManager;

        @Override
        public POD getPod(long podRrn) {
            return podDao.getPod(podRrn);
        }

        @Override
        public Map<String, Object> qryPodInfoDetailById(String podId, String namedSpace) {
            return podDao.qryPodInfoDetailById(podId, namedSpace);
        }

        @Override
        public void insertPodH(Long podRrn, String comments, Long transRrn) {
            podDao.insertPodH(podRrn, comments, transRrn);
            PcdClean cleanInfo = pcdManager.getPcdCleanInfo(podRrn);
            if (cleanInfo != null && StringUtils.isNotBlank(cleanInfo.getInstanceId())) {
                pcdManager.insertPcdCleanH(transRrn, cleanInfo);
            }
        }

        @Override
        public void updatePodByDeassembly(Long transRrn, POD pod) {
            podDao.updatePodByDeassembly(transRrn, pod);
        }

        @Override
        public void holdPod(Map transInfo) {
            String transPerformedBy = MapUtils.getString(transInfo, "transPerformedBy");
            long holdBy = MapUtils.getLong(transInfo, "holdBy");
            NamedObject pcd = (NamedObject) transInfo.get("pcd");
            long instanceRrn = pcd.getInstanceRrn();
            long facilityRrn = MapUtils.getLongValue(transInfo, "facilityRrn");
            TransReason transReason = (TransReason) transInfo.get("transReason");

            PcdAssembly pcdAssembly = (PcdAssembly) transInfo.get("pcdAssembly");

            TransactionLog transactionLog = transactionLogManager
                    .startTransactionLog(transPerformedBy, TransactionNames.HOLD_POD_KEY);
            long transRrn = transactionLog.getTransRrn();

            if (pcdAssembly == null) {
                pcdAssembly = new PcdAssembly();
                pcdAssembly.setPodRrn(instanceRrn);
            }
            // step1: update pcd status and add history
            POD pod = getPod(instanceRrn);
            if (!StringUtils.equalsIgnoreCase(pod.getPodStatus(), PcdStatus.HOLD_KEY)) {
                String podEventId = eventManager
                        .getEventIdBy2Status(facilityRrn, instanceRrn, pod.getPodStatus(), PcdStatus.HOLD_KEY);
                statusManager
                        .changePCDStatusByEvent(facilityRrn, transPerformedBy, instanceRrn, ObjectList.POD_KEY, podEventId,
                                                "Hold");

                podDao.updatePodStatus(pcdAssembly, transRrn, PcdStatus.HOLD_KEY, null);
            }

            // step2: insert into multiple_Hold
            pcdManager.insertMultipleHold(instanceRrn, holdBy, transRrn);

            // step3: insert into trans_reason
            pcdManager.insertTransReason(transRrn, instanceRrn, transReason, 1);

            transactionLogManager.markTransactionLog(transactionLog);
        }

        @Override
        public void releasePod(Map transInfo) {
            String transPerformedBy = MapUtils.getString(transInfo, "transPerformedBy");
            List releaseReasons = (List) transInfo.get("releaseReasons");
            NamedObject pcd = (NamedObject) transInfo.get("pcd");
            long instanceRrn = pcd.getInstanceRrn();
            String transNames = TransactionNames.RELEASE_POD_KEY;
            TransReason transReason = (TransReason) transInfo.get("transReason");
            String targetStatus = MapUtils.getString(transInfo, "targetStatus");
            PcdAssembly pcdAssembly = (PcdAssembly) transInfo.get("pcdAssembly");
            long facilityRrn = MapUtils.getLongValue(transInfo, "facilityRrn");

            if (pcdAssembly == null) {
                pcdAssembly = new PcdAssembly();
                pcdAssembly.setPodRrn(instanceRrn);
            }
            TransactionLog transactionLog = transactionLogManager.startTransactionLog(transPerformedBy, transNames);

            // delete Multiple hold
            Object[] releaseReasonArray = releaseReasons.toArray();

            for (int i = 0; i < releaseReasonArray.length; i++) {
                HashMap releaseReason = (HashMap) releaseReasonArray[i];
                pcdManager.deleteMultipleHold(instanceRrn, Long.parseLong((String) releaseReason.get("sequenceNumber")));
            }

            if (!StringUtils.equalsIgnoreCase(targetStatus, PcdStatus.HOLD_KEY)) {
                POD pod = getPod(instanceRrn);
                String cstEventId = eventManager
                        .getEventIdBy2Status(facilityRrn, instanceRrn, pod.getPodStatus(), targetStatus);
                statusManager
                        .changePCDStatusByEvent(facilityRrn, transPerformedBy, instanceRrn, ObjectList.POD_KEY, cstEventId,
                                                "Hold");

                podDao.updatePodStatus(pcdAssembly, transactionLog.getTransRrn(), targetStatus, null);
            }

            transReason.setReasonCategory(transNames);

            pcdManager.insertTransReason(transactionLog.getTransRrn(), instanceRrn, transReason, 1);

            transactionLogManager.markTransactionLog(transactionLog);

        }

        @Override
        public Map<String, Object> qryPodListByPage(Map<String, Object> argMap) {
            int pageSize = 20;
            int startRow = 0;
            int currentTotalRow = 10;

            if (MapUtils.isNotEmpty(argMap) && MapUtils.getInteger(argMap, "startRow") != null) {
                startRow = MapUtils.getInteger(argMap, "startRow");
                currentTotalRow = startRow + pageSize;
            }

            if (MapUtils.getLong(argMap, "facility") > 0) {
                argMap.put("namedSpace",
                           namedObjectManager.getNamedSpace(MapUtils.getLong(argMap, "facility"), ObjectList.ENTITY_KEY));
            }

            if (StringUtils.isNotBlank(MapUtils.getString(argMap, "podId"))) {
                argMap.put("podId",
                           StringUtils.replace(MapUtils.getString(argMap, "podId"), "*", "%").toString().toUpperCase());
            }

            // 查询数据集和数据总量
            int totalCount = podDao.getPodTotalCount(argMap);
            List<Map> eqptInfoList = podDao.getPodListByPage(argMap, startRow, currentTotalRow);

            for (Map dataMap : eqptInfoList) {
                // 替换location
                String location = MapUtils.getString(dataMap, "location");
                if (StringUtils.isNotBlank(location) && StringUtils.equalsIgnoreCase("$EQPT_LOCATION", location)) {
                    dataMap.put("location", "");
                }
                PcdAssembly pcdAssembly = pcdManager.getPcdAssembly(null, MapUtils.getLong(dataMap, "podRrn"), null);
                if (pcdAssembly != null) {
                    dataMap.put("carrierId", pcdAssembly.getCarrierId());
                    dataMap.put("doorId", pcdAssembly.getDoorId());

                    if (pcdManager.isPcdCleaningTimeIsLessThan3Days(pcdAssembly.getCarrierRrn())) {
                        dataMap.put("carrierCleanRedFlag", "1");
                    }
                    if (pcdManager.isPcdCleaningTimeIsLessThan3Days(pcdAssembly.getDoorRrn())) {
                        dataMap.put("doorCleanRedFlag", "1");
                    }
                }
                if (pcdManager.isPcdCleaningTimeIsLessThan3Days(MapUtils.getLong(dataMap, "podRrn"))) {
                    dataMap.put("podCleanRedFlag", "1");
                }
            }
            Map<String, Object> dataMap = new HashMap<String, Object>();
            dataMap.put("data", eqptInfoList);
            dataMap.put("totalCount", totalCount);
            return dataMap;
        }

        @Override
        public void deletePodEntity(String podId, Long facilityRrn, String user) {
            String namedSpace = namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY);
            long podRrn = 0L;
            podRrn = namedObjectManager.getNamedObjectRrn(podId, namedSpace, ObjectList.ENTITY_KEY, ObjectList.POD_KEY);
            Assert.isFalse(podRrn <= 0, Errors.create().key(MessageIdList.POD_POD_ID_MISSING).content("Pod号不存在!").build());
            // pod存在，检查pod当前信息，判断是否可以删除
            POD pod = this.getPod(podRrn);
            // 目前判断不是FREE状态不能删除
            if (StringUtils.equalsIgnoreCase(PcdStatus.FREE_KEY, pod.getPodStatus())) {
                // 删除pod
                pod.setTransId("DELETE");
                pod.setPodStatus(PcdStatus.DELETED_KEY);
                pod.setTransPerformedby(user);
                deletePod(pod);
            } else {
                Assert.isFalse(StringUtils.equalsIgnoreCase(PcdStatus.HOLD_KEY, pod.getPodStatus()),
                               Errors.create().key(MessageIdList.POD_IN_HOLD_STATUS).content("Pod在hold 状态，不能删除!").build());
                throw new SystemIllegalArgumentException(
                        Errors.create().key(MessageIdList.POD_IN_USE_CANNOT_DELETE).content("Pod正在使用中，不能删除!").build());
            }

        }

        @Override
        public void updatePodEntity(Map<String, Object> attrMap, Long facilityRrn, String user) {
            String allowableEventId = MapUtils.getString(attrMap, "podAllowableEvent").toUpperCase().trim();
            String engineerGroupId = MapUtils.getString(attrMap, "podEngineerGroupID").toUpperCase().trim();
            long allowableEventRrn = namedObjectManager.getNamedObjectRrn(allowableEventId, namedObjectManager
                                                                                  .getNamedSpace(facilityRrn,
                                                                                                 ObjectList.ALLOWABLEEVENTSET_KEY),
                                                                          ObjectList.ALLOWABLEEVENTSET_KEY.toString());

            long engineerGroupRrn = namedObjectManager.getNamedObjectRrn(engineerGroupId, namedObjectManager
                    .getNamedSpace(facilityRrn, ObjectList.USERGROUP_KEY), ObjectList.USERGROUP_KEY);

            Assert.isFalse(allowableEventRrn <= 0,
                           Errors.create().key(MessageIdList.CARRIER_ALLOWABLE_EVENT_EMPTY).content("允许事件集号不能为空!").build());
            Assert.isFalse(StringUtils.isNotBlank(engineerGroupId) && engineerGroupRrn <= 0,
                           Errors.create().key(MessageIdList.ENGINEERGROUP_ENGINEER_GROUP_MISSING).content("工程师组无效!")
                                 .build());

            Long podRrn = MapUtils.getLong(attrMap, "podRrn");

            POD pod = getPod(podRrn);

            pod.setAllowableEventsId(allowableEventId);
            pod.setAllowableEventsRrn(allowableEventRrn);
            pod.setCarrierCode(MapUtils.getString(attrMap, "podColor"));
            pod.setInstanceDesc(MapUtils.getString(attrMap, "podDesc"));
            pod.setPollutionLevel(MapUtils.getString(attrMap, "podPollutionLevel"));
            pod.setTransId(TransactionNames.MODIFY_KEY);
            pod.setTransPerformedby(user);
            pod.setObjectSubtype(MapUtils.getString(attrMap, "podType"));
            pod.setMaintenanceEngineerId(engineerGroupId);
            pod.setMaintenanceEngineerRrn(engineerGroupRrn);
            pod.setFlagType(MapUtils.getString(attrMap, "podCategory"));

            TransactionLog transactionLog = transactionLogManager.startTransactionLog(user, pod.getTransId());
            long transRrn = transactionLog.getTransRrn();

            if (pcdManager.countPcdCategoryByRrn(pod.getInstanceRrn()) > 0) {
                // 已经存在数据
                pcdManager.updatePcdNamedObjectExt(pod.getInstanceRrn(), pod.getFlagType());
            } else {
                pcdManager.insertPcdNamedObjectExt(pod.getInstanceRrn(), pod.getFlagType(), pod.getDmmType());
            }
            podDao.updatePod(pod, transRrn);

            PcdClean podCleanInfo = new PcdClean();
            podCleanInfo.setInstanceRrn(podRrn);
            podCleanInfo.setInstanceId(pod.getInstanceId());
            podCleanInfo.setCleanCycle(MapUtils.getDoubleValue(attrMap, "podCleanCycle"));
            podCleanInfo.setNamedSpace(namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY));
            pcdManager.updatePcdCleanInfo(transRrn, podCleanInfo);
            // insert into Transaction Log
            transactionLogManager.markTransactionLog(transactionLog);
        }

        @Override
        public void addPodEntity(Map<String, Object> attrMap, Long facilityRrn, String user) {
            Map<String, Object> resultMap = new HashMap<String, Object>();

            String allowableEventId = MapUtils.getString(attrMap, "podAllowableEvent").toUpperCase().trim();
            String engineerGroupId = MapUtils.getString(attrMap, "podEngineerGroupID").toUpperCase().trim();
            long allowableEventRrn = namedObjectManager.getNamedObjectRrn(allowableEventId, namedObjectManager
                                                                                  .getNamedSpace(facilityRrn,
                                                                                                 ObjectList.ALLOWABLEEVENTSET_KEY),
                                                                          ObjectList.ALLOWABLEEVENTSET_KEY.toString());
            long engineerGroupRrn = namedObjectManager.getNamedObjectRrn(engineerGroupId, namedObjectManager
                    .getNamedSpace(facilityRrn, ObjectList.USERGROUP_KEY), ObjectList.USERGROUP_KEY);
            Assert.isFalse(allowableEventRrn <= 0,
                           Errors.create().key(MessageIdList.CARRIER_ALLOWABLE_EVENT_EMPTY).content("允许事件集号不能为空!").build());
            Assert.isFalse(StringUtils.isNotBlank(engineerGroupId) && engineerGroupRrn <= 0,
                           Errors.create().key(MessageIdList.ENGINEERGROUP_ENGINEER_GROUP_MISSING).content("工程师组无效!")
                                 .build());

            POD pod = new POD();
            pod.setAllowableEventsId(allowableEventId);
            pod.setAllowableEventsRrn(allowableEventRrn);
            pod.setCarrierCode(MapUtils.getString(attrMap, "podColor"));
            pod.setInstanceId(MapUtils.getString(attrMap, "podId").toUpperCase().trim());
            pod.setInstanceDesc(MapUtils.getString(attrMap, "podDesc"));
            pod.setInstanceStatus("ACTIVE");
            pod.setNamedSpace(namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY));
            pod.setObject(ObjectList.ENTITY_KEY);
            pod.setObjectType(ObjectList.POD_KEY);
            // carrier.setObjectSubtype(Objects);
            pod.setPollutionLevel(MapUtils.getString(attrMap, "podPollutionLevel"));
            pod.setPodStatus(PcdStatus.FREE_KEY);
            pod.setTransId(TransactionNames.CREATE_KEY);
            pod.setTransPerformedby(user);
            pod.setObjectSubtype(MapUtils.getString(attrMap, "podType"));
            pod.setMaintenanceEngineerId(engineerGroupId);
            pod.setMaintenanceEngineerRrn(engineerGroupRrn);
            pod.setFlagType(MapUtils.getString(attrMap, "podCategory"));
            pod.setCleanCycle(MapUtils.getDoubleValue(attrMap, "podCleanCycle"));
            insertPod(pod, facilityRrn);
        }

        @Override
        public long insertPod(POD pod, Long facilityRrn) {
            long instanceRrn = 0;
            TransactionLog transactionLog = transactionLogManager
                    .startTransactionLog(pod.getTransPerformedby(), pod.getTransId());
            instanceRrn = namedObjectManager.insertNamedObject(pod, transactionLog.getTransRrn());

            pod.setInstanceRrn(instanceRrn);
            // main or history table handle
            pcdManager.insertPcdNamedObjectExt(pod.getInstanceRrn(), pod.getFlagType(), pod.getDmmType());
            entityManager.insertParentEntity(pod, transactionLog.getTransRrn(), instanceRrn);
            entityManager.insertEntityHistory(pod, transactionLog.getTransRrn(), instanceRrn);
            podDao.insertPod(pod, transactionLog.getTransRrn());
            pcdManager.addPcdCleanInfo(instanceRrn, transactionLog.getTransRrn(), facilityRrn, ObjectList.POD_KEY,
                                       pod.getCleanCycle());
            // mark transaction end flag
            transactionLogManager.markTransactionLog(transactionLog);
            return instanceRrn;
        }

        @Override
        public void deletePod(POD pod) {
            // get the transaction log
            TransactionLog transactionLog = transactionLogManager
                    .startTransactionLog(pod.getTransPerformedby(), pod.getTransId());
            // delete the named object.
            long transRrn = transactionLog.getTransRrn();
            podDao.deletePod(pod, transRrn);
            entityManager.deleteEntityOnly(pod.getInstanceRrn());
            entityManager.deleteEntityConstraints(pod.getInstanceRrn());
            namedObjectManager.deleteNamedObject(pod, transRrn);
            pcdManager.deletePcdCleanInfo(pod.getInstanceRrn(), transRrn);
            // insert into Transaction Log
            transactionLogManager.markTransactionLog(transactionLog);
        }

        @Override
        public Map<String, Object> getPodInfoDetailById(String podId, String namedSpace) {
            Map<String, Object> dataMap = qryPodInfoDetailById(podId, namedSpace);
            PcdAssembly pcdAssembly = pcdManager.getPcdAssembly(null, MapUtils.getLong(dataMap, "podRrn"), null);
            if (pcdAssembly != null) {
                dataMap.put("carrierId", pcdAssembly.getCarrierId());
                dataMap.put("doorId", pcdAssembly.getDoorId());

                if (pcdManager.isPcdCleaningTimeIsLessThan3Days(pcdAssembly.getCarrierRrn())) {
                    dataMap.put("carrierCleanRedFlag", "1");
                }
                if (pcdManager.isPcdCleaningTimeIsLessThan3Days(pcdAssembly.getDoorRrn())) {
                    dataMap.put("doorCleanRedFlag", "1");
                }
            }

            if (pcdManager.isPcdCleaningTimeIsLessThan3Days(MapUtils.getLong(dataMap, "podRrn"))) {
                dataMap.put("podCleanRedFlag", "1");
            }
            return dataMap;
        }

        @Override
        public List<Map> getAllPod(Map<String, Object> getAllPodMap) {
            return podDao.getPodListByPage(getAllPodMap, 0, Integer.MAX_VALUE);
        }

        @Override
        public String generatePodId(String prefix, int width) {
            String newPodId= podDao.generatePodId(prefix,width);
            Assert.isFalse(StringUtils.contains(newPodId,"-1"),Errors.create().key(MessageIdList.PCD_POD_OUT_OF_MAX).content("Error, Maximum upper limit").build());
            return newPodId;
        }

    }