@Override
  public void onQuery(Query query) throws DeadlineExceededException {
    JSONObject parameters = query.getParameters();
    Object monthId = parameters.opt("monthid");
    Object yearId = parameters.opt("yearid");
    if (monthId == null || yearId == null) {
      throw new RuntimeException("Please Select Month Year.");
    }

    String yearName =
        EmployeeSalaryGenerationServlet.getYearName((long) Translator.integerValue(yearId));
    String fromDateString = yearName + "-" + monthId + "-1";
    Date fromDate = Translator.dateValue(fromDateString);
    Date toDate = DataTypeUtilities.getMonthLastDate(fromDate);
    String toDateString = EmployeeSalaryGenerationServlet.getDateInString(toDate);
    String filter = "date>='" + fromDateString + "' AND date<='" + toDateString + "'";
    query.addFilter(filter);

    JSONArray filters = query.getFilters();
    LogUtility.writeLog("parameters >> " + parameters + " << filters >> " + filters);
  }
  @Override
  public void onResult(Result result) throws DeadlineExceededException {
    try {
      JSONArray records = result.getRecords();
      JSONObject parameters = result.getQuery().getParameters();

      Object monthId = parameters.opt("monthid");
      Object yearId = parameters.opt("yearid");

      LogUtility.writeLog("records >> " + records);
      Map<Integer, Double> resourceRevenewDetails = new HashMap<Integer, Double>();
      Map<Integer, String[]> resourceNameMap = new HashMap<Integer, String[]>();
      List<Integer> list = new ArrayList<Integer>();
      if (records != null) {
        for (int counter = 0; counter < records.length(); counter++) {
          JSONObject engagementDetailsObject;
          engagementDetailsObject = records.getJSONObject(counter);
          int resourceId = Translator.integerValue(engagementDetailsObject.opt("resourceid"));
          String resourceName =
              Translator.stringValue(engagementDetailsObject.opt("resourceid.name"));
          String employeeCode =
              Translator.stringValue(engagementDetailsObject.opt("resourceid.employeecode"));
          double rate = Translator.doubleValue(engagementDetailsObject.opt("deliveryid.rate"));
          double billableEfforts =
              Translator.doubleValue(engagementDetailsObject.opt("billableefforts"));
          double amount = rate * billableEfforts;
          if (!resourceNameMap.containsKey(resourceId)) {
            resourceNameMap.put(resourceId, new String[] {resourceName, employeeCode});
          }
          if (resourceRevenewDetails.containsKey(resourceId)) {
            amount += resourceRevenewDetails.get(resourceId);
          }
          resourceRevenewDetails.put(resourceId, amount);
          if (!list.contains(resourceId)) {
            list.add(resourceId);
          }
        }
        String listString = list.toString();
        if (listString.length() > 0) {
          listString = listString.substring(1, listString.length() - 1);
          HashMap<Integer, Double> employeeSalaryPaidDetsils =
              getEmployeeSalaryPaidDetsils(listString, monthId, yearId);
          JSONArray array = new JSONArray();
          for (Integer resourceId : resourceNameMap.keySet()) {
            String[] employeeDetails = resourceNameMap.get(resourceId);
            double paidSalary =
                employeeSalaryPaidDetsils.get(resourceId) == null
                    ? 0.0
                    : employeeSalaryPaidDetsils.get(resourceId);
            double revenew = resourceRevenewDetails.get(resourceId);
            JSONObject details = new JSONObject();
            details.put("resourceName", employeeDetails[0]);
            details.put("resourceCode", employeeDetails[1]);
            details.put("paidSalary", new DecimalFormat("#.##").format(paidSalary));
            details.put("revenew", new DecimalFormat("#.##").format(revenew));
            if (paidSalary < revenew) {
              details.put("profit", new DecimalFormat("#.##").format(revenew - paidSalary));
            } else {
              details.put("loss", new DecimalFormat("#.##").format(paidSalary - revenew));
            }
            array.put(details);
          }
          records.put(new JSONObject().put("revenewReport", array));
        }
      }
    } catch (JSONException e) {
      String trace = ExceptionUtils.getExceptionTraceMessage(getClass().getName(), e);
      LogUtility.writeLog("RevenewLossBusinessLogic >>  Exception >> Trace >> " + trace);
      throw new BusinessLogicException("Some Unknown Error Occured Please Contact To Admin.");
    }
  }
  private void putRecordsIntoMap(
      HashMap<Integer, HashMap<Integer, Object[]>> employeeTourDetailsMap,
      JSONArray employeeTourRequestRecords,
      HashMap<Integer, HashMap<Integer, Object[]>> employeeTourRequestAndDetailsMap)
      throws JSONException {
    for (int counter = 0; counter < employeeTourRequestRecords.length(); counter++) {
      int tourId =
          Translator.integerValue(
              employeeTourRequestRecords.getJSONObject(counter).opt(Updates.KEY));
      int employeeId =
          Translator.integerValue(
              employeeTourRequestRecords.getJSONObject(counter).opt("employeeid"));
      String employeeCode =
          Translator.stringValue(
              employeeTourRequestRecords.getJSONObject(counter).opt("employeeid.employeecode"));
      String employeeName =
          Translator.stringValue(
              employeeTourRequestRecords.getJSONObject(counter).opt("employeeid.name"));

      Object departOn = employeeTourRequestRecords.getJSONObject(counter).opt("startdate");
      Object ariveOn = employeeTourRequestRecords.getJSONObject(counter).opt("enddate");

      Object advance =
          employeeTourRequestRecords.getJSONObject(counter).opt("advanceamount_amount");
      Object tourCode = employeeTourRequestRecords.getJSONObject(counter).opt("tourcode");

      Object employeeDetailsObject =
          employeeTourRequestRecords.getJSONObject(counter).opt("hris_tourdetails");

      if (departOn != null) {
        String fromDateString = "" + departOn;
        if (fromDateString.contains(" ")) {
          departOn = fromDateString.split(" ")[0];
        }
      }
      if (ariveOn != null) {
        String toDateString = "" + ariveOn;
        if (toDateString.contains(" ")) {
          ariveOn = toDateString.split(" ")[0];
        }
      }

      if (employeeId != 0) {
        Object[] details = new Object[9];
        details[0] = tourId;
        details[1] = employeeName;
        details[2] = employeeCode;
        details[3] = advance;
        details[4] = departOn;
        details[5] = ariveOn;
        details[6] = tourCode;
        HashMap<Integer, Object[]> tourRequestDetails = new HashMap<Integer, Object[]>();
        if (employeeTourRequestAndDetailsMap.containsKey(employeeId)) {
          tourRequestDetails = employeeTourRequestAndDetailsMap.get(employeeId);
        }
        tourRequestDetails.put(tourId, details);
        employeeTourRequestAndDetailsMap.put(employeeId, tourRequestDetails);

        HashMap<Integer, Object[]> tourDetails = new HashMap<Integer, Object[]>();
        JSONArray employeeRecords = new JSONArray();
        if (employeeDetailsObject != null && employeeDetailsObject instanceof JSONArray) {
          employeeRecords = (JSONArray) employeeDetailsObject;
        } else if (employeeDetailsObject != null && employeeDetailsObject instanceof JSONObject) {
          employeeRecords = new JSONArray().put(employeeDetailsObject);
        }
        if (employeeRecords != null && employeeRecords.length() > 0) {
          double totalEstimatedAmount = 0.0;
          double totalActualAmount = 0.0;
          for (int tourDetailCounter = 0;
              tourDetailCounter < employeeRecords.length();
              tourDetailCounter++) {
            Object[] nestedTourDetails = new Object[5];
            int tourDatailId =
                Translator.integerValue(
                    employeeRecords.getJSONObject(tourDetailCounter).opt(Updates.KEY));
            Object fromDate = employeeRecords.getJSONObject(tourDetailCounter).opt("fromdate");
            Object toDate = employeeRecords.getJSONObject(tourDetailCounter).opt("todate");

            double estmateAmount =
                Translator.doubleValue(
                    employeeRecords.getJSONObject(tourDetailCounter).opt("expectedamount_amount"));
            double actualAmount =
                Translator.doubleValue(
                    employeeRecords.getJSONObject(tourDetailCounter).opt("actual_amount_amount"));
            Object cityName = employeeRecords.getJSONObject(tourDetailCounter).opt("cityid.name");
            totalEstimatedAmount += estmateAmount;
            totalActualAmount += actualAmount;
            if (fromDate != null) {
              String fromDateString = "" + fromDate;
              if (fromDateString.contains(" ")) {
                fromDate = fromDateString.split(" ")[0];
              }
            }
            if (toDate != null) {
              String toDateString = "" + toDate;
              if (toDateString.contains(" ")) {
                toDate = toDateString.split(" ")[0];
              }
            }
            nestedTourDetails[0] = fromDate;
            nestedTourDetails[1] = toDate;
            nestedTourDetails[2] = estmateAmount;
            nestedTourDetails[3] = actualAmount;
            nestedTourDetails[4] = cityName;
            tourDetails.put(tourDatailId, nestedTourDetails);
          }
          details[7] = totalEstimatedAmount;
          details[8] = totalActualAmount;
        }
        employeeTourDetailsMap.put(tourId, tourDetails);
      }
    }
  }