blob: f21b02c88c7ca9a28e0ad52d76ddd6c8d986a2ff [file] [log] [blame]
/********************************************************************************
* 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;
}
}