| /******************************************************************************** |
| * Copyright (c) 2018 Mettenmeier GmbH |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0 |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| ********************************************************************************/ |
| package org.eclipse.openk.sp.controller.planning; |
| |
| import java.util.ArrayList; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.log4j.Logger; |
| import org.eclipse.openk.sp.controller.AbstractController; |
| import org.eclipse.openk.sp.db.converter.EntityConverter; |
| import org.eclipse.openk.sp.db.dao.ArchiveRepository; |
| import org.eclipse.openk.sp.db.dao.StandbyGroupRepository; |
| import org.eclipse.openk.sp.db.dao.StandbyScheduleBodyRepository; |
| import org.eclipse.openk.sp.db.dao.StandbyStatusRepository; |
| import org.eclipse.openk.sp.db.dao.UserRepository; |
| import org.eclipse.openk.sp.db.model.ArchiveStandbyScheduleHeader; |
| import org.eclipse.openk.sp.db.model.StandbyGroup; |
| import org.eclipse.openk.sp.db.model.StandbyScheduleBody; |
| import org.eclipse.openk.sp.db.model.StandbyStatus; |
| import org.eclipse.openk.sp.db.model.User; |
| import org.eclipse.openk.sp.dto.ArchiveStandbyScheduleHeaderDto; |
| import org.eclipse.openk.sp.dto.ArchiveStandbyScheduleHeaderSelectionDto; |
| import org.eclipse.openk.sp.dto.StandbyGroupSelectionDto; |
| import org.eclipse.openk.sp.dto.StandbyScheduleArchiveDto; |
| import org.eclipse.openk.sp.dto.StandbyScheduleBodySelectionDto; |
| import org.eclipse.openk.sp.dto.planning.PlanRowsArchiveDto; |
| import org.eclipse.openk.sp.dto.planning.PlanningMsgDto; |
| import org.eclipse.openk.sp.dto.planning.PlanningMsgResponseDto; |
| import org.eclipse.openk.sp.dto.planning.StandbyScheduleActionDto; |
| import org.eclipse.openk.sp.dto.planning.StandbyScheduleFilterDto; |
| import org.eclipse.openk.sp.dto.planning.StandbyScheduleSearchDto; |
| import org.eclipse.openk.sp.dto.planning.TransferGroupDto; |
| import org.eclipse.openk.sp.exceptions.SpErrorEntry; |
| import org.eclipse.openk.sp.exceptions.SpException; |
| import org.eclipse.openk.sp.exceptions.SpExceptionEnum; |
| import org.eclipse.openk.sp.util.DateHelper; |
| import org.eclipse.openk.sp.util.SpMsg; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.stereotype.Service; |
| import org.springframework.transaction.annotation.Transactional; |
| |
| import com.google.gson.Gson; |
| |
| @Service |
| @Transactional(rollbackFor = Exception.class) |
| public class ArchiveController extends AbstractController { |
| |
| protected static final Logger LOGGER = Logger.getLogger(ArchiveController.class); |
| |
| @Autowired |
| private StandbyGroupRepository standbyGroupRepository; |
| |
| @Autowired |
| private StandbyStatusRepository standbyStatusRepository; |
| |
| @Autowired |
| private ArchiveRepository archiveRepository; |
| |
| @Autowired |
| private PlannedDataController plannedDataController; |
| |
| @Autowired |
| private EntityConverter entityConverter; |
| |
| @Autowired |
| private StandbyScheduleBodyRepository standbyScheduleBodyRepository; |
| |
| @Autowired |
| private UserRepository userRepository; |
| |
| public ArchiveStandbyScheduleHeader createHeader(StandbyScheduleArchiveDto plan, Long statusId, String title, |
| String comment, String userName, String userAction) throws SpException { |
| ArchiveStandbyScheduleHeader header = new ArchiveStandbyScheduleHeader(); |
| |
| StandbyStatus status = null; |
| |
| header.setComment(comment); |
| header.setTitle(title); |
| |
| status = standbyStatusRepository.findOne(statusId); |
| |
| header.setStatusId(status.getId()); |
| header.setStatusName(status.getTitle()); |
| |
| Date validFrom = plan.getFilter().getValidFrom(); |
| Date validTo = plan.getFilter().getValidTo(); |
| |
| validFrom = DateHelper.getStartOfDay(validFrom); |
| validTo = DateHelper.getEndOfDay(validTo); |
| |
| header.setValidFrom(validFrom); |
| header.setValidTo(validTo); |
| |
| if (title == null || title.equals("")) { |
| header.setTitle(header.getComment()); |
| } |
| |
| header.setModificationDate(new Date()); |
| header.setModifiedBy(userName); |
| header.setModifiedCause(userAction); |
| |
| String json = new Gson().toJson(plan); |
| header.setJsonPlan(json); |
| |
| return header; |
| |
| } |
| |
| /** |
| * |
| * @param standbyScheduleFilterDto |
| * @param statusId |
| * @param userName |
| * @return |
| * @throws SpException |
| */ |
| public ArchiveStandbyScheduleHeaderDto manualCreateByStandbyList(StandbyScheduleFilterDto standbyScheduleFilterDto, |
| Long statusId, String userName) throws SpException { |
| |
| StandbyScheduleArchiveDto plan = plannedDataController |
| .getFilteredPlanByStatusForArchive(standbyScheduleFilterDto, statusId); |
| |
| ArchiveStandbyScheduleHeader header = createHeader(plan, statusId, standbyScheduleFilterDto.getTitle(), |
| standbyScheduleFilterDto.getComment(), userName, SpMsg.ACT_STANDBY_MANUAL_ARCHIVING_LIST); |
| |
| header = archiveRepository.save(header); |
| |
| ArchiveStandbyScheduleHeaderDto headerDto = (ArchiveStandbyScheduleHeaderDto) entityConverter |
| .convertEntityToDto(header, new ArchiveStandbyScheduleHeaderDto()); |
| |
| return headerDto; |
| } |
| |
| public ArchiveStandbyScheduleHeaderDto createByStandbyGroup(StandbyScheduleFilterDto standbyScheduleFilterDto, |
| Long statusId, String userName) throws SpException { |
| |
| StandbyScheduleArchiveDto plan = plannedDataController |
| .getFilteredPlanByStatusByGroupsForArchive(standbyScheduleFilterDto, statusId); |
| |
| ArchiveStandbyScheduleHeader header = createHeader(plan, statusId, standbyScheduleFilterDto.getTitle(), |
| standbyScheduleFilterDto.getComment(), userName, SpMsg.ACT_STANDBY_MANUAL_ARCHIVING_GROUP); |
| |
| header = archiveRepository.save(header); |
| |
| ArchiveStandbyScheduleHeaderDto headerDto = (ArchiveStandbyScheduleHeaderDto) entityConverter |
| .convertEntityToDto(header, new ArchiveStandbyScheduleHeaderDto()); |
| |
| return headerDto; |
| } |
| |
| /** |
| * get one archived plan |
| * |
| * @param id |
| * @return |
| */ |
| public ArchiveStandbyScheduleHeaderDto getOneArchiveHeader(Long id) { |
| |
| ArchiveStandbyScheduleHeader header = archiveRepository.findOne(id); |
| ArchiveStandbyScheduleHeaderDto headerDto = (ArchiveStandbyScheduleHeaderDto) entityConverter |
| .convertEntityToDto(header, new ArchiveStandbyScheduleHeaderDto()); |
| |
| return headerDto; |
| } |
| |
| /** |
| * get all archived plans |
| * |
| * @return |
| */ |
| @SuppressWarnings("unchecked") |
| public List<ArchiveStandbyScheduleHeaderSelectionDto> getAll() { |
| List<ArchiveStandbyScheduleHeaderSelectionDto> listHeaderDto = new ArrayList<>(); |
| List<ArchiveStandbyScheduleHeader> listHeader = archiveRepository.findAllByOrderByModificationDateDesc(); |
| |
| listHeaderDto = entityConverter.convertEntityToDtoList(listHeader, listHeaderDto, |
| ArchiveStandbyScheduleHeaderSelectionDto.class); |
| |
| return listHeaderDto; |
| } |
| |
| public PlanningMsgResponseDto importPlan(Long id, String modUserName) throws SpException { |
| PlanningMsgResponseDto responseDto = new PlanningMsgResponseDto(); |
| List<PlanningMsgDto> lsMsg = new ArrayList<>(); |
| responseDto.setLsMsg(lsMsg); |
| |
| try { |
| |
| if (id == null || !archiveRepository.exists(id)) { |
| SpErrorEntry ee = SpExceptionEnum.MISSING_PARAMETERS_EXCEPTION.getEntry(); |
| SpException spE = new SpException(ee.getCode(), null, ee.getMessage(), ee.getMessage()); |
| LOGGER.error(spE, spE); |
| throw spE; |
| } |
| |
| // the import works allways on the planning |
| StandbyStatus status = standbyStatusRepository.findOne(1L); |
| |
| ArchiveStandbyScheduleHeader header = archiveRepository.findOne(id); |
| String jsonPlan = header.getJsonPlan(); |
| |
| StandbyScheduleArchiveDto plan = new Gson().fromJson(jsonPlan, StandbyScheduleArchiveDto.class); |
| |
| lsMsg.add(createMsg("Das Archiv (" + header.getId() + ") '" + header.getTitle() |
| + "' wird in die Plan-Ebene übernommen. ", PlanningMsgDto.INFO, PlanningMsgDto.CSS_WARN)); |
| |
| importPlanFast(header, plan, status, lsMsg, modUserName); |
| |
| } catch (SpException e) { |
| LOGGER.error(e, e); |
| throw e; |
| } |
| return responseDto; |
| |
| } |
| |
| private boolean importPlanFast(ArchiveStandbyScheduleHeader header, StandbyScheduleArchiveDto plan, |
| StandbyStatus status, List<PlanningMsgDto> lsMsg, String userName) { |
| boolean isImported = true; |
| boolean printWarningDetails = true; |
| int warnCount = 0; |
| |
| List<PlanningMsgDto> msg = new ArrayList<>(); |
| List<PlanningMsgDto> msgWarning = new ArrayList<>(); |
| |
| StandbyScheduleFilterDto filter = plan.getFilter(); |
| Date startDate = filter.getValidFrom(); |
| Date endDate = filter.getValidTo(); |
| |
| msg.add(createMsg( |
| "Importzeitraum ist von " + DateHelper.convertToLocalString(startDate, null) + " bis " |
| + DateHelper.convertToLocalString(endDate, null), |
| PlanningMsgDto.INFO, PlanningMsgDto.CSS_INFO)); |
| msg.add(createMsg("Vorhandene Daten der Plan-Ebene werden gelöscht. ", PlanningMsgDto.INFO, |
| PlanningMsgDto.CSS_INFO)); |
| |
| // get groupIDs |
| List<StandbyGroupSelectionDto> listOfGroups = plan.getPlanHeader().getListGroups(); |
| List<Long> lsGroupIds = new ArrayList<>(); |
| |
| Map<Long, StandbyGroup> mapGroups = new HashMap<>(); |
| Map<Long, User> mapUser = new HashMap<>(); |
| |
| warnCount = initGroups(mapGroups, listOfGroups, lsGroupIds, msgWarning, warnCount); |
| |
| if (lsGroupIds.isEmpty()) { |
| msgWarning.add(createMsg("Die Gruppen im Archiv können nicht verarbeitet werden!", |
| PlanningMsgDto.CSS_DANGER, PlanningMsgDto.CSS_WARN)); |
| |
| } else { |
| |
| Long[] groupIds = lsGroupIds.toArray(new Long[lsGroupIds.size()]); |
| |
| List<StandbyScheduleBody> oldBodyData = plannedDataController.matrixOfPlannedBodysByStatus(groupIds, |
| startDate, endDate, status.getId(), true); |
| |
| msg.add(createMsg("Es werden " + oldBodyData.size() + " Bereitschaften in der Planebene gelöscht. ", |
| PlanningMsgDto.INFO, PlanningMsgDto.CSS_INFO)); |
| |
| // delete |
| standbyScheduleBodyRepository.delete(oldBodyData); |
| |
| oldBodyData.clear(); |
| |
| msg.add(createMsg("Bereitschaften in der Planebene gelöscht. ", PlanningMsgDto.INFO, |
| PlanningMsgDto.CSS_INFO)); |
| |
| // collect all arc bodies |
| |
| List<StandbyScheduleBody> bodyData = new ArrayList<>(); |
| List<PlanRowsArchiveDto> rows = plan.getListPlanRows(); |
| for (PlanRowsArchiveDto planRowsArchiveDto : rows) { |
| |
| List<List<StandbyScheduleBodySelectionDto>> groupList = planRowsArchiveDto.getListGroupBodys(); |
| |
| for (List<StandbyScheduleBodySelectionDto> dayList : groupList) { |
| |
| for (StandbyScheduleBodySelectionDto bodyDto : dayList) { |
| |
| Long userId = bodyDto.getUser().getId(); |
| Long groupId = bodyDto.getStandbyGroup().getId(); |
| |
| mapUser = initUser(mapUser, userId); |
| |
| if (mapGroups.containsKey(groupId) && mapUser.containsKey(userId)) { |
| |
| // createEntry |
| StandbyScheduleBody newSbsb = new StandbyScheduleBody(); |
| newSbsb.setStatus(status); |
| newSbsb.setModificationDate(new Date()); |
| newSbsb.setModifiedCause( |
| "reimport aus Archiv (" + header.getId() + ") " + header.getModifiedBy() + "."); |
| newSbsb.setModifiedBy(userName); |
| |
| newSbsb.setStandbyGroup(mapGroups.get(groupId)); |
| newSbsb.setUser(mapUser.get(userId)); |
| newSbsb.setValidFrom(bodyDto.getValidFrom()); |
| newSbsb.setValidTo(bodyDto.getValidTo()); |
| bodyData.add(newSbsb); |
| |
| } else { |
| warnCount = msgWarn(printWarningDetails, bodyDto, warnCount, msgWarning); |
| printWarningDetails = (warnCount < 50) ? true : false; |
| } |
| |
| } |
| |
| } |
| |
| } |
| |
| msg.add(createMsg("Es werden " + bodyData.size() + " Bereitschaften in der Planebene erstellt. ", |
| PlanningMsgDto.INFO, PlanningMsgDto.CSS_INFO)); |
| |
| standbyScheduleBodyRepository.save(bodyData); |
| |
| msg.add(createMsg("Bereitschaften in der Planebene erstellt. ", PlanningMsgDto.INFO, |
| PlanningMsgDto.CSS_INFO)); |
| |
| msg.add(createMsg("Es konnten " + warnCount + " Bereitschaften nicht hergestellt werden! ", |
| PlanningMsgDto.CSS_WARN, PlanningMsgDto.CSS_WARN)); |
| } |
| |
| msg.addAll(msgWarning); |
| |
| lsMsg.addAll(msg); |
| |
| return isImported; |
| } |
| |
| public Map<Long, User> initUser(Map<Long, User> mapUser, Long userId) { |
| |
| if (!mapUser.containsKey(userId) && userRepository.exists(userId)) { |
| User user = userRepository.findOne(userId); |
| mapUser.put(user.getId(), user); |
| } |
| |
| return mapUser; |
| } |
| |
| public int msgWarn(boolean printWarningDetails, StandbyScheduleBodySelectionDto bodyDto, int warnCount, |
| List<PlanningMsgDto> msgWarning) { |
| if (printWarningDetails) { |
| if (warnCount < 50) { |
| msgWarning.add(createMsg(getBodyString(bodyDto), PlanningMsgDto.INFO, PlanningMsgDto.CSS_WARN)); |
| } else { |
| |
| msgWarning.add(createMsg("und weitere ...", PlanningMsgDto.WARN, PlanningMsgDto.CSS_DANGER)); |
| |
| } |
| } |
| return ++warnCount; |
| } |
| |
| public int initGroups(Map<Long, StandbyGroup> mapGroups, List<StandbyGroupSelectionDto> listOfGroups, |
| List<Long> lsGroupIds, List<PlanningMsgDto> msgWarning, int warnCount) { |
| |
| for (int i = 0; i < listOfGroups.size(); i++) { |
| |
| StandbyGroupSelectionDto sbg = listOfGroups.get(i); |
| if (standbyGroupRepository.exists(sbg.getId())) { |
| |
| StandbyGroup standbyGroup = standbyGroupRepository.findOne(sbg.getId()); |
| mapGroups.put(standbyGroup.getId(), standbyGroup); |
| |
| } else { |
| msgWarning.add(createMsg("Bereitschaften der Gruppe (" + sbg.getId() + ") '" + sbg.getTitle() |
| + "' können nicht importiert werden!", PlanningMsgDto.INFO, PlanningMsgDto.CSS_WARN)); |
| warnCount++; |
| } |
| |
| } |
| |
| Set<Long> keySet = mapGroups.keySet(); |
| lsGroupIds.addAll(keySet); |
| |
| return warnCount; |
| } |
| |
| private String getBodyString(StandbyScheduleBodySelectionDto bodyDto) { |
| StringBuffer sb = new StringBuffer(); |
| |
| sb.append(bodyDto.getStandbyGroup().getTitle()); |
| sb.append(", "); |
| sb.append(bodyDto.getUser().getLastname()); |
| sb.append(", "); |
| sb.append(bodyDto.getUser().getFirstname()); |
| sb.append(" ["); |
| sb.append(bodyDto.getValidFrom()); |
| sb.append(","); |
| sb.append(bodyDto.getValidTo()); |
| sb.append("]"); |
| |
| return sb.toString(); |
| |
| } |
| |
| /** |
| * Method to create a failure message for saving an {@link StandbyScheduleBody} |
| * object. |
| * |
| * @param stbyBody |
| * @return |
| */ |
| public PlanningMsgDto createMsg(String txt, String type, String css, Object... obj) { |
| String info = txt; |
| |
| PlanningMsgDto dto = new PlanningMsgDto(info, type, css); |
| return dto; |
| } |
| |
| public boolean createArchiveForIntervallAndGroups(List<TransferGroupDto> lsTransferGroup, Date validFrom, |
| Date validTo, Long statusId, String username, String action, String comment) { |
| boolean isArchived = false; |
| |
| try { |
| |
| StandbyScheduleFilterDto standbyScheduleFilterDto = new StandbyScheduleFilterDto(); |
| standbyScheduleFilterDto.setLsTransferGroup(lsTransferGroup); |
| standbyScheduleFilterDto.setValidFrom(validFrom); |
| standbyScheduleFilterDto.setValidTo(validTo); |
| standbyScheduleFilterDto.setComment(comment); |
| standbyScheduleFilterDto.setTitle(action); |
| |
| // unique |
| Map<Long, TransferGroupDto> mapGroups = new HashMap<>(); |
| List<TransferGroupDto> lsGroups = standbyScheduleFilterDto.getLsTransferGroup(); |
| for (TransferGroupDto transferGroupDto : lsGroups) { |
| mapGroups.put(transferGroupDto.getGroupId(), transferGroupDto); |
| } |
| |
| List<TransferGroupDto> list = new ArrayList<TransferGroupDto>(mapGroups.values()); |
| |
| standbyScheduleFilterDto.setLsTransferGroup(list); |
| |
| StandbyScheduleArchiveDto plan = plannedDataController |
| .getFilteredPlanByStatusByGroupsForArchive(standbyScheduleFilterDto, statusId); |
| |
| ArchiveStandbyScheduleHeader header = createHeader(plan, statusId, standbyScheduleFilterDto.getTitle(), |
| standbyScheduleFilterDto.getComment(), username, action); |
| |
| archiveRepository.save(header); |
| |
| isArchived = true; |
| |
| } catch (SpException e) { |
| LOGGER.info(e.getMessage()); |
| } |
| |
| return isArchived; |
| } |
| |
| public List<ArchiveStandbyScheduleHeaderSelectionDto> search(StandbyScheduleSearchDto searchDto) { |
| List<ArchiveStandbyScheduleHeaderSelectionDto> listHeaderDto = new ArrayList<>(); |
| |
| Date date = searchDto.getDateIndex(); |
| |
| Date validFrom = DateHelper.getStartOfDay(date); |
| Date validTo = DateHelper.getEndOfDay(validFrom); |
| |
| List<ArchiveStandbyScheduleHeader> listHeader = archiveRepository.findByDate(validFrom, validTo); |
| |
| listHeaderDto = entityConverter.convertEntityToDtoList(listHeader, listHeaderDto, |
| ArchiveStandbyScheduleHeaderSelectionDto.class); |
| |
| return listHeaderDto; |
| } |
| |
| public boolean createArchiveOnMove(StandbyScheduleActionDto actionDto, String username) { |
| |
| StandbyScheduleBody body = standbyScheduleBodyRepository.findOne(actionDto.getScheduleBodyId()); |
| |
| StandbyGroup tempOldGroup = body.getStandbyGroup(); |
| StandbyGroup tempNewGroup = standbyGroupRepository.findOne(actionDto.getStandbyGroupId()); |
| |
| if (body.getStatus().getId().longValue() == SpMsg.STATUS_CLOSED_PLANNING.longValue()) { |
| |
| List<TransferGroupDto> lsGroup = new ArrayList<>(); |
| lsGroup.add(new TransferGroupDto(tempOldGroup.getTitle(), tempOldGroup.getId())); |
| lsGroup.add(new TransferGroupDto(tempNewGroup.getTitle(), tempNewGroup.getId())); |
| |
| String comment = ""; |
| |
| createArchiveForIntervallAndGroups(lsGroup, actionDto.getValidFrom(), actionDto.getValidTo(), |
| SpMsg.STATUS_CLOSED_PLANNING, username, SpMsg.ACT_STANDBY_MOVE + " " + body.toString(), comment); |
| |
| } |
| |
| return true; |
| } |
| |
| public boolean createArchiveOnReplaceInOneGroup(StandbyScheduleActionDto actionDto, String username) { |
| |
| User currentUser = userRepository.findOne(actionDto.getCurrentUserId()); |
| User newUser = userRepository.findOne(actionDto.getNewUserId()); |
| StandbyGroup group = standbyGroupRepository.findOne(actionDto.getStandbyGroupId()); |
| |
| if (actionDto.getStatusId().longValue() == SpMsg.STATUS_CLOSED_PLANNING.longValue()) { |
| |
| List<TransferGroupDto> lsGroup = new ArrayList<>(); |
| lsGroup.add(new TransferGroupDto(group.getTitle(), group.getId())); |
| |
| String comment = ""; |
| String text = currentUser.getFirstname() + " " + currentUser.getLastname() + " durch " |
| + newUser.getFirstname() + " " + newUser.getLastname(); |
| |
| createArchiveForIntervallAndGroups(lsGroup, actionDto.getValidFrom(), actionDto.getValidTo(), |
| SpMsg.STATUS_CLOSED_PLANNING, username, SpMsg.ACT_STANDBY_REPLACE + " " + text, comment); |
| } |
| |
| return true; |
| |
| } |
| |
| } |