/* * Copyright (C) 2012-2015 Stichting Akvo (Akvo Foundation) * * This file is part of Akvo FLOW. * * Akvo FLOW is free software: you can redistribute it and modify it under the terms of * the GNU Affero General Public License (AGPL) as published by the Free Software Foundation, * either version 3 of the License or any later version. * * Akvo FLOW is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License included below for more details. * * The full license text can also be seen at <http://www.gnu.org/licenses/agpl.html>. */ package org.waterforpeople.mapping.app.web.rest; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Logger; import javax.inject.Inject; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.waterforpeople.mapping.app.gwt.client.surveyinstance.SurveyInstanceDto; import org.waterforpeople.mapping.app.util.DtoMarshaller; import org.waterforpeople.mapping.app.web.rest.dto.RestStatusDto; import org.waterforpeople.mapping.app.web.rest.dto.SurveyInstancePayload; import org.waterforpeople.mapping.dao.SurveyInstanceDAO; import org.waterforpeople.mapping.domain.SurveyInstance; import com.gallatinsystems.survey.dao.SurveyDAO; import com.gallatinsystems.survey.dao.SurveyGroupDAO; import com.gallatinsystems.survey.dao.SurveyUtils; import com.gallatinsystems.survey.domain.Survey; import com.gallatinsystems.survey.domain.SurveyGroup; import com.gallatinsystems.surveyal.dao.SurveyedLocaleDao; import com.gallatinsystems.surveyal.domain.SurveyedLocale; @Controller @RequestMapping("/survey_instances") public class SurveyInstanceRestService { private static final Logger log = Logger.getLogger(SurveyInstanceRestService.class.getName()); @Inject private SurveyInstanceDAO surveyInstanceDao; @Inject private SurveyDAO surveyDao; @Inject private SurveyGroupDAO surveyGroupDao; @Inject private SurveyedLocaleDao surveyedLocaleDao; // list survey instances @RequestMapping(method = RequestMethod.GET, value = "") @ResponseBody public Map<String, Object> listSurveyInstances( @RequestParam(value = "beginDate", defaultValue = "") Long bDate, @RequestParam(value = "endDate", defaultValue = "") Long eDate, @RequestParam(value = "surveyId", required = false) Long surveyId, @RequestParam(value = "since", defaultValue = "") String since, @RequestParam(value = "unapprovedOnlyFlag", defaultValue = "") Boolean unapprovedOnlyFlag, @RequestParam(value = "surveyInstanceId", defaultValue = "") Long surveyInstanceId, @RequestParam(value = "deviceId", defaultValue = "") String deviceId, @RequestParam(value = "submitterName", defaultValue = "") String submitterName, @RequestParam(value = "countryCode", defaultValue = "") String countryCode, @RequestParam(value = "level1", defaultValue = "") String level1, @RequestParam(value = "level2", defaultValue = "") String level2, @RequestParam(value = "surveyedLocaleId", defaultValue = "") Long surveyedLocaleId) { // we don't want to search for empty fields if ("".equals(deviceId)) { deviceId = null; } if ("".equals(submitterName)) { submitterName = null; } if ("".equals(countryCode)) { countryCode = null; } if ("".equals(level1)) { level1 = null; } if ("".equals(level2)) { level2 = null; } final Map<String, Object> response = new HashMap<String, Object>(); RestStatusDto statusDto = new RestStatusDto(); // for dashboard requests we immediately return empty list of no surveyId is provided if (surveyId == null && surveyedLocaleId == null) { response.put("survey_instances", Collections.emptyList()); return response; } // If surveyInstanceId is set return the survey instance if (surveyInstanceId != null) { SurveyInstance surveyInstance = surveyInstanceDao.getByKey(surveyInstanceId); List<SurveyInstanceDto> dtoList = new ArrayList<>(); if (surveyInstance != null && surveyInstance.getSurveyId().equals(surveyId)) { SurveyInstanceDto dto = new SurveyInstanceDto(); DtoMarshaller.copyToDto(surveyInstance, dto); dtoList.add(dto); } response.put("survey_instances", dtoList); return response; } // turn params into dates Date beginDate = null; Date endDate = null; if (bDate != null) { beginDate = new Date(bDate); } if (eDate != null) { endDate = new Date(eDate); } // if no begin and end date, choose begin date 1-1-1970 if (beginDate == null && endDate == null) { // Calendar c = Calendar.getInstance(); // c.add(Calendar.YEAR, -90); beginDate = new Date(0); // c.getTime(); } // get survey Instances List<SurveyInstance> siList = null; if (surveyId != null) { // authorized surveys list List<Survey> authorizedSurveys = surveyDao.listAllFilteredByUserAuthorization(); Set<Long> authorizedSurveyIds = new HashSet<Long>(); for (Survey s : authorizedSurveys) { authorizedSurveyIds.add(s.getKey().getId()); } if (!authorizedSurveyIds.contains(surveyId)) { response.put("survey_instances", Collections.emptyList()); return response; } siList = surveyInstanceDao.listByDateRangeAndSubmitter(beginDate, endDate, false, surveyId, deviceId, submitterName, countryCode, level1, level2, since); } else if (surveyedLocaleId != null) { SurveyedLocale sl = surveyedLocaleDao.getByKey(surveyedLocaleId); if (sl.getSurveyGroupId() == null) { log.warning("No surveyGroupId found for surveyedLocale=" + sl.getKey()); response.put("survey_instances", Collections.emptyList()); return response; } // authorized survey groups list List<SurveyGroup> authorizedSurveyGroups = surveyGroupDao .listAllFilteredByUserAuthorization(); Set<Long> authorizedSurveyGroupIds = new HashSet<Long>(); for (SurveyGroup sg : authorizedSurveyGroups) { authorizedSurveyGroupIds.add(sg.getKey().getId()); } if (authorizedSurveyGroupIds.contains(sl.getSurveyGroupId())) { siList = surveyInstanceDao .listInstancesByLocale(surveyedLocaleId, null, null, null); } else { siList = Collections.emptyList(); } } Integer num = siList.size(); String newSince = SurveyInstanceDAO.getCursor(siList); String surveyCode = null; if (siList.size() > 0) { Survey selectedSurvey = surveyDao.getByKey(siList.get(0).getSurveyId()); surveyCode = selectedSurvey.getPath(); } else { surveyCode = ""; } // put in survey group/survey names ArrayList<SurveyInstanceDto> siDtoList = new ArrayList<SurveyInstanceDto>(); for (SurveyInstance siItem : siList) { SurveyInstanceDto dto = new SurveyInstanceDto(); DtoMarshaller.copyToDto(siItem, dto); dto.setSurveyCode(surveyCode); siDtoList.add(dto); } statusDto.setSince(newSince); statusDto.setNum(num); response.put("meta", statusDto); response.put("survey_instances", siDtoList); return response; } // find survey instance by id @RequestMapping(method = RequestMethod.GET, value = "/{id}") @ResponseBody public Map<String, SurveyInstanceDto> findSurveyInstanceById( @PathVariable("id") Long id) { final Map<String, SurveyInstanceDto> response = new HashMap<String, SurveyInstanceDto>(); SurveyInstance s = surveyInstanceDao.getByKey(id); SurveyInstanceDto dto = null; if (s != null) { dto = new SurveyInstanceDto(); DtoMarshaller.copyToDto(s, dto); } response.put("survey_instance", dto); return response; } // delete survey instance by id // TODO update counts @RequestMapping(method = RequestMethod.DELETE, value = "/{id}") @ResponseBody public Map<String, RestStatusDto> deleteSurveyInstanceById( @PathVariable("id") Long id) { final Map<String, RestStatusDto> response = new HashMap<String, RestStatusDto>(); RestStatusDto statusDto = new RestStatusDto(); statusDto.setStatus("failed"); response.put("meta", statusDto); // check if surveyInstance exists in the datastore SurveyInstance si = surveyInstanceDao.getByKey(id); if (si == null) { return response; } Long surveyId = si.getSurveyId(); surveyInstanceDao.deleteSurveyInstance(si); statusDto.setStatus("ok"); List<Long> ids = new ArrayList<Long>(); ids.add(surveyId); SurveyUtils.notifyReportService(ids, "invalidate"); return response; } // Update survey instance // TODO: question - when is this used? @RequestMapping(method = RequestMethod.PUT, value = "/{id}") @ResponseBody public Map<String, Object> saveExistingSurveyInstance( @RequestBody SurveyInstancePayload payLoad) { final SurveyInstanceDto surveyInstanceDto = payLoad.getSurvey_instance(); final Map<String, Object> response = new HashMap<String, Object>(); SurveyInstanceDto dto = null; RestStatusDto statusDto = new RestStatusDto(); statusDto.setStatus("failed"); // if the POST data contains a valid surveyInstanceDto, continue. // Otherwise, server 400 Bad Request if (surveyInstanceDto != null) { Long keyId = surveyInstanceDto.getKeyId(); SurveyInstance s; // if the surveyInstanceDto has a key, try to get the surveyInstance. if (keyId != null) { s = surveyInstanceDao.getByKey(keyId); // if we find the surveyInstance, update it's properties if (s != null) { // copy the properties, except the properties that are set // or provided by the Dao. BeanUtils.copyProperties(surveyInstanceDto, s, new String[] { "createdDateTime", "lastUpdateDateTime", "displayName", "questionInstanceList" }); s = surveyInstanceDao.save(s); dto = new SurveyInstanceDto(); DtoMarshaller.copyToDto(s, dto); statusDto.setStatus("ok"); } } } response.put("meta", statusDto); response.put("survey_instance", dto); return response; } // Create new survey instance @RequestMapping(method = RequestMethod.POST) @ResponseBody public Map<String, Object> saveNewSurveyInstance( @RequestBody SurveyInstancePayload payLoad) { final SurveyInstanceDto surveyInstanceDto = payLoad.getSurvey_instance(); final Map<String, Object> response = new HashMap<String, Object>(); SurveyInstanceDto dto = null; RestStatusDto statusDto = new RestStatusDto(); statusDto.setStatus("failed"); // if the POST data contains a valid surveyInstanceDto, continue. // Otherwise, server 400 Bad Request if (surveyInstanceDto != null) { SurveyInstance s = new SurveyInstance(); // copy the properties, except the properties that are set or // provided by the Dao. BeanUtils.copyProperties(surveyInstanceDto, s, new String[] { "createdDateTime", "lastUpdateDateTime", "displayName", "questionInstanceList" }); s = surveyInstanceDao.save(s); dto = new SurveyInstanceDto(); DtoMarshaller.copyToDto(s, dto); statusDto.setStatus("ok"); } response.put("meta", statusDto); response.put("survey_instance", dto); return response; } }