package kr.wisestone.owl.service.impl; import com.google.common.collect.Lists; import kr.wisestone.owl.common.ExcelConditionCheck; import kr.wisestone.owl.constant.Constants; import kr.wisestone.owl.constant.MsgConstants; import kr.wisestone.owl.domain.*; import kr.wisestone.owl.domain.enumType.EmailType; import kr.wisestone.owl.domain.enumType.ProjectType; import kr.wisestone.owl.domain.enumType.ServiceType; import kr.wisestone.owl.exception.OwlRuntimeException; import kr.wisestone.owl.mapper.WorkspaceMapper; import kr.wisestone.owl.repository.WorkspaceRepository; import kr.wisestone.owl.service.*; import kr.wisestone.owl.util.*; import kr.wisestone.owl.vo.ExportExcelVo; import kr.wisestone.owl.vo.WorkspaceVo; import kr.wisestone.owl.web.form.*; import kr.wisestone.owl.web.view.ExcelView; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.ui.Model; import org.springframework.web.servlet.ModelAndView; import java.util.*; @Service public class WorkspaceServiceImpl extends AbstractServiceImpl> implements WorkspaceService { private static final Logger log = LoggerFactory.getLogger(WorkspaceServiceImpl.class); @Autowired private WorkspaceRepository workspaceRepository; @Autowired private IssueStatusService issueStatusService; @Autowired private UserWorkspaceService userWorkspaceService; @Autowired private WorkflowService workflowService; @Autowired private IssueTypeService issueTypeService; @Autowired private SimpMessagingTemplate simpMessagingTemplate; @Autowired private WorkspaceMapper workspaceMapper; @Autowired private AttachedFileService attachedFileService; @Autowired private UserService userService; @Autowired private SystemEmailService systemEmailService; @Autowired private PriorityService priorityService; @Autowired private SeverityService severityService; @Autowired private ExcelView excelView; @Autowired private ExcelConditionCheck excelConditionCheck; // zenith add type @Value("${saas.packagetype}") private Integer packageType; @Value("${saas.maxUser}") private Integer maxUserCount; @Value("${saas.period}") private Integer usePeriod; @Value("${saas.usdkrw}") private Integer usdKrw; @Override protected JpaRepository getRepository() { return this.workspaceRepository; } // 업무 공간 생성 @Override @Transactional public Workspace addWorkspace(String workspaceName) { Workspace workspace = new Workspace(); // 업무 공간 명 유효성 체크 this.verifyWorkspaceName(workspaceName); workspace.setName(workspaceName); workspace.setMaxUser(this.maxUserCount); workspace.setStorageSize(workspace.calculateStorageSize()); workspace.setStartDate(new Date()); workspace.setExpireDate(DateUtil.addDays(new Date(), this.usePeriod)); workspace.setServiceType(ServiceType.USE); this.workspaceRepository.saveAndFlush(workspace); // 시스템에서 사용할 수 있는 기본 제공 이슈 상태를 생성한다. this.issueStatusService.addDefaultIssueStatus(workspace); // 시스템에서 사용할 수 있는 기본 워크플로우를 생성한다. this.workflowService.addDefaultWorkflow(workspace, Arrays.asList(ProjectType.BTS_PROJECT, ProjectType.RMS_PROJECT, ProjectType.TCM_PROJECT)); // 시스템에서 사용할 수 있는 기본 이슈 유형을 생성한다. this.issueTypeService.addDefaultIssueType(workspace, Arrays.asList(ProjectType.BTS_PROJECT, ProjectType.RMS_PROJECT, ProjectType.TCM_PROJECT)); // 시스템에서 사용할 수 있는 기본 우선 순위를 생성한다. this.priorityService.addDefaultPriority(workspace); // 시스템에서 사용할 수 있는 기본 중요도를 생성한다. this.severityService.addDefaultSeverity(workspace); return workspace; } // 업무 공간 명 유효성 체크 private void verifyWorkspaceName(String workspaceName) { if (StringUtils.isEmpty(workspaceName)) { throw new OwlRuntimeException( this.messageAccessor.getMessage(MsgConstants.WORKSPACE_NOT_NAME)); } if (workspaceName.length() > 50) { throw new OwlRuntimeException( this.messageAccessor.getMessage(MsgConstants.WORKSPACE_NAME_MAX_LENGTH_OUT)); } } // 업무 공간에서 사용자 제외 @Override @Transactional public void out(WorkspaceForm workspaceForm) { /*List users = this.userService.findByIdIn(workspaceForm.getUserIds()); Workspace workspace = this.workspaceRepository.findOne(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); List userEmails = Lists.newArrayList(); users.parallelStream().forEach(user -> { userEmails.add(user.getAccount()); }); // 해당 업무 공간에 존재하는 모든 프로젝트에서 제외 this.projectRoleUserService.outWorkspaceModifyProjectRole(workspace, userEmails); // 이전에 보낸 초대 정보 삭제 this.userInviteService.deleteUserInvite(workspace.getId(), userEmails); // 업무 공간 사용자 연결 정보 삭제 this.userWorkspaceService.deleteUserWorkspace(workspace, workspaceForm.getUserIds()); // 이슈의 담당자였으면 해당 이슈에서 담당자 제외 this.issueUserService.outWorkspaceModifyAssignee(workspace, userEmails); // 업무 공간 제외 이메일 알림 String[] sendUsers = userEmails.toArray(new String[userEmails.size()]); Map content = new HashMap<>(); content.put("workspaceName", workspace.getName()); this.systemEmailService.sendEmail(sendUsers, EmailType.WORKSPACE_OUT, content);*/ } // 정기 결제가 완료된 후 업무 공간 만료일, 최대 사용자 수, 저장 공간, 사용 가능 트래픽을 업데이트 한다. @Override @Transactional public Workspace updateWorkspace(Workspace workspace, PaymentForm paymentForm) { Date nextExpireDate = workspace.calculateNextPaymentDate(paymentForm.getType(), workspace.getExpireDate()); Date expireDate = DateUtil.convertStrToDate(DateUtil.convertDateToStr(nextExpireDate, "yyyy-MM-dd") + " 23:59:59"); workspace.setStartDate(new Date()); workspace.setExpireDate(expireDate); workspace.setMaxUser(paymentForm.getBuyUser()); workspace.setStorageSize(workspace.calculateStorageSize()); workspace.setUseTraffic(0L); workspace.setServiceType(ServiceType.USE); return this.workspaceRepository.saveAndFlush(workspace); } // 추가 결제 완료 후 최대 사용자 수, 저장 공간을 업데이트한다. @Override @Transactional public Workspace updateWorkspaceByImmediatePayment(Workspace workspace, int buyUser) { workspace.setMaxUser(buyUser); workspace.setStorageSize(workspace.calculateStorageSize()); return this.workspaceRepository.saveAndFlush(workspace); } // 정기 결제일이 된 업무 공간 목록을 가져온다. - 스케쥴링에서 사용함 @Override @Transactional(readOnly = true) public List findSubscribeImmediateExpireDate() { String today = DateUtil.convertDateToYYYYMMDD(DateUtil.addDays(new Date(), -1)); Date todayFrom = DateUtil.convertStrToDate(today + " 00:00:00"); Date todayTo = DateUtil.convertStrToDate(today + " 23:59:59"); return this.workspaceRepository.findSubscribeImmediateExpireDate(todayFrom, todayTo); } // 사용자 및 사용 가능 용량 초기화 @Override @Transactional public void initMaxUserAndStorageSize(Workspace workspace) { workspace.setMaxUser(0); workspace.setStorageSize(0L); workspace.setServiceType(ServiceType.UNUSED); // 사용 안함으로 변경 workspace.setPayment(null); // 이전 결제 정보 삭제 this.workspaceRepository.saveAndFlush(workspace); } // 업무 공간 정기 결제 취소 - 정기 결제 정보 삭제 @Override @Transactional public void cancelWorkspacePayment(Workspace workspace) { workspace.setPayment(null); this.workspaceRepository.saveAndFlush(workspace); } // 최초 설치한 관리자가 생성한 업무 공간를 가져온다. @Override @Transactional(readOnly = true) public Workspace getPrimaryWorkspace() { Long workspaceid = 0L; List users = this.userService.findAdmin(); if(users.size() > 0 ) { User adminUser = users.get(0); workspaceid = adminUser.getLastWorkspaceId(); } if (workspaceid == 0) { return null; } Workspace workspace = this.findOne(workspaceid); if (workspace == null) { throw new OwlRuntimeException( this.messageAccessor.getMessage(MsgConstants.WORKSPACE_NOT_EXIST)); } return workspace; } // 아이디에 해당하는 업무 공간를 가져온다. @Override @Transactional(readOnly = true) public Workspace getWorkspace(Long id) { if (id == null) { throw new OwlRuntimeException( this.messageAccessor.getMessage(MsgConstants.WORKSPACE_NOT_EXIST)); } Workspace workspace = this.findOne(id); if (workspace == null) { throw new OwlRuntimeException( this.messageAccessor.getMessage(MsgConstants.WORKSPACE_NOT_EXIST)); } return workspace; } // 참여하고 있는 업무 공간 목록을 가져온다. @Override @Transactional(readOnly = true) public void find(Map resJsonData) { List workspaces = this.workspaceRepository.findByUserId(this.webAppUtil.getLoginId()); List workspaceVos = Lists.newArrayList(); for (Workspace workspace : workspaces) { WorkspaceVo workspaceVo = ConvertUtil.copyProperties(workspace, WorkspaceVo.class); workspaceVos.add(workspaceVo); } resJsonData.put(Constants.RES_KEY_CONTENTS, workspaceVos); } // 자신이 관리하는 업무 공간를 가져온다. @Override @Transactional(readOnly = true) public void findPrimaryWorkspace(Map resJsonData) { boolean bHavePrimaryWorkspace = false; Workspace primaryWorkspace = this.getPrimaryWorkspace(); if(primaryWorkspace != null) { bHavePrimaryWorkspace = true; } resJsonData.put(Constants.RES_KEY_CONTENTS, bHavePrimaryWorkspace); } // 자신이 관리하는 업무 공간를 가져온다. @Override @Transactional(readOnly = true) public void findMyWorkspace(Map resJsonData) { UserWorkspace userWorkspace = this.userWorkspaceService.findWorkspaceManager(this.webAppUtil.getLoginId()); //워크스페이스 관리자 if(userWorkspace == null){ userWorkspace = this.userWorkspaceService.findMyWorkspace(this.webAppUtil.getLoginId()); } Workspace workspace = userWorkspace.getWorkspace(); WorkspaceVo workspaceVo = ConvertUtil.copyProperties(workspace, WorkspaceVo.class); workspaceVo.setServiceType((workspace.getServiceType().toString())); workspaceVo.setExpireDateTerm(DateUtil.getDateDiff(new Date(), workspace.getExpireDate())); // 추가 결제를 진행할 때 금액 계산을 위해 사용 // zenith edit // packagetype을 저장한다. workspaceVo.setPackageType(this.packageType); // 업무 공간 사용 가능 기간 this.checkRemainPeriod(workspace, workspaceVo); // 현재 사용 용량 this.checkUseStorageSize(workspace, workspaceVo); // 참여 사용자 this.checkActiveUserCount(workspace, workspaceVo); // 참여 대기 사용자 this.checkStandByUserCount(workspace, workspaceVo); // 환율 정보 workspaceVo.setUsdKrw(this.usdKrw); resJsonData.put(Constants.RES_KEY_CONTENTS, workspaceVo); } // zenith edit private long getRemainPeriod(Date fromDate, Date toDate) { long lRemainDays = 0; // zenith edit packageType 1 이상이명, 만료일이 없음. (local version) if (this.packageType > 0) { lRemainDays = 9999; } else { Integer totalDate = DateUtil.getDateDiff(fromDate, toDate); // 사용 가능 기간은 0보다 적을 경우 0으로 표시 if (totalDate < 0) { totalDate = 0; } lRemainDays = totalDate.longValue(); } return lRemainDays; } // 업무 공간 사용 가능 기간 private void checkRemainPeriod(Workspace workspace, WorkspaceVo workspaceVo) { long lRemainDays = getRemainPeriod(new Date(), workspace.getExpireDate()); workspaceVo.setTotalDate(lRemainDays); } // 현재 사용 용량 private void checkUseStorageSize(Workspace workspace, WorkspaceVo workspaceVo) { // 업무 공간에서 사용중인 저장 용량을 조회한다. Long useStorageSize = this.attachedFileService.findUseStorage(workspace); if (useStorageSize == null) { useStorageSize = 0L; } workspaceVo.setUseStorageSize(useStorageSize); } // 참여 사용자 private void checkActiveUserCount(Workspace workspace, WorkspaceVo workspaceVo) { Integer userCount = this.userWorkspaceService.countByWorkspaceIdAndUseYn(workspace.getId(), true); workspaceVo.setActiveUser(userCount); } // 참여 대기 사용자 private void checkStandByUserCount(Workspace workspace, WorkspaceVo workspaceVo) { Integer userCount = this.userWorkspaceService.countByWorkspaceIdAndUseYn(workspace.getId(), false); workspaceVo.setStandByUser(userCount); } // 사용자가 회원 탈퇴를 진행하면 업무 공간에 있는 정보를 삭제한다. @Override @Transactional public void removeWorkspace(Workspace workspace, User user) { // 삭제되는 업무 공간에 참여하고 있는 사용자 List updateTargetUsers = this.findUpdateLastWorkspaceTargetUser(workspace); String workspaceName = workspace.getName(); Map deleteWorkspaceMap = new HashMap<>(); deleteWorkspaceMap.put("workspaceId", workspace.getId()); // 업무 공간에 연관된 테이블을 삭제하기 위해 id 값을 추출한다. this.setWorkspaceRelationIds(workspace, deleteWorkspaceMap); // 업무 공간에 있는 모든 정보를 삭제한다. this.workspaceMapper.deleteWorkspace(deleteWorkspaceMap); // 업무 공간 삭제시 이슈에 첨부된 파일을 시스템에서 삭제한다. this.attachedFileService.deleteWorkspaceCascadeAttachedFile(workspace); // 업무 공간을 사용하지 못하도록 한다. workspace.setStorageSize(0L); // 저장 가능 공간 0으로 변경 workspace.setMaxUser(0); // 사용 가능 인원 0으로 변경 workspace.setServiceType(ServiceType.UNUSED); // 업무 공간 서비스를 사용 안함으로 변경 this.workspaceRepository.flush(); for (String account : updateTargetUsers) { // 업무 공간에 참여하던 사용자에게 업무 공간 삭제 알림 및 화면 새로고침 this.simpMessagingTemplate.convertAndSendToUser(account, "/notification/workspace-remove", this.messageAccessor.getMessage(MsgConstants.WORKSPACE_OUT, workspaceName)); } } // 업무 공간에 연관된 테이블을 삭제하기 위해 id 값을 추출한다. private void setWorkspaceRelationIds(Workspace workspace, Map deleteWorkspaceMap) { List workflowIds = Lists.newArrayList(); for (Workflow workflow : workspace.getWorkflows()) { workflowIds.add(workflow.getId()); } deleteWorkspaceMap.put("workflowIds", workflowIds); List userInviteIds = Lists.newArrayList(); for (UserInvite userInvite : workspace.getUserInvites()) { userInviteIds.add(userInvite.getId()); } deleteWorkspaceMap.put("userInviteIds", userInviteIds); List projectIds = Lists.newArrayList(); List projectRoleIds = Lists.newArrayList(); for (Project project : workspace.getProjects()) { projectIds.add(project.getId()); for (ProjectRole projectRole : project.getProjectRoles()) { projectRoleIds.add(projectRole.getId()); } } deleteWorkspaceMap.put("projectIds", projectIds); deleteWorkspaceMap.put("projectRoleIds", projectRoleIds); List customFieldIds = Lists.newArrayList(); for (CustomField customField : workspace.getCustomFields()) { customFieldIds.add(customField.getId()); } deleteWorkspaceMap.put("customFieldIds", customFieldIds); } // 삭제되는 업무 공간에 참여하고 있는 사용자 private List findUpdateLastWorkspaceTargetUser(Workspace workspace) { List updateTargetUsers = Lists.newArrayList(); // 해당 업무 공간을 마지막으로 접근한 사용자 목록 List userWorkspaces = this.userWorkspaceService.findByWorkspaceIdAndManagerYn(workspace.getId(), false); for (UserWorkspace userWorkspace : userWorkspaces) { User user = userWorkspace.getUser(); if (workspace.getId().equals(user.getLastWorkspaceId())) { updateTargetUsers.add(user.getAccount()); } // 해당 사용자가 관리하는 업무 공간을 마지막으로 접근한 업무 공간 정보로 업데이트한다. this.userService.updateLastDefaultWorkspace(workspace, user); } return updateTargetUsers; } // 업무 공간 명을 수정한다. @Override @Transactional public void modifyWorkspace(WorkspaceForm workspaceForm) { Workspace workspace = this.getWorkspace(workspaceForm.getWorkspaceId()); // 업무 공간 명 유효성 체크 this.verifyWorkspaceName(workspaceForm.getName()); workspace.setName(workspaceForm.getName()); this.workspaceRepository.saveAndFlush(workspace); } // 사용 기간이 만료된 업무 공간을 찾아 용량, 최대 사용자, 서비스 유형을 변경한다. @Override @Transactional public void expireWorkspace() { // zenith edit packageType 0 이상이면, 만료일이 없음. (local version) if(this.packageType > 0) { String today = DateUtil.convertDateToYYYYMMDD(DateUtil.addDays(new Date(), -1)); Date todayFrom = DateUtil.convertStrToDate(today + " 00:00:00"); Date todayTo = DateUtil.convertStrToDate(today + " 23:59:59"); // 결제일이 도래된 업무 공간 목록을 가져온다. List workspaces = this.workspaceRepository.findExpireDate(todayFrom, todayTo); for (Workspace workspace : workspaces) { // 사용기간이 만료된 업무 공간의 관리자가 아닌 사용자를 추출하여 마지막 접근한 업무 공간 정보를 변경한다. this.userWorkspaceService.limitExpireUserWorkspace(workspace); List managerUserWorkspace = this.userWorkspaceService.findByWorkspaceIdAndManagerYn(workspace.getId(), true); for (UserWorkspace userWorkspace : managerUserWorkspace) { Map workspaceMap = new HashMap<>(); workspaceMap.put("workspaceName", workspace.getName()); workspaceMap.put("userName", userWorkspace.getUser().getName()); workspaceMap.put("expireDate", DateUtil.convertDateToYYYYMMDD(workspace.getExpireDate())); // 업무 공간 관리자에게 사용 기간 만료 알림 this.systemEmailService.directEmail(new String[]{userWorkspace.getUser().getAccount()}, EmailType.WORKSPACE_EXPIRE, workspaceMap, null); } // 업무 공간 최대 사용자 및 사용 가능 용량 초기화 this.initMaxUserAndStorageSize(workspace); } } } // 업무 공간 만료 안내 메일을 보낸다. @Override @Transactional(readOnly = true) public void expireAlarmWorkspace() { // 7일 후 만료인 업무 공간 담당자에게 메일 보내기 this.sendExpireAlarmWorkspace(7); // 3일 후 만료인 업무 공간 담당자에게 메일 보내기 this.sendExpireAlarmWorkspace(3); } private void sendExpireAlarmWorkspace(int dayCount) { String day = DateUtil.convertDateToYYYYMMDD(DateUtil.addDays(new Date(), dayCount)); Date dayFrom = DateUtil.convertStrToDate(day + " 00:00:00"); Date dayTo = DateUtil.convertStrToDate(day + " 23:59:59"); // 만료일이 도래된 업무 공간을 가져온다. List workspaces = this.workspaceRepository.findExpireDate(dayFrom, dayTo); for (Workspace workspace : workspaces) { List userWorkspaces = this.userWorkspaceService.findByWorkspaceIdAndManagerYn(workspace.getId(), true); if (userWorkspaces.size() > 0) { Map workspaceMap = new HashMap<>(); workspaceMap.put("workspaceName", workspace.getName()); workspaceMap.put("expireDate", DateUtil.convertDateToYYYYMMDD(workspace.getExpireDate())); workspaceMap.put("dayCount", dayCount); workspaceMap.put("name", userWorkspaces.get(0).getUser().getName()); // 업무 공간 관리자에게 사용 기간 만료 예정일 알림 this.systemEmailService.directEmail(new String[]{userWorkspaces.get(0).getUser().getAccount()}, EmailType.WORKSPACE_EXPIRE_ALARM, workspaceMap, null); } } } // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. @Override @Transactional public void checkUseWorkspace() { User user = this.webAppUtil.getLoginUserObject(); Workspace workspace = this.getWorkspace(user.getLastWorkspaceId()); this.checkUseWorkspace(user, workspace.getId()); } // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. @Override @Transactional public void checkUseWorkspace(User user) { Workspace workspace = this.getWorkspace(user.getLastWorkspaceId()); this.checkUseWorkspace(user, workspace.getId()); } // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. @Override @Transactional public Workspace checkUseWorkspace(User user, Long workspaceId) { if (user == null) { throw new OwlRuntimeException( this.messageAccessor.getMessage(MsgConstants.USER_NOT_EXIST)); } if (workspaceId == null) { throw new OwlRuntimeException( this.messageAccessor.getMessage(MsgConstants.WORKSPACE_NOT_EXIST)); } Workspace workspace = this.getWorkspace(workspaceId); if (workspace.getServiceType().equals(ServiceType.UNUSED)) { throw new OwlRuntimeException( this.messageAccessor.getMessage(MsgConstants.WORKSPACE_USE_PERIOD_EXCESS)); } UserWorkspace userWorkspace = this.userWorkspaceService.findByUserIdAndWorkspaceId(user.getId(), workspace.getId()); if (!userWorkspace.getUseYn()) { // 해당 사용자가 관리하는 업무 공간를 마지막 접근 업무 공간로 변경한다. this.userService.updateLastMyWorkspace(userWorkspace.getUser()); // 비활성 사용자는 더이상 해당 업무 공간에 있으면 안된다. this.simpMessagingTemplate.convertAndSendToUser(user.getAccount(), "/notification/workspace-remove", this.messageAccessor.getMessage(MsgConstants.WORKSPACE_OUT, workspace.getName())); throw new OwlRuntimeException( this.messageAccessor.getMessage(MsgConstants.WORKSPACE_INCLUDE_DISABLED)); } return workspace; } // 사용 공간에서 로그인한 사용자가 비활성인지 확인하고 비활성일 경우 엑셀 다운로드를 금지한다. @Override @Transactional public ModelAndView checkUseExcelDownload(Model model) { try { // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. this.checkUseWorkspace(); } catch (OwlRuntimeException e) { // 업무 공간 활성 체크에서 Exception 이 전송되어 이 부분에서 Exception 메세지를 전송하지 않는다. ExportExcelVo excelInfo = this.excelConditionCheck.makeEmptyDownloadExcel(); excelInfo.setFileName(this.messageAccessor.message("common.excelDownloadNotPossibleExcludedFromTheWorkspace")); // 업무 공간에서 참여가 제외되어 엑셀 다운로드가 불가능합니다. model.addAttribute(Constants.EXCEL, excelInfo); return new ModelAndView(this.excelView); } return null; } // 트래픽 사용량을 저장하고 초과할 경우에는 해당 업무 공간에서 다운로드를 일시적으로 금지한다. @Override @Transactional public boolean checkUseTraffic(Long fileSize) { // zenith edit packageType 0 이상이면, 트래픽 제약이 없음. (local version) if(this.packageType > 0) { Workspace workspace = this.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); // 트래픽은 사용 공간의 3배로 준다. if (workspace.getUseTraffic() > workspace.getStorageSize() * 3) { return false; } Long useTraffic = workspace.getUseTraffic() + fileSize; workspace.setUseTraffic(useTraffic); this.workspaceRepository.saveAndFlush(workspace); } return true; } // 업무 공간의 남은 사용 기간을 조회한다. @Override @Transactional(readOnly = true) public Map getWorkspaceExpireDay() { Map workspaceMap = new HashMap<>(); Workspace workspace = this.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); workspaceMap.put("name", workspace.getName()); // zenith edit workspaceMap.put("expireDay", getRemainPeriod(new Date(), workspace.getExpireDate())); return workspaceMap; } }