# DoorManagerImpl.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.DoorDAO;
    import com.mycim.server.carrier.manager.DoorManager;
    import com.mycim.server.carrier.manager.PcdManager;
    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.Door;
    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/8/23
     * @since 1.8
     **/
    @Service
    @Transactional
    public class DoorManagerImpl implements DoorManager {

        @Autowired
        DoorDAO doorDAO;

        @Autowired
        TransactionLogManager transactionLogManager;

        @Autowired
        PcdManager pcdManager;

        @Autowired
        EventManager eventManager;

        @Autowired
        StatusManager statusManager;

        @Autowired
        NamedObjectManager namedObjectManager;

        @Autowired
        EntityManager entityManager;

        @Override
        public Door getDoor(long doorRrn) {
            return doorDAO.getDoor(doorRrn);
        }

        @Override
        public Map<String, Object> qrysDoorInfoDetailById(String doorId, String namedSpace) {
            return doorDAO.qrysDoorInfoDetailById(doorId, namedSpace);
        }

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

        @Override
        public void updateDoorByDeassembly(Long transRrn, Door door) {
            doorDAO.updateDoorByDeassembly(transRrn, door);
        }

        @Override
        public void holdDoor(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.getLong(transInfo, "facilityRrn");
            TransReason transReason = (TransReason) transInfo.get("transReason");
            PcdAssembly pcdAssembly = (PcdAssembly) transInfo.get("pcdAssembly");

            TransactionLog transactionLog = transactionLogManager
                    .startTransactionLog(transPerformedBy, TransactionNames.HOLD_DOOR_KEY);

            long transRrn = transactionLog.getTransRrn();
            if (pcdAssembly == null) {
                pcdAssembly = new PcdAssembly();
                pcdAssembly.setDoorRrn(instanceRrn);
            }

            // step1: update pcd status and add history
            Door door = getDoor(instanceRrn);
            if (!StringUtils.equalsIgnoreCase(door.getDoorStatus(), PcdStatus.HOLD_KEY)) {
                String podEventId = eventManager
                        .getEventIdBy2Status(facilityRrn, instanceRrn, door.getDoorStatus(), PcdStatus.HOLD_KEY);
                statusManager
                        .changePCDStatusByEvent(facilityRrn, transPerformedBy, instanceRrn, ObjectList.DOOR_KEY, podEventId,
                                                "Hold");

                doorDAO.updateDoorStatus(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 releaseDoor(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_DOOR_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.setDoorRrn(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)) {
                Door door = getDoor(instanceRrn);
                String cstEventId = eventManager
                        .getEventIdBy2Status(facilityRrn, instanceRrn, door.getDoorStatus(), targetStatus);
                statusManager
                        .changePCDStatusByEvent(facilityRrn, transPerformedBy, instanceRrn, ObjectList.DOOR_KEY, cstEventId,
                                                "Hold");
                doorDAO.updateDoorStatus(pcdAssembly, transactionLog.getTransRrn(), targetStatus, null);
            }

            transReason.setReasonCategory(transNames);

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

            transactionLogManager.markTransactionLog(transactionLog);
        }

        @Override
        public Map<String, Object> getDoorInfoDetailById(String doorId, String namedSpace) {
            Map<String, Object> dataMap = doorDAO.qrysDoorInfoDetailById(doorId, namedSpace);
            PcdAssembly pcdAssembly = pcdManager.getPcdAssembly(null, null, MapUtils.getLong(dataMap, "doorRrn"));
            if (pcdAssembly != null) {
                dataMap.put("carrierId", pcdAssembly.getCarrierId());
                dataMap.put("podId", pcdAssembly.getPodId());

                if (pcdManager.isPcdCleaningTimeIsLessThan3Days(pcdAssembly.getCarrierRrn())) {
                    dataMap.put("carrierCleanRedFlag", "1");
                }
                if (pcdManager.isPcdCleaningTimeIsLessThan3Days(pcdAssembly.getPodRrn())) {
                    dataMap.put("podCleanRedFlag", "1");
                }
            }
            if (pcdManager.isPcdCleaningTimeIsLessThan3Days(MapUtils.getLong(dataMap, "doorRrn"))) {
                dataMap.put("doorCleanRedFlag", "1");
            }
            return dataMap;
        }

        @Override
        public Map<String, Object> qryDoorListByPage(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, "doorId"))) {
                argMap.put("doorId",
                           StringUtils.replace(MapUtils.getString(argMap, "doorId"), "*", "%").toString().toUpperCase());
            }

            // 查询数据集和数据总量

            int totalCount = doorDAO.getDoorTotalCount(argMap);
            List<Map> eqptInfoList = doorDAO.getDoorListByPage(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, null, MapUtils.getLong(dataMap, "doorRrn"));
                if (pcdAssembly != null) {
                    dataMap.put("carrierId", pcdAssembly.getCarrierId());
                    dataMap.put("podId", pcdAssembly.getPodId());

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

        @Override
        public void deleteDoorEntity(String doorId, Long facilityRrn, String user) {
            String namedSpace = namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY);
            long doorRrn = namedObjectManager
                    .getNamedObjectRrn(doorId, namedSpace, ObjectList.ENTITY_KEY, ObjectList.DOOR_KEY);

            Assert.isFalse(doorRrn <= 0,
                           Errors.create().key(MessageIdList.DOOR_DOOR_ID_MISSING).content("Door号不存在!").build());
            // Door存在，检查Door当前信息，判断是否可以删除
            Door door = this.getDoor(doorRrn);
            // 目前判断不是FREE状态不能删除
            if (StringUtils.equalsIgnoreCase(PcdStatus.FREE_KEY, door.getDoorStatus())) {
                // 删除Door
                door.setTransId("DELETE");
                door.setDoorStatus(PcdStatus.DELETED_KEY);
                door.setTransPerformedby(user);

                deleteDoor(door);
            } else {
                Assert.isFalse(StringUtils.equalsIgnoreCase(PcdStatus.HOLD_KEY, door.getDoorStatus()),
                               Errors.create().key(MessageIdList.DOOR_IN_HOLD_STATUS).content("Door在hold 状态，不能删除!")
                                     .build());
                throw new SystemIllegalArgumentException(
                        Errors.create().key(MessageIdList.DOOR_IN_USE_CANNOT_DELETE).content("Door正在使用中，不能删除!").build());
            }
        }

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

            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 doorRrn = MapUtils.getLong(attrMap, "doorRrn");

            Door door = getDoor(doorRrn);

            door.setAllowableEventsId(allowableEventId);
            door.setAllowableEventsRrn(allowableEventRrn);
            door.setCarrierCode(MapUtils.getString(attrMap, "doorColor"));
            door.setInstanceDesc(MapUtils.getString(attrMap, "doorDesc"));
            door.setPollutionLevel(MapUtils.getString(attrMap, "doorPollutionLevel"));
            door.setTransId(TransactionNames.MODIFY_KEY);
            door.setTransPerformedby(user);
            door.setObjectSubtype(MapUtils.getString(attrMap, "doorType"));
            door.setMaintenanceEngineerId(engineerGroupId);
            door.setMaintenanceEngineerRrn(engineerGroupRrn);
            door.setFlagType(MapUtils.getString(attrMap, "doorCategory"));

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

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

            PcdClean doorCleanInfo = new PcdClean();
            doorCleanInfo.setInstanceRrn(door.getInstanceRrn());
            doorCleanInfo.setInstanceId(door.getInstanceId());
            doorCleanInfo.setCleanCycle(MapUtils.getDoubleValue(attrMap, "doorCleanCycle"));
            doorCleanInfo.setNamedSpace(namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY));
            pcdManager.updatePcdCleanInfo(transRrn, doorCleanInfo);

            // insert into Transaction Log
            transactionLogManager.markTransactionLog(transactionLog);
        }

        @Override
        public void addDoorEntity(Map<String, Object> attrMap, Long facilityRrn, String user) {
            String allowableEventId = MapUtils.getString(attrMap, "doorAllowableEvent").toUpperCase().trim();
            String engineerGroupId = MapUtils.getString(attrMap, "doorEngineerGroupID").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());

            Door door = new Door();
            door.setAllowableEventsId(allowableEventId);
            door.setAllowableEventsRrn(allowableEventRrn);
            door.setCarrierCode(MapUtils.getString(attrMap, "doorColor"));
            door.setInstanceId(MapUtils.getString(attrMap, "doorId").toUpperCase().trim());
            door.setInstanceDesc(MapUtils.getString(attrMap, "doorDesc"));
            door.setInstanceStatus("ACTIVE");
            door.setNamedSpace(namedObjectManager.getNamedSpace(facilityRrn, ObjectList.ENTITY_KEY));
            door.setObject(ObjectList.ENTITY_KEY);
            door.setObjectType(ObjectList.DOOR_KEY);
            door.setPollutionLevel(MapUtils.getString(attrMap, "doorPollutionLevel"));
            door.setDoorStatus(PcdStatus.FREE_KEY);
            door.setTransId(TransactionNames.CREATE_KEY);
            door.setTransPerformedby(user);
            door.setObjectSubtype(MapUtils.getString(attrMap, "doorType"));
            door.setMaintenanceEngineerId(engineerGroupId);
            door.setMaintenanceEngineerRrn(engineerGroupRrn);
            door.setFlagType(MapUtils.getString(attrMap, "doorCategory"));
            door.setCleanCycle(MapUtils.getDoubleValue(attrMap, "doorCleanCycle"));
            insertDoor(door, facilityRrn);
        }

        @Override
        public void deleteDoor(Door door) {
            // get the transaction log
            TransactionLog transactionLog = transactionLogManager
                    .startTransactionLog(door.getTransPerformedby(), door.getTransId());

            // delete the named object.
            long transRrn = transactionLog.getTransRrn();
            doorDAO.deleteDoor(door, transRrn);
            entityManager.deleteEntityOnly(door.getInstanceRrn());
            entityManager.deleteEntityConstraints(door.getInstanceRrn());
            long instanceRrn = namedObjectManager.deleteNamedObject(door, transRrn);
            pcdManager.deletePcdCleanInfo(door.getInstanceRrn(), transRrn);

            // insert into Transaction Log
            transactionLogManager.markTransactionLog(transactionLog);
        }

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

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

        @Override
        public List<Map> getAllDoor(Map<String, Object> getAllDoorMap) {
            return doorDAO.getDoorListByPage(getAllDoorMap, 0, Integer.MAX_VALUE);
        }

    }