V1_0.java [src/java/m/wqm/nutappmgtscores] Revision: 69891c32fc5b880eed59e1555d59faf1d3520056 Date: Fri May 27 10:18:56 MDT 2016
package m.wqm.nutappmgtscores;
import csip.ModelDataService;
import csip.ServiceException;
import csip.utils.JSONUtils;
import csip.utils.Dates;
import csip.annotations.Polling;
import csip.annotations.Resource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Map;
import javax.ws.rs.Path;
import oms3.annotations.Name;
import oms3.annotations.Description;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import org.codehaus.jettison.json.JSONException;
import wqm.utils.DBResources;
import static wqm.utils.DBResources.WQM_ID;
@Name("WQM-16: Nutrient Application Management Scores (NutAppMgtScores)")
@Description("This service computes scores for adjusting the rate, timing, "
+ "and method of applying nutrients to mitigate nitrogen leaching, "
+ "and nitrogen and phosphorus runoff loss potential.")
@Path("m/nutappmgtscores/1.0")
@Polling(first = 10000, next = 2000)
@Resource(from = DBResources.class)
public class V1_0 extends ModelDataService {
//Response
private ArrayList<Result> result;
//private class variables for this service
private int AoAId = 0;
private String p_soil_test_result = "err";
private ArrayList<Crop> cropList;
private String error_msg = "";
@Override
protected void preProcess() throws Exception {
try {
AoAId = getIntParam("aoa_id", 0);
p_soil_test_result = getStringParam("p_soil_test_result", "err");
cropList = new ArrayList<>();
JSONArray cropIds = getJSONArrayParam("cropIds");
for (int i = 0; i < cropIds.length(); i++) {
JSONArray applicationList = null;
Map<String, JSONObject> mgtCropId = JSONUtils.preprocess(cropIds.getJSONArray(i));
if (JSONUtils.checkKeyExistsB(mgtCropId, "applicationList")) {
applicationList = JSONUtils.getJSONArrayParam(mgtCropId, "applicationList");
}
cropList.add(new Crop(JSONUtils.getIntParam(mgtCropId, "mgt_crop_id", 0), JSONUtils.getStringParam(mgtCropId, "crop_plant_date", "err"),
JSONUtils.getDoubleParam(mgtCropId, "crop_yield", 0), JSONUtils.getStringParam(mgtCropId, "crop_yield_units", "err"),
applicationList, p_soil_test_result));
}
} catch (ServiceException | JSONException ex) {
LOG.log(Level.SEVERE, "Error in processing the request JSON for WQM-16!", ex);
throw new ServiceException("Error in processing the request JSON.", ex);
}
ValidateInput();
}
@Override
protected void doProcess() throws Exception {
String ret_val = EXEC_OK;
int n_app_timing_score = 100;
int p_app_timing_score = 100;
int app_method_score = -1;
int n_app_rate_score = 0;
int p_app_rate_score = 0;
int this_crop_id = 0;
String query;
if (!error_msg.isEmpty()) {
ret_val = error_msg;
} else {
result = new ArrayList<>();
try (Connection conn = getResourceJDBC(WQM_ID);
Statement statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY)) {
for (Crop crop : cropList) {
String crop_type = crop.getCropType();
//////TODO: Remember to check for errors from the classes.... ///////
if (!crop_type.isEmpty()) {
//#Update N and P application management rate scores for each crop
int[] app_rate_scores = crop.getNutrientApplicationRateScores();
if (!(error_msg = crop.getErrorMsg()).isEmpty()) {
break;
}
//Cummulative sum of N and P application management scores over all crops for the AoA
n_app_rate_score += app_rate_scores[Crop.N_APP_RATE_SCORE];
p_app_rate_score += app_rate_scores[Crop.P_APP_RATE_SCORE];
//#Compute N and P application timing scores for the crop and update timing scores for the AoA
int[] app_time_scores = crop.getNutrientApplicationTimingScores();
if (!(error_msg = crop.getErrorMsg()).isEmpty()) {
break;
}
// There is a problem with the logic of the specification here...It does not take into account the actual timing of applications when
// there are mulitple crops and multiple years invovled....these final values are probably not correct. The "-1" below is placed here
// in an attempt to fix the missing database values problem that also exists with this logic at the nutrient level.
if ((app_time_scores[Crop.N_APP_TIMING_SCORE] < n_app_timing_score) || (n_app_timing_score == -1)) {
n_app_timing_score = app_time_scores[Crop.N_APP_TIMING_SCORE];
}
if ((app_time_scores[Crop.P_APP_TIMING_SCORE] < p_app_timing_score) || (p_app_timing_score == -1)) {
p_app_timing_score = app_time_scores[Crop.P_APP_TIMING_SCORE];
}
//#If any nutrient application for any crop is not incorporated, the method score for the AoA is zero
if (!crop.allNutrientsIncorporated()) {
app_method_score = 0;
}
if (!(error_msg = crop.getErrorMsg()).isEmpty()) {
break;
}
} else {
ret_val = error_msg = "Cannot get crop_type. " + crop.getErrorMsg();
}
}
// If all crops' nutrients were incorporated this value will still be -1
if (app_method_score == -1) {
query = "SELECT app_mgt_score FROM wqm.wqm_nutrient_application_mgt_scores "
+ "WHERE app_mgt_kind='Method' AND app_mgt_factor='incorporate';";
try (ResultSet resultSet = statement.executeQuery(query)) {
if (resultSet.first()) {
app_method_score = resultSet.getInt("app_mgt_score");
}
}
//#Compute application management scores for nitrogen in groundwater, nitrogen in surface water, and phosphorus in surface water
int nleach_app_mgt_score = n_app_rate_score + n_app_timing_score + app_method_score;
int nsurf_app_mgt_score = n_app_rate_score + n_app_timing_score + app_method_score;
int psurf_app_mgt_score = p_app_rate_score + p_app_timing_score + app_method_score;
result.add(new Result(AoAId, nleach_app_mgt_score, nsurf_app_mgt_score, psurf_app_mgt_score, n_app_rate_score, n_app_timing_score, p_app_rate_score, p_app_timing_score, app_method_score));
}
} catch (ServiceException | SQLException ex) {
LOG.log(Level.SEVERE, "SQL problem for WQM-16!", ex);
throw new ServiceException("SQL problem", ex);
} catch (Exception ex) {
LOG.log(Level.SEVERE, "Error in processing for WQM-16!", ex);
throw new ServiceException("Exception", ex);
}
}
}
@Override
//writing the results back to JSON
protected void postProcess() throws Exception {
try {
for (Result rs1 : result) {
JSONArray tmpArr = new JSONArray();
tmpArr.put(JSONUtils.dataDesc("AoAId", rs1.getAoAId(), "Area of Analysis Identifier"));
tmpArr.put(JSONUtils.dataDesc("nleach_app_mgt_score", rs1.getNleachAppMgtScore(), "Nitrogen Application Management Score for Mitigating Leaching Loss Potential"));
tmpArr.put(JSONUtils.dataDesc("nsurf_app_mgt_score", rs1.getNsurfAppMgtScore(), "Nitrogen Application Management Score for Mitigating Surface Runoff Loss Potential"));
tmpArr.put(JSONUtils.dataDesc("psurf_app_mgt_score", rs1.getPsurfAppMgtScore(), "Phosphorus Application Management Score for Mitigating Surface Runoff Loss Potential"));
tmpArr.put(JSONUtils.dataDesc("n_app_rate_score", rs1.getnAppRateScore(), "Nitrogen Application Rate Mitigation Score"));
tmpArr.put(JSONUtils.dataDesc("n_app_timing_score", rs1.getnAppTimingScore(), "Nitrogen Application Timing Mitigation Score"));
tmpArr.put(JSONUtils.dataDesc("p_app_rate_score", rs1.getpAppRateScore(), "Phosphorus Application Rate Mitigation Score"));
tmpArr.put(JSONUtils.dataDesc("p_app_timing_score", rs1.getpAppTimingScore(), "Phosphorus Application Timing Mitigation Score"));
tmpArr.put(JSONUtils.dataDesc("app_method_score", rs1.getAppMethodScore(), "Nutrient Application Method Mitigation Score"));
putResult("Nutrition Application Summary", tmpArr, "Nutrition Application Summary");
}
} catch (JSONException ex) {
LOG.log(Level.SEVERE, "Error in processing the response JSON for WQM-16!", ex);
throw new ServiceException("Error in processing the response JSON.", ex);
}
}
private boolean ValidateInput() {
for (Crop tCrop : cropList) {
if (!tCrop.validate()) {
error_msg += "; " + tCrop.getErrorMsg();
}
}
return (error_msg.isEmpty());
}
public class Crop {
// Begin Crop Class
public static final int N_APP_RATE_SCORE = 0;
public static final int P_APP_RATE_SCORE = 1;
public static final int N_APP_TIMING_SCORE = 0;
public static final int P_APP_TIMING_SCORE = 1;
private int mgtCropId;
private String cropPlantDate;
private Date plantDate;
private double cropYield;
private String cropYieldUnits;
private ArrayList<Crop.NutrientApplication> nutrientApplicationList;
private Result calc_result;
private String cropType = "";
private String error_msg = "";
private Boolean multipleNutrientApplication = false;
private int n_app_timing_score = 100;
private int p_app_timing_score = 100;
private int app_method_score = 0;
private int[] appRateScore = new int[2];
private int[] appNutrientTimingScore = new int[2];
private String pSoilTestResult = "None";
public Crop(int mgtCropId, String cropPlantDate, double cropYield,
String cropYieldUnits, JSONArray applicationList, String pSoilTestResult) throws ServiceException {
this.mgtCropId = mgtCropId;
this.cropPlantDate = cropPlantDate;
this.cropYield = cropYield;
this.cropYieldUnits = cropYieldUnits;
this.pSoilTestResult = pSoilTestResult;
nutrientApplicationList = new ArrayList<Crop.NutrientApplication>();
try {
plantDate = getCropPlantDate();
if (null != applicationList) {
for (int j = 0; j < applicationList.length(); j++) {
Map<String, JSONObject> application = JSONUtils.preprocess(applicationList.getJSONArray(j));
nutrientApplicationList.add(new Crop.NutrientApplication(JSONUtils.getStringParam(application, "nutrient_application_date", "err"), JSONUtils.getStringParam(application, "incorporated", ""), JSONUtils.getJSONArrayParam(application, "application")));
}
}
} catch (Exception ex) {
LOG.log(Level.SEVERE, "Error in processing for WQM-16!", ex);
throw new ServiceException("Exception", ex);
}
multipleNutrientApplication = (nutrientApplicationList.size() > 1);
appRateScore[N_APP_RATE_SCORE] = appRateScore[P_APP_RATE_SCORE] = -1;
appNutrientTimingScore[N_APP_TIMING_SCORE] = appNutrientTimingScore[P_APP_TIMING_SCORE] = -1;
}
//Get methods
public int getMgtCropId() {
return mgtCropId;
}
public String getErrorMsg() {
for (Crop.NutrientApplication nutrientApplied : nutrientApplicationList) {
error_msg += nutrientApplied.getErrorMsg();
}
return error_msg;
}
public String getCropType() throws ServiceException {
if ((cropType.isEmpty()) && (error_msg.isEmpty())) {
String query = "SELECT wqm_crop_type FROM wqm.wqm_crops WHERE wqm_crop_id="
+ mgtCropId + " AND wqm_crop_units='" + cropYieldUnits + "';";
try (Connection conn = getResourceJDBC(WQM_ID);
Statement statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
try (ResultSet resultSet = statement.executeQuery(query)) {
if (!resultSet.first()) {
error_msg += "That crop, " + mgtCropId + ", and crop yield units, " + cropYieldUnits + ", was not found in the database";
} else {
cropType = resultSet.getString("wqm_crop_type");
}
}
} catch (ServiceException | SQLException ex) {
LOG.log(Level.SEVERE, "SQL problem for WQM-16!", ex);
throw new ServiceException("SQL problem", ex);
}
}
return cropType;
}
public final Date getCropPlantDate() throws Exception {
String[] parse = cropPlantDate.split("-");
Calendar date = new GregorianCalendar(Integer.parseInt(parse[0]),
Integer.parseInt(parse[1]) - 1, Integer.parseInt(parse[2]));
return date.getTime();
}
public double getCropYield() {
return cropYield;
}
public String getCropYieldUnits() {
return cropYieldUnits;
}
public ArrayList getNutrientApplicationList() {
return nutrientApplicationList;
}
public int[] getNutrientApplicationRateScores() throws ServiceException {
if ((appRateScore[N_APP_RATE_SCORE] < 0) || (appRateScore[P_APP_RATE_SCORE] < 0)) {
try (Connection conn = getResourceJDBC(WQM_ID);
Statement statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
if (nutrientApplicationList.isEmpty()) {
ResultSet resultSet;
appRateScore[N_APP_RATE_SCORE] = appRateScore[P_APP_RATE_SCORE] = 0;
String queryNitrogen = "SELECT app_mgt_score "
+ "FROM wqm.wqm_nutrient_application_mgt_scores "
+ "WHERE nutrient='Nitrogen' AND app_mgt_kind='Rate' AND app_mgt_factor='none';";
String queryPhosporous = "SELECT app_mgt_score "
+ "FROM wqm.wqm_nutrient_application_mgt_scores "
+ "WHERE nutrient='Phosphorus' AND app_mgt_kind='Rate' "
+ "AND app_mgt_factor='none' AND soil_test_result='" + pSoilTestResult + "';";
resultSet = statement.executeQuery(queryNitrogen);
if (resultSet.first()) {
appRateScore[N_APP_RATE_SCORE] = resultSet.getInt("app_mgt_score");
}
resultSet = statement.executeQuery(queryPhosporous);
if (resultSet.first()) {
appRateScore[P_APP_RATE_SCORE] = resultSet.getInt("app_mgt_score");
}
} else {
ResultSet resultSet;
String query;
double nrate = 0.0;
double prate = 0.0;
double wqm_crop_pct_dmat = 0.0;
double wqm_pct_nitrogen = 0.0;
double wqm_pct_phosphorus = 0.0;
double wqm_crop_yield = 0.0;
int ncrop_app_rate_score = 0;
int pcrop_app_rate_score = 0;
for (Crop.NutrientApplication nutrient : nutrientApplicationList) {
ArrayList<Crop.NutrientApplication.Nutrient> nutrientAppliedList = nutrient.getNutrientList();
for (Crop.NutrientApplication.Nutrient nApplied : nutrientAppliedList) {
switch (nApplied.getNutrientApplied()) { //Note: This switch requires JDK 1.7 or above
case "Nitrogen":
nrate += nApplied.getApplicationRate();
break;
case "Phosphorus":
prate += nApplied.getApplicationRate();
break;
}
}
}
query = "SELECT wqm_crop_pct_dmat, wqm_pct_nitrogen, wqm_pct_phosphorus, wqm_crop_yield "
+ "FROM wqm.wqm_crops WHERE wqm_crop_id=" + mgtCropId + ";";
resultSet = statement.executeQuery(query);
if (resultSet.first()) {
wqm_crop_pct_dmat = resultSet.getDouble("wqm_crop_pct_dmat");
wqm_pct_nitrogen = resultSet.getDouble("wqm_pct_nitrogen");
wqm_pct_phosphorus = resultSet.getDouble("wqm_pct_phosphorus");
wqm_crop_yield = resultSet.getDouble("wqm_crop_yield");
// Added wqm_crop_yield to the calc per bug #462839
double n_growout = cropYield * wqm_crop_yield * wqm_crop_pct_dmat * wqm_pct_nitrogen;
double p_growout = cropYield * wqm_crop_yield * wqm_crop_pct_dmat * wqm_pct_phosphorus;
double n_remove_ratio = nrate / n_growout;
double p_remove_ratio = prate / p_growout;
query = "SELECT app_mgt_score FROM wqm.wqm_nutrient_application_mgt_scores "
+ "WHERE nutrient = 'Nitrogen' AND app_mgt_kind = 'Rate' AND app_mgt_factor=";
switch (cropType) {
case "Small Grain": //Note the case conflicts here...
query += "'small grain'";
break;
default:
query += "'other'";
}
query += " AND remove_ratio_1 <= " + n_remove_ratio + "AND remove_ratio_2 > " + n_remove_ratio + ";";
resultSet = statement.executeQuery(query);
if (resultSet.first()) {
ncrop_app_rate_score = resultSet.getInt("app_mgt_score");
} else {
appRateScore[N_APP_RATE_SCORE] = appRateScore[P_APP_RATE_SCORE] = 0;
}
pcrop_app_rate_score = -1;
//#Compute P application management rate scores based on removal ratio and soil test result
switch (pSoilTestResult) {
case "High":
if (p_remove_ratio >= 1.2) {
pcrop_app_rate_score = 0;
}
break;
case "Medium":
case "Low":
if (p_remove_ratio >= 1.6) {
pcrop_app_rate_score = 0;
}
break;
case "None":
if (p_remove_ratio >= 1.2) {
pcrop_app_rate_score = 0;
}
break;
}
if (pcrop_app_rate_score == -1) {
query = "SELECT app_mgt_score FROM wqm.wqm_nutrient_application_mgt_scores "
+ "WHERE nutrient='Phosphorus' AND app_mgt_kind='Rate' "
+ "AND app_mgt_factor='app' AND soil_test_result='"
+ pSoilTestResult + "' AND remove_ratio_1 <= " + p_remove_ratio
+ " AND remove_ratio_2 > " + p_remove_ratio + ";";
resultSet = statement.executeQuery(query);
if (resultSet.first()) {
pcrop_app_rate_score = resultSet.getInt("app_mgt_score");
}
}
if (pcrop_app_rate_score != -1) {
//#Update N and P application management rate scores for the AoA
appRateScore[N_APP_RATE_SCORE] = ncrop_app_rate_score;
appRateScore[P_APP_RATE_SCORE] = pcrop_app_rate_score;
} else {//We have a problem...no validity in any following computations if we proceed since the last query failed to find any data. What would you like to do?
appRateScore[N_APP_RATE_SCORE] = appRateScore[P_APP_RATE_SCORE] = 0;
}
} else { //We have a problem...no validity in any following computations if we proceed. What would you like to do?
appRateScore[N_APP_RATE_SCORE] = appRateScore[P_APP_RATE_SCORE] = 0;
}
}
} catch (ServiceException | SQLException ex) {
error_msg += ex.getMessage();
LOG.log(Level.SEVERE, "SQL problem for WQM-16!", ex);
throw new ServiceException("SQL problem", ex);
}
}
return appRateScore;
}
public int[] getNutrientApplicationTimingScores() throws ServiceException, Exception {
if ((appNutrientTimingScore[N_APP_TIMING_SCORE] < 0) || (appNutrientTimingScore[P_APP_TIMING_SCORE] < 0)) {
int tempNScore = 100;
int tempPScore = 100;
for (Crop.NutrientApplication nutrientApplication : nutrientApplicationList) {
// Call each application compare its results to the last and adjust main score if necessary.
int[] tempAppTimingScores = nutrientApplication.getNutrientTimingScores(multipleNutrientApplication);
if (tempAppTimingScores[N_APP_TIMING_SCORE] < tempNScore) {
tempNScore = tempAppTimingScores[N_APP_TIMING_SCORE];
}
if (tempAppTimingScores[P_APP_TIMING_SCORE] < tempPScore) {
tempPScore = tempAppTimingScores[P_APP_TIMING_SCORE];
}
}
appNutrientTimingScore[P_APP_TIMING_SCORE] = tempPScore;
appNutrientTimingScore[N_APP_TIMING_SCORE] = tempNScore;
}
return appNutrientTimingScore;
}
public Boolean allNutrientsIncorporated() {
Boolean ret_val = true;
for (Crop.NutrientApplication nutrientApplication : nutrientApplicationList) {
if (!nutrientApplication.allNutrientsIncorporated()) {
ret_val = false;
break;
}
}
return ret_val;
}
public String processCropData() {
String ret_val = "";
return ret_val;
}
public Boolean validate() {
for (Crop.NutrientApplication tNutrientApplication : nutrientApplicationList) {
if (!tNutrientApplication.validate()) {
error_msg += "; " + tNutrientApplication.getErrorMsg();
}
}
return (error_msg.isEmpty());
}
// Inner Classes
class NutrientApplication {
class Nutrient {
private final String nutrientApplied;
private final double applicationRate;
Nutrient(String nutrientApplied, double applicationRate) throws ServiceException {
this.nutrientApplied = nutrientApplied;
this.applicationRate = applicationRate;
if (!nutrientApplied.equals("Nitrogen") && !nutrientApplied.equals("Phosphorus")) {
throw new ServiceException("Invalid input data. Bad nutrient name");
}
}
//Get Methods
public String getNutrientApplied() {
return nutrientApplied;
}
public double getApplicationRate() {
return applicationRate;
}
public String getErrorMsg() {
return error_msg;
}
public Boolean validate() {
return (error_msg.isEmpty());
}
}
private String error_msg = "";
private String applicationDate;
private boolean incorporated;
private ArrayList<Crop.NutrientApplication.Nutrient> nutrientList;
private int appMethodScore = 0;
private int[] nutrientTimingScores = new int[2];
NutrientApplication(String applicationDate, String incorporated, JSONArray applications) throws ServiceException {
this.applicationDate = applicationDate;
nutrientTimingScores[N_APP_TIMING_SCORE] = nutrientTimingScores[P_APP_TIMING_SCORE] = -1;
if ((!"true".equalsIgnoreCase(incorporated)) && (!"false".equalsIgnoreCase(incorporated))) {
throw new ServiceException("Invalid incorporation value for nutrient application " + applicationDate);
} else {
this.incorporated = Boolean.parseBoolean(incorporated);
nutrientList = new ArrayList<>();
try {
for (int k = 0; k < applications.length(); k++) {
Map<String, JSONObject> nutrient = JSONUtils.preprocess(applications.getJSONArray(k));
nutrientList.add(new Crop.NutrientApplication.Nutrient(JSONUtils.getStringParam(nutrient, "nutrient_applied", "err"), JSONUtils.getDoubleParam(nutrient, "application_rate", 0)));
}
} catch (JSONException ex) {
LOG.log(Level.SEVERE, "Error in processing for WQM-16!", ex);
throw new ServiceException("JSONException", ex);
}
}
}
//Get Methods
public Date getApplicationDate() throws Exception {
String[] parse = applicationDate.split("-");
//Some say should set to use UTC first...do we wanna do that?
Calendar date = new GregorianCalendar(Integer.parseInt(parse[0]),
Integer.parseInt(parse[1]) - 1, Integer.parseInt(parse[2]));
return date.getTime();
}
public boolean isIncorporated() {
return incorporated;
}
public ArrayList getNutrientList() {
return nutrientList;
}
public String getErrorMsg() {
for (Crop.NutrientApplication.Nutrient nutrient : nutrientList) {
error_msg += nutrient.getErrorMsg();
}
return error_msg;
}
public Boolean validate() {
for (Crop.NutrientApplication.Nutrient nutrient : nutrientList) {
if (!nutrient.validate()) {
error_msg += "; " + nutrient.getErrorMsg();
}
}
return (error_msg.isEmpty());
}
public int[] getNutrientTimingScores(Boolean split) throws ServiceException, Exception {
if ((nutrientTimingScores[N_APP_TIMING_SCORE] < 0) || (nutrientTimingScores[P_APP_TIMING_SCORE] < 0)) {
int tempNScore = 100;
int tempPScore = 100;
for (Crop.NutrientApplication.Nutrient nutrient : nutrientList) {
int app_timing_score;
try (Connection conn = getResourceJDBC(WQM_ID);
Statement statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
long app_day_diff = Dates.diffInMillis(getCropPlantDate(), getApplicationDate());
app_day_diff = TimeUnit.MILLISECONDS.toDays(app_day_diff);
String query = "SELECT app_mgt_score "
+ "FROM wqm.wqm_nutrient_application_mgt_scores WHERE nutrient='";
query += nutrient.getNutrientApplied() + "' ";
query += "AND app_mgt_kind='Timing' AND app_mgt_factor='" + (split ? "split" : "nosplit") + "'AND days_fr_plant_1 <= " + app_day_diff + "AND days_fr_plant_2 > " + app_day_diff + ";";
try (ResultSet resultSet = statement.executeQuery(query)) {
if (!resultSet.first()) {
app_timing_score = -1;
} else {
app_timing_score = resultSet.getInt("app_mgt_score");
}
switch (nutrient.getNutrientApplied()) {
case "Nitrogen":
if (app_timing_score < tempNScore) {
tempNScore = app_timing_score;
}
break;
case "Phosphorus":
if (app_timing_score < tempPScore) {
tempPScore = app_timing_score;
}
break;
default:
error_msg += "Invalid nutrient name specified";
}
}
} catch (ServiceException | SQLException ex) {
LOG.log(Level.SEVERE, "SQL problem for WQM-16!", ex);
throw new ServiceException("SQL problem", ex);
}
if (error_msg.isEmpty()) {
nutrientTimingScores[N_APP_TIMING_SCORE] = tempNScore;
nutrientTimingScores[P_APP_TIMING_SCORE] = tempPScore;
}
}
}
return nutrientTimingScores;
}
public Boolean allNutrientsIncorporated() {
return incorporated;
}
}
}
static class Result {
int AoAId;
int nleach_app_mgt_score;
int nsurf_app_mgt_score;
int psurf_app_mgt_score;
int n_app_rate_score;
int n_app_timing_score;
int p_app_rate_score;
int p_app_timing_score;
int app_method_score;
public Result(int AoAId, int nleach_app_mgt_score, int nsurf_app_mgt_score,
int psurf_app_mgt_score, int n_app_rate_score, int n_app_timing_score,
int p_app_rate_score, int p_app_timing_score, int app_method_score) {
this.AoAId = AoAId;
this.nleach_app_mgt_score = nleach_app_mgt_score;
this.nsurf_app_mgt_score = nsurf_app_mgt_score;
this.psurf_app_mgt_score = psurf_app_mgt_score;
this.n_app_rate_score = n_app_rate_score;
this.n_app_timing_score = n_app_timing_score;
this.p_app_rate_score = p_app_rate_score;
this.p_app_timing_score = p_app_timing_score;
this.app_method_score = app_method_score;
}
//Getter Methods
public int getAoAId() {
return AoAId;
}
public int getNleachAppMgtScore() {
return nleach_app_mgt_score;
}
public int getNsurfAppMgtScore() {
return nsurf_app_mgt_score;
}
public int getPsurfAppMgtScore() {
return psurf_app_mgt_score;
}
public int getnAppRateScore() {
return n_app_rate_score;
}
public int getnAppTimingScore() {
return n_app_timing_score;
}
public int getpAppRateScore() {
return p_app_rate_score;
}
public int getpAppTimingScore() {
return p_app_timing_score;
}
public int getAppMethodScore() {
return app_method_score;
}
}
}