/* * Copyright (c) 2005-2011 Grameen Foundation USA * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * See also http://www.apache.org/licenses/LICENSE-2.0.html for an * explanation of the license and how it is applied. */ package org.mifos.platform.questionnaire.service; import java.text.ParseException; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.mifos.application.admin.servicefacade.RolesPermissionServiceFacade; import org.mifos.application.master.business.LookUpValueEntity; import org.mifos.application.master.persistence.LegacyMasterDao; import org.mifos.core.MifosRuntimeException; import org.mifos.framework.exceptions.SystemException; import org.mifos.platform.questionnaire.AuditLogService; import org.mifos.platform.questionnaire.QGFlowsService; import org.mifos.platform.questionnaire.domain.QuestionGroup; import org.mifos.platform.questionnaire.domain.QuestionnaireService; import org.mifos.platform.questionnaire.service.dtos.EventSourceDto; import org.mifos.platform.questionnaire.service.dtos.QuestionDto; import org.mifos.platform.questionnaire.service.dtos.QuestionGroupDto; import org.mifos.platform.questionnaire.service.dtos.QuestionGroupInstanceDto; import org.mifos.security.util.SecurityConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.AccessDeniedException; public class QuestionnaireServiceFacadeImpl implements QuestionnaireServiceFacade { @Autowired private QuestionnaireService questionnaireService; @Autowired private AuditLogService auditLogService; @Autowired private QGFlowsService qgFlowsService; @Autowired private RolesPermissionServiceFacade rolesPermissionService; public LegacyMasterDao legacyMasterDao; public QuestionnaireServiceFacadeImpl(QuestionnaireService questionnaireService,RolesPermissionServiceFacade rolesPermissionService) { this.questionnaireService = questionnaireService; this.rolesPermissionService = rolesPermissionService; } public QuestionnaireServiceFacadeImpl(QuestionnaireService questionnaireService, AuditLogService auditLogService, QGFlowsService qgFlowsService) { this.questionnaireService = questionnaireService; this.auditLogService = auditLogService; this.qgFlowsService = qgFlowsService; } @SuppressWarnings({"UnusedDeclaration"}) public QuestionnaireServiceFacadeImpl() { this(null,null); } @Override public void createQuestions(List<QuestionDetail> questionDetails) throws SystemException { for (QuestionDetail questionDetail : questionDetails) { questionnaireService.defineQuestion(questionDetail); } } @Override public boolean isDuplicateQuestion(String text) { return questionnaireService.isDuplicateQuestionText(text); } @Override public QuestionGroupDetail createQuestionGroup(QuestionGroupDetail questionGroupDetail) throws SystemException { questionGroupDetail.setActivityId(addActivityPermission(questionGroupDetail.getTitle(), questionGroupDetail.getId())); return questionnaireService.defineQuestionGroup(questionGroupDetail); } @Override public QuestionGroupDetail createActiveQuestionGroup(QuestionGroupDetail questionGroupDetail) throws SystemException { questionGroupDetail.setActivityId(addActivityPermission(questionGroupDetail.getTitle(), questionGroupDetail.getId())); return questionnaireService.defineQuestionGroup(questionGroupDetail); } @Override public List<QuestionDetail> getAllQuestions() { return questionnaireService.getAllQuestions(); } @Override public List<QuestionDetail> getAllActiveQuestions() { return questionnaireService.getAllActiveQuestions(null); } @Override public List<QuestionDetail> getAllActiveQuestions(List<Integer> excludedQuestions) { return questionnaireService.getAllActiveQuestions(excludedQuestions); } @Override public List<QuestionGroupDetail> getAllQuestionGroups() { return questionnaireService.getAllQuestionGroups(); } @Override public QuestionGroupDetail getQuestionGroupDetail(Integer questionGroupId) throws SystemException { if(!checkAccessToQuestionGroup(questionGroupId)) { throw new AccessDeniedException("Access denied"); } return questionnaireService.getQuestionGroup(questionGroupId); } @Override public QuestionGroupDetail getQuestionGroupDetailForLoanPrd(Integer questionGroupId) throws SystemException { return questionnaireService.getQuestionGroup(questionGroupId); } @Override public QuestionDetail getQuestionDetail(Integer questionId) throws SystemException { return questionnaireService.getQuestion(questionId); } @Override public List<EventSourceDto> getAllEventSources() { return questionnaireService.getAllEventSources(); } @Override public Integer getEventSourceId(String event, String source) { return questionnaireService.getEventSourceId(event, source); } @Override public void saveResponses(QuestionGroupDetails questionGroupDetails) { questionnaireService.saveResponses(questionGroupDetails); if (auditLogService != null) { int creatorId = questionGroupDetails.getCreatorId(); int entityId = questionGroupDetails.getEntityId(); for (QuestionGroupDetail questionGroupDetail : questionGroupDetails.getDetails()) { EventSourceDto eventSourceDto = questionnaireService.getEventSource(questionGroupDetails.getEventSourceId()); String source = eventSourceDto.getSource(); String event = eventSourceDto.getEvent(); QuestionGroupDetail secondLastQuestionGroupDetail = null; int max = 0; int secondMax = 0; List<QuestionGroupInstanceDetail> oldQuestionGroupDetails = questionnaireService.getQuestionGroupInstances(entityId, eventSourceDto, false, false); for (QuestionGroupInstanceDetail oldQuestionGroupDetail : oldQuestionGroupDetails) { // find previously entered responses that belong to the same question group as one being saved if (oldQuestionGroupDetail.getQuestionGroupDetail().getId().equals(questionGroupDetail.getId())) { if (oldQuestionGroupDetail.getId() >= max) { secondMax = max; max = oldQuestionGroupDetail.getId(); } else if (oldQuestionGroupDetail.getId() > secondMax) { secondMax = oldQuestionGroupDetail.getId(); } } } if (secondMax != 0) { secondLastQuestionGroupDetail = questionnaireService.getQuestionGroupInstance(secondMax).getQuestionGroupDetail(); } auditLogService.addAuditLogRegistry(questionGroupDetail, secondLastQuestionGroupDetail, creatorId, entityId, source, event); } } } @Override public void validateResponses(List<QuestionGroupDetail> questionGroupDetails) { questionnaireService.validateResponses(questionGroupDetails); } @Override public List<QuestionGroupDetail> getQuestionGroups(String event, String source) throws SystemException { return questionnaireService.getQuestionGroups(getEventSource(event, source)); } @Override public List<QuestionGroupInstanceDetail> getQuestionGroupInstances(Integer entityId, String event, String source) { List<QuestionGroupInstanceDetail> details = questionnaireService.getQuestionGroupInstances(entityId, getEventSource(event, source), false, false); updateEditableForUserValues(details); return details; } @Override public List<QuestionGroupInstanceDetail> getQuestionGroupInstancesWithUnansweredQuestionGroups(Integer entityId, String event, String source) { boolean includeUnansweredQuestionGroups = true; if(event.equals("Create") && source.equals("Loan")) { includeUnansweredQuestionGroups = false; } List<QuestionGroupInstanceDetail> details = filterInActiveQuestions(questionnaireService.getQuestionGroupInstances(entityId, getEventSource(event, source), includeUnansweredQuestionGroups, true)); updateEditableForUserValues(details); return details; } private void updateEditableForUserValues(List<QuestionGroupInstanceDetail> details) { for (QuestionGroupInstanceDetail detail: details) { detail.setEditableForUser(checkAccessToQuestionGroup(detail.getQuestionGroupDetail().getId())); } } private List<QuestionGroupInstanceDetail> filterInActiveQuestions(List<QuestionGroupInstanceDetail> instanceDetails) { for (QuestionGroupInstanceDetail instanceDetail : instanceDetails) { for (SectionDetail sectionDetail : instanceDetail.getQuestionGroupDetail().getSectionDetails()) { List<SectionQuestionDetail> sectionQuestionDetails = sectionDetail.getQuestions(); for (Iterator<SectionQuestionDetail> iterator = sectionQuestionDetails.iterator(); iterator.hasNext();) { SectionQuestionDetail sectionQuestionDetail = iterator.next(); if (sectionQuestionDetail.isNotActive()) { iterator.remove(); } } } } return instanceDetails; } @Override public QuestionGroupInstanceDetail getQuestionGroupInstance(Integer questionGroupInstanceId) { return questionnaireService.getQuestionGroupInstance(questionGroupInstanceId); } @Override public Integer createQuestionGroup(QuestionGroupDto questionGroupDto) throws SystemException { questionGroupDto.setActivityId(addActivityPermission(questionGroupDto.getTitle(), null)); return questionnaireService.defineQuestionGroup(questionGroupDto); } @Override public List<String> getAllCountriesForPPI() { return questionnaireService.getAllCountriesForPPI(); } @Override public void uploadPPIQuestionGroup(String country) { questionnaireService.uploadPPIQuestionGroup(country); } @Override public Integer saveQuestionGroupInstance(QuestionGroupInstanceDto questionGroupInstanceDto) { return questionnaireService.saveQuestionGroupInstance(questionGroupInstanceDto); } @Override public Integer getSectionQuestionId(String sectionName, Integer questionId, Integer questionGroupId) { return questionnaireService.getSectionQuestionId(sectionName, questionId, questionGroupId); } @Override public Integer createQuestion(QuestionDto questionDto) { return questionnaireService.defineQuestion(questionDto); } @Override public void applyToAllLoanProducts(Integer entityId) { if (qgFlowsService != null) { qgFlowsService.applyToAllLoanProducts(entityId); } } private EventSourceDto getEventSource(String event, String source) { return new EventSourceDto(event, source, String.format("%s.%s", event, source)); } private boolean checkAccessToQuestionGroup(Integer questionGroupId) { QuestionGroup questionGroup = this.questionnaireService.getQuestionGroupById(questionGroupId); boolean result = false; if (questionGroup != null) { Short activityID = questionGroup.getActivityId(); try { result = this.rolesPermissionService.hasUserAccessForActivity(activityID); } catch (Exception ex) { result = false; } } return result; } @SuppressWarnings({"PMD.AvoidUsingShortType", "PMD.AvoidUsingShortType"}) private Short addActivityPermission(String title, Integer id) { short parentActivity = SecurityConstants.QUESTION_MANAGMENT; Short oldActivityId; int newActivityId; try { oldActivityId = this.questionnaireService.getQuestionGroupById(id).getActivityId(); } catch (Exception e) { oldActivityId = 0; } String activityNameHead = "Can edit "; try { if(null != oldActivityId && !oldActivityId.equals((short)0)) { newActivityId = oldActivityId; this.rolesPermissionService.updateLookUpValue(newActivityId, activityNameHead, title); } else { newActivityId = this.rolesPermissionService.calculateDynamicActivityId(); this.rolesPermissionService.createActivityForQuestionGroup(parentActivity, activityNameHead + title); } } catch (Exception e) { throw new MifosRuntimeException(e); } return new Short((short)newActivityId); } @Override public Map<String, Map<Integer, Boolean>> getHiddenVisibleQuestionsAndSections( Integer questionId, String response) throws ParseException { return questionnaireService.getHiddenVisibleQuestionsAndSections(questionId, response); } @Override public Map<String, String> getAllLinkTypes() { Map<String, String> values = new HashMap<String, String>(); List<LookUpValueEntity> conditionTypes = null; conditionTypes=questionnaireService.getAllConditions(); for(LookUpValueEntity conditionType : conditionTypes){ if(conditionType.getLookUpName().equals("QuestionGroupLink.equals")) values.put(conditionType.getLookUpId().toString(), "Equals"); if(conditionType.getLookUpName().equals("QuestionGroupLink.notEquals")) values.put(conditionType.getLookUpId().toString(), "Not equals"); if(conditionType.getLookUpName().equals("QuestionGroupLink.greater")) values.put(conditionType.getLookUpId().toString(), "Greater"); if(conditionType.getLookUpName().equals("QuestionGroupLink.smaller")) values.put(conditionType.getLookUpId().toString(), "Smaller"); if(conditionType.getLookUpName().equals("QuestionGroupLink.range")) values.put(conditionType.getLookUpId().toString(), "Range"); if(conditionType.getLookUpName().equals("QuestionGroupLink.dateRange")) values.put(conditionType.getLookUpId().toString(), "Date range"); if(conditionType.getLookUpName().equals("QuestionGroupLink.before")) values.put(conditionType.getLookUpId().toString(), "Before"); if(conditionType.getLookUpName().equals("QuestionGroupLink.after")) values.put(conditionType.getLookUpId().toString(), "After"); } return values; } @Override public void createQuestionLinks(List<QuestionLinkDetail> questionLinks) { questionnaireService.createQuestionLinks(questionLinks); return; } @Override public void createSectionLinks(List<SectionLinkDetail> sectionLinks) { questionnaireService.createSectionLinks(sectionLinks); } @Override public Map<String, List<String>> getHiddenQuestionsAndSections(String questionsId, String sectionsId) { return questionnaireService.getHiddenQuestionsAndSections(questionsId, sectionsId); } }