Skip to content
Snippets Groups Projects
Commit 4d5b7b8d authored by Tor-Einar Skog's avatar Tor-Einar Skog
Browse files

Support for crop organism filtering for forecasts

parent 6a5f9d39
No related branches found
No related tags found
No related merge requests found
Showing
with 81 additions and 11 deletions
...@@ -35,9 +35,11 @@ import no.bioforsk.vips.logic.controller.session.ForecastBean; ...@@ -35,9 +35,11 @@ import no.bioforsk.vips.logic.controller.session.ForecastBean;
import no.bioforsk.vips.logic.controller.session.UserBean; import no.bioforsk.vips.logic.controller.session.UserBean;
import no.bioforsk.vips.logic.entity.ForecastConfiguration; import no.bioforsk.vips.logic.entity.ForecastConfiguration;
import no.bioforsk.vips.logic.entity.ModelInformation; import no.bioforsk.vips.logic.entity.ModelInformation;
import no.bioforsk.vips.logic.entity.Organism;
import no.bioforsk.vips.logic.entity.Organization; import no.bioforsk.vips.logic.entity.Organization;
import no.bioforsk.vips.logic.entity.VipsLogicRole; import no.bioforsk.vips.logic.entity.VipsLogicRole;
import no.bioforsk.vips.logic.entity.VipsLogicUser; import no.bioforsk.vips.logic.entity.VipsLogicUser;
import no.bioforsk.vips.logic.i18n.SessionLocaleUtil;
import no.bioforsk.vips.logic.util.SessionControllerGetter; import no.bioforsk.vips.logic.util.SessionControllerGetter;
import no.bioforsk.vips.util.ArrayUtil; import no.bioforsk.vips.util.ArrayUtil;
import no.bioforsk.vips.util.ServletUtil; import no.bioforsk.vips.util.ServletUtil;
...@@ -173,6 +175,10 @@ public class ForecastConfigurationController extends HttpServlet { ...@@ -173,6 +175,10 @@ public class ForecastConfigurationController extends HttpServlet {
request.setAttribute("vipsLogicUsers", em.createNamedQuery("VipsLogicUser.findByOrganizationId").setParameter("organizationId", user.getOrganizationId()).getResultList()); request.setAttribute("vipsLogicUsers", em.createNamedQuery("VipsLogicUser.findByOrganizationId").setParameter("organizationId", user.getOrganizationId()).getResultList());
} }
request.setAttribute("forecastConfiguration", forecastConfiguration); request.setAttribute("forecastConfiguration", forecastConfiguration);
// All organisms used for parent organism list
request.setAttribute("allOrganisms", em.createNamedQuery("Organism.findAll").getResultList());
// Hierarchy categories
request.setAttribute("hierarchyCategories", SessionControllerGetter.getOrganismBean().getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request)));
request.setAttribute("modelInformations", em.createNamedQuery("ModelInformation.findAll").getResultList()); request.setAttribute("modelInformations", em.createNamedQuery("ModelInformation.findAll").getResultList());
request.setAttribute("messageKey", request.getParameter("messageKey")); request.setAttribute("messageKey", request.getParameter("messageKey"));
request.getRequestDispatcher("/forecastConfigurationForm.ftl").forward(request, response); request.getRequestDispatcher("/forecastConfigurationForm.ftl").forward(request, response);
......
...@@ -45,14 +45,15 @@ import no.bioforsk.vips.coremanager.service.ManagerResource; ...@@ -45,14 +45,15 @@ import no.bioforsk.vips.coremanager.service.ManagerResource;
import no.bioforsk.vips.entity.ModelConfiguration; import no.bioforsk.vips.entity.ModelConfiguration;
import no.bioforsk.vips.entity.ModelRunRequest; import no.bioforsk.vips.entity.ModelRunRequest;
import no.bioforsk.vips.entity.Result; import no.bioforsk.vips.entity.Result;
import no.bioforsk.vips.logic.entity.ForecastConfiguration;
import no.bioforsk.vips.logic.entity.ForecastModelConfiguration;
import no.bioforsk.vips.logic.entity.ForecastResult; import no.bioforsk.vips.logic.entity.ForecastResult;
import no.bioforsk.vips.logic.entity.ModelInformation; import no.bioforsk.vips.logic.entity.ModelInformation;
import no.bioforsk.vips.logic.entity.Organism;
import no.bioforsk.vips.logic.entity.Organization; import no.bioforsk.vips.logic.entity.Organization;
import no.bioforsk.vips.logic.entity.PointOfInterest; import no.bioforsk.vips.logic.entity.PointOfInterest;
import no.bioforsk.vips.logic.entity.PointOfInterestWeatherStation; import no.bioforsk.vips.logic.entity.PointOfInterestWeatherStation;
import no.bioforsk.vips.logic.entity.VipsLogicUser; import no.bioforsk.vips.logic.entity.VipsLogicUser;
import no.bioforsk.vips.logic.entity.ForecastConfiguration;
import no.bioforsk.vips.logic.entity.ForecastModelConfiguration;
import no.bioforsk.vips.logic.scheduling.model.ModelRunPreprocessor; import no.bioforsk.vips.logic.scheduling.model.ModelRunPreprocessor;
import no.bioforsk.vips.logic.scheduling.model.ModelRunPreprocessorFactory; import no.bioforsk.vips.logic.scheduling.model.ModelRunPreprocessorFactory;
import no.bioforsk.vips.logic.scheduling.model.PreprocessorException; import no.bioforsk.vips.logic.scheduling.model.PreprocessorException;
...@@ -60,6 +61,7 @@ import no.bioforsk.vips.logic.util.Globals; ...@@ -60,6 +61,7 @@ import no.bioforsk.vips.logic.util.Globals;
import no.bioforsk.vips.logic.util.RunModelException; import no.bioforsk.vips.logic.util.RunModelException;
import no.bioforsk.vips.logic.util.SessionControllerGetter; import no.bioforsk.vips.logic.util.SessionControllerGetter;
import no.bioforsk.web.forms.FormField; import no.bioforsk.web.forms.FormField;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonNode;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget; import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
...@@ -124,6 +126,15 @@ public class ForecastBean { ...@@ -124,6 +126,15 @@ public class ForecastBean {
return q.getResultList(); return q.getResultList();
} }
public List<ForecastConfiguration> getForecastConfigurationsForUserAndCrops(Integer userId, List<Integer> cropOrganismIds)
{
VipsLogicUser user = em.find(VipsLogicUser.class, userId);
Query q = em.createNamedQuery("ForecastConfiguration.findByVipsLogicUserIdAndCropOrganismId");
q.setParameter("vipsLogicUserId", user);
q.setParameter("cropOrganismIds", cropOrganismIds);
return q.getResultList();
}
/** /**
* Returns _ALL_ forecasts. Not for the faint hearted * Returns _ALL_ forecasts. Not for the faint hearted
* @return * @return
...@@ -265,6 +276,7 @@ public class ForecastBean { ...@@ -265,6 +276,7 @@ public class ForecastBean {
public ForecastConfiguration storeForecastConfiguration(ForecastConfiguration forecastConfiguration, Map<String, FormField> formFields, Map<String, FormField> modelSpecificFormFields) public ForecastConfiguration storeForecastConfiguration(ForecastConfiguration forecastConfiguration, Map<String, FormField> formFields, Map<String, FormField> modelSpecificFormFields)
{ {
forecastConfiguration.setModelId(formFields.get("modelId").getWebValue()); forecastConfiguration.setModelId(formFields.get("modelId").getWebValue());
forecastConfiguration.setCropOrganismId(em.find(Organism.class, formFields.get("cropOrganismId").getValueAsInteger()));
PointOfInterest locationPoi = em.find(PointOfInterest.class, formFields.get("locationPointOfInterestId").getValueAsInteger()); PointOfInterest locationPoi = em.find(PointOfInterest.class, formFields.get("locationPointOfInterestId").getValueAsInteger());
forecastConfiguration.setLocationPointOfInterestId(locationPoi); forecastConfiguration.setLocationPointOfInterestId(locationPoi);
PointOfInterest weatherStationPoi = em.find(PointOfInterestWeatherStation.class, formFields.get("weatherStationPointOfInterestId").getValueAsInteger()); PointOfInterest weatherStationPoi = em.find(PointOfInterestWeatherStation.class, formFields.get("weatherStationPointOfInterestId").getValueAsInteger());
...@@ -396,7 +408,7 @@ public class ForecastBean { ...@@ -396,7 +408,7 @@ public class ForecastBean {
return resource; return resource;
} }
public Kml getForecastsAggregateKml(Integer organizationId, Date theDate, String serverName) public Kml getForecastsAggregateKml(Integer organizationId, List<Integer> cropOrganismIds, Date theDate, String serverName)
{ {
String iconPath = "http://" + serverName + "/public/images/"; String iconPath = "http://" + serverName + "/public/images/";
// Initialization // Initialization
...@@ -440,7 +452,7 @@ public class ForecastBean { ...@@ -440,7 +452,7 @@ public class ForecastBean {
.withHref(iconPath + "dot_red.png"); .withHref(iconPath + "dot_red.png");
// Run through forecast configurations // Run through forecast configurations
List<PointOfInterest> poisWithAggregate = getPointOfInterestForecastsAggregate(organizationId, theDate); List<PointOfInterest> poisWithAggregate = getPointOfInterestForecastsAggregate(organizationId, cropOrganismIds, theDate);
for(PointOfInterest poiWithAggregate:poisWithAggregate) for(PointOfInterest poiWithAggregate:poisWithAggregate)
{ {
final Placemark placemark = document.createAndAddPlacemark() final Placemark placemark = document.createAndAddPlacemark()
...@@ -470,7 +482,7 @@ public class ForecastBean { ...@@ -470,7 +482,7 @@ public class ForecastBean {
* @param theDate * @param theDate
* @return * @return
*/ */
private List<PointOfInterest> getPointOfInterestForecastsAggregate(Integer organizationId, Date theDate) { private List<PointOfInterest> getPointOfInterestForecastsAggregate(Integer organizationId, List<Integer> cropOrganismIds, Date theDate) {
// TODO: More precise gathering of POIs... // TODO: More precise gathering of POIs...
List<PointOfInterest> pois = null; List<PointOfInterest> pois = null;
if(organizationId != null && organizationId > 0) if(organizationId != null && organizationId > 0)
...@@ -491,6 +503,7 @@ public class ForecastBean { ...@@ -491,6 +503,7 @@ public class ForecastBean {
" SELECT forecast_configuration_id \n" + " SELECT forecast_configuration_id \n" +
" FROM forecast_configuration \n" + " FROM forecast_configuration \n" +
" WHERE location_point_of_interest_id=:locationPointOfInterestId \n" + " WHERE location_point_of_interest_id=:locationPointOfInterestId \n" +
(cropOrganismIds != null && ! cropOrganismIds.isEmpty() ? " AND crop_organism_id IN (" + StringUtils.join(cropOrganismIds, ",") + ") " : "") +
")\n" + ")\n" +
"AND to_char(result_valid_time, 'yyyy-MM-dd') = :dateStr"); "AND to_char(result_valid_time, 'yyyy-MM-dd') = :dateStr");
q.setParameter("locationPointOfInterestId", poi.getPointOfInterestId()); q.setParameter("locationPointOfInterestId", poi.getPointOfInterestId());
......
...@@ -58,6 +58,7 @@ import org.codehaus.jackson.annotate.JsonIgnore; ...@@ -58,6 +58,7 @@ import org.codehaus.jackson.annotate.JsonIgnore;
@NamedQuery(name = "ForecastConfiguration.findByDateEnd", query = "SELECT f FROM ForecastConfiguration f WHERE f.dateEnd = :dateEnd"), @NamedQuery(name = "ForecastConfiguration.findByDateEnd", query = "SELECT f FROM ForecastConfiguration f WHERE f.dateEnd = :dateEnd"),
@NamedQuery(name = "ForecastConfiguration.findByLocationPointOfInterestId", query = "SELECT f FROM ForecastConfiguration f WHERE f.locationPointOfInterestId = :locationPointOfInterestId"), @NamedQuery(name = "ForecastConfiguration.findByLocationPointOfInterestId", query = "SELECT f FROM ForecastConfiguration f WHERE f.locationPointOfInterestId = :locationPointOfInterestId"),
@NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserId", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId"), @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserId", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId"),
@NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdAndCropOrganismId", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId AND f.cropOrganismId.organismId IN (:cropOrganismIds)"),
@NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds)"), @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds)"),
@NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdsAndModelIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.modelId IN (:modelIds)") @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdsAndModelIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.modelId IN (:modelIds)")
}) })
...@@ -89,6 +90,9 @@ public class ForecastConfiguration implements Serializable, Comparable { ...@@ -89,6 +90,9 @@ public class ForecastConfiguration implements Serializable, Comparable {
@JoinColumn(name = "weather_station_point_of_interest_id", referencedColumnName = "point_of_interest_id") @JoinColumn(name = "weather_station_point_of_interest_id", referencedColumnName = "point_of_interest_id")
@ManyToOne @ManyToOne
private PointOfInterest weatherStationPointOfInterestId; private PointOfInterest weatherStationPointOfInterestId;
@JoinColumn(name = "crop_organism_id", referencedColumnName = "organism_id")
@ManyToOne
private Organism cropOrganismId;
public ForecastConfiguration() { public ForecastConfiguration() {
} }
...@@ -232,4 +236,18 @@ public class ForecastConfiguration implements Serializable, Comparable { ...@@ -232,4 +236,18 @@ public class ForecastConfiguration implements Serializable, Comparable {
return this.getLocationPointOfInterestId().getName().compareTo(other.getLocationPointOfInterestId().getName()); return this.getLocationPointOfInterestId().getName().compareTo(other.getLocationPointOfInterestId().getName());
} }
} }
/**
* @return the organismiId
*/
public Organism getCropOrganismId() {
return cropOrganismId;
}
/**
* @param organismiId the organismiId to set
*/
public void setCropOrganismId(Organism cropOrganismId) {
this.cropOrganismId = cropOrganismId;
}
} }
...@@ -98,7 +98,9 @@ public class LogicService { ...@@ -98,7 +98,9 @@ public class LogicService {
@GET @GET
@Path("organizationforecastconfigurations/{organizationId}") @Path("organizationforecastconfigurations/{organizationId}")
@Produces("application/json;charset=UTF-8") @Produces("application/json;charset=UTF-8")
public Response getForecastConfigurationsForOrganization(@PathParam("organizationId") Integer organizationId) public Response getForecastConfigurationsForOrganization(
@PathParam("organizationId") Integer organizationId,
@QueryParam("cropOrganismId") List<Integer> cropOrganismIds)
{ {
// First: Get all users for organization // First: Get all users for organization
List<VipsLogicUser> organizationUsers = SessionControllerGetter.getUserBean().getUsersByOrganization(organizationId); List<VipsLogicUser> organizationUsers = SessionControllerGetter.getUserBean().getUsersByOrganization(organizationId);
...@@ -106,11 +108,14 @@ public class LogicService { ...@@ -106,11 +108,14 @@ public class LogicService {
List<ForecastConfiguration> forecasts = new ArrayList<>(); List<ForecastConfiguration> forecasts = new ArrayList<>();
for(VipsLogicUser user:organizationUsers) for(VipsLogicUser user:organizationUsers)
{ {
Integer userId = (Integer) user.getUserId(); Integer userId = user.getUserId();
List<ForecastConfiguration> result = cropOrganismIds != null && ! cropOrganismIds.isEmpty() ?
SessionControllerGetter.getForecastBean().getForecastConfigurationsForUserAndCrops(userId,cropOrganismIds)
: SessionControllerGetter.getForecastBean().getForecastConfigurationsForUser(userId);
if(forecasts == null) if(forecasts == null)
forecasts = SessionControllerGetter.getForecastBean().getForecastConfigurationsForUser(userId); forecasts = result;
else else
forecasts.addAll(SessionControllerGetter.getForecastBean().getForecastConfigurationsForUser(userId)); forecasts.addAll(result);
} }
return Response.ok().entity(forecasts).build(); return Response.ok().entity(forecasts).build();
...@@ -148,9 +153,11 @@ public class LogicService { ...@@ -148,9 +153,11 @@ public class LogicService {
@GET @GET
@Path("forecastresults/aggregate/{organizationId}") @Path("forecastresults/aggregate/{organizationId}")
@Produces("application/vnd.google-earth.kml+xml;charset=utf-8") @Produces("application/vnd.google-earth.kml+xml;charset=utf-8")
public Response getForecastResultsAggregate(@PathParam("organizationId") Integer organizationId) public Response getForecastResultsAggregate(
@PathParam("organizationId") Integer organizationId,
@QueryParam("cropOrganismId") List<Integer> cropOrganismIds)
{ {
Kml retVal = SessionControllerGetter.getForecastBean().getForecastsAggregateKml(organizationId, SystemTime.getSystemTime(), ServletUtil.getServerName(httpServletRequest)); Kml retVal = SessionControllerGetter.getForecastBean().getForecastsAggregateKml(organizationId, cropOrganismIds, SystemTime.getSystemTime(), ServletUtil.getServerName(httpServletRequest));
return Response.ok().entity(retVal).build(); return Response.ok().entity(retVal).build();
} }
......
...@@ -247,3 +247,4 @@ reset=Reset ...@@ -247,3 +247,4 @@ reset=Reset
messageDeleted=Message was deleted messageDeleted=Message was deleted
taskHistoryStatusFailedCompletely=Failed completely taskHistoryStatusFailedCompletely=Failed completely
weatherStationStored=Weather station information was stored weatherStationStored=Weather station information was stored
cropOrganismId=Crop
...@@ -247,3 +247,4 @@ reset=Reset ...@@ -247,3 +247,4 @@ reset=Reset
messageDeleted=Message was deleted messageDeleted=Message was deleted
taskHistoryStatusFailedCompletely=Failed completely taskHistoryStatusFailedCompletely=Failed completely
weatherStationStored=Weather station information was stored weatherStationStored=Weather station information was stored
cropOrganismId=Crop
...@@ -247,3 +247,4 @@ reset=Reset ...@@ -247,3 +247,4 @@ reset=Reset
messageDeleted=Message was deleted messageDeleted=Message was deleted
taskHistoryStatusFailedCompletely=Failed completely taskHistoryStatusFailedCompletely=Failed completely
weatherStationStored=Weather station information was stored weatherStationStored=Weather station information was stored
cropOrganismId=Crop
...@@ -247,3 +247,4 @@ reset=Nullstill ...@@ -247,3 +247,4 @@ reset=Nullstill
messageDeleted=Meldingen ble slettet messageDeleted=Meldingen ble slettet
taskHistoryStatusFailedCompletely=Feilet fullstendig taskHistoryStatusFailedCompletely=Feilet fullstendig
weatherStationStored=Informasjon om m\u00e5lestasjon ble lagret weatherStationStored=Informasjon om m\u00e5lestasjon ble lagret
cropOrganismId=Kultur
...@@ -247,3 +247,4 @@ reset=Reset ...@@ -247,3 +247,4 @@ reset=Reset
messageDeleted=Message was deleted messageDeleted=Message was deleted
taskHistoryStatusFailedCompletely=Failed completely taskHistoryStatusFailedCompletely=Failed completely
weatherStationStored=Weather station information was stored weatherStationStored=Weather station information was stored
cropOrganismId=Crop
...@@ -37,6 +37,13 @@ ...@@ -37,6 +37,13 @@
"nullValue": "-1", "nullValue": "-1",
"required" : true "required" : true
}, },
{
"name" : "cropOrganismId",
"dataType" : "INTEGER",
"fieldType" : "SELECT_SINGLE",
"nullValue": "-1",
"required" : true
},
{ {
"name" : "locationPointOfInterestId", "name" : "locationPointOfInterestId",
"dataType" : "INTEGER", "dataType" : "INTEGER",
......
...@@ -71,6 +71,20 @@ ...@@ -71,6 +71,20 @@
</select> </select>
<span class="help-block" id="${formId}_modelId_validation"></span> <span class="help-block" id="${formId}_modelId_validation"></span>
</div> </div>
<div class="form-group">
<label for="cropOrganismId">${i18nBundle.cropOrganismId}</label>
<select class="form-control" id="cropOrganismId" name="cropOrganismId" onblur="validateField(this);" onchange="renderModelSpecificFields();">
<option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.cropOrganismId?lower_case}</option>
<#list allOrganisms?sort_by("latinName") as organism>
<option value="${organism.organismId}"
<#if (forecastConfiguration.cropOrganismId?has_content && forecastConfiguration.cropOrganismId.organismId == organism.organismId)>
selected="selected"
</#if>
>${organism.latinName!""}/${organism.tradeName!""}/${organism.getLocalName(currentLocale.language)!""} (${hierarchyCategories.getName(organism.hierarchyCategoryId)})</option>
</#list>
</select>
<span class="help-block" id="${formId}_cropOrganismId_validation"></span>
</div>
<div class="form-group"> <div class="form-group">
<label for="locationPointOfInterestId">${i18nBundle.locationPointOfInterestId}</label> <label for="locationPointOfInterestId">${i18nBundle.locationPointOfInterestId}</label>
<select class="form-control" name="locationPointOfInterestId" onblur="validateField(this);"> <select class="form-control" name="locationPointOfInterestId" onblur="validateField(this);">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment