/**
   * Used to collect user the input data to generate the report.
   *
   * @param modelMap of type ModelMap
   * @return java.lang.String
   * @throws AkuraAppException throw exception if occur.
   */
  @RequestMapping(method = RequestMethod.GET)
  public String showReportForm(ModelMap modelMap) throws AkuraAppException {

    LOG.info("Calling StudentPerformance.jsp to collect data for input pages");
    CRStudentPerformanceTemplate cRStudentPerformanceTemplate = new CRStudentPerformanceTemplate();

    // set template date to the model map
    modelMap.addAttribute(MODEL_ATT_STUDENT_PERFORMANCE_TEMPLATE, cRStudentPerformanceTemplate);
    String selectOption =
        PropertyReader.getPropertyValue(ReportUtil.REPORT_TEMPLATE, STU_PERFORMANCE_SELECT_OPTION);
    modelMap.addAttribute(SELECT_OPTION, selectOption);

    return VIEW_METHOD_REPORTING_STUDENT_PERFORMANCE;
  }
  /**
   * Perform the logic of the controller to generate Teacher Wise Attendance Report .
   *
   * @param attendeesWrapperTemplate of type AttendeesWrapperTemplate
   * @param request of type HttpServletRequest
   * @param response of type HttpServletResponse
   * @param errors of type BindingResult
   * @return java.lang.String
   * @param map of type ModelMap
   * @throws AkuraAppException AkuraAppException
   */
  @RequestMapping(value = REQ_MAP_STUDENT_LATE_REPORT, method = RequestMethod.POST)
  public String onSubmit(
      HttpServletRequest request,
      HttpServletResponse response,
      @ModelAttribute(MODEL_MAP_ATTENDEES_WRAPPER_TEMPLATE)
          AttendeesWrapperTemplate attendeesWrapperTemplate,
      BindingResult errors,
      ModelMap map)
      throws AkuraAppException {

    String returnString = STRING_EMPTY;
    lateComersValidator.validate(attendeesWrapperTemplate, errors);

    if (errors.hasErrors()) {

      return VIEW_PAGE;
    }

    Map<String, Object> params = new HashMap<String, Object>();

    params.put(
        REPORT_PARA_TITLE,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STUDENT_LATE_ATTENDEES_REPORT));
    params.put(
        REPORT_PARA_STUDENTID,
        PropertyReader.getPropertyValue(ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STUDENT_ID));
    params.put(
        REPORT_PARA_STUDENTNAME,
        PropertyReader.getPropertyValue(ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STUDENT_NAME));
    params.put(
        REPORT_PARA_DATE,
        PropertyReader.getPropertyValue(ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_DATE_CONSIDERED));
    params.put(
        REPORT_PARA_TIMEIN,
        PropertyReader.getPropertyValue(ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_TIME_IN));
    params.put(
        REPORT_PARA_TIMEOUT,
        PropertyReader.getPropertyValue(ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_TIME_OUT));
    params.put(
        REPORT_PARA_DATEFROM,
        attendeesWrapperTemplate.getTeacherLateAttendiesTemplate().getDateFrom());
    params.put(
        REPORT_PARA_DATETO, attendeesWrapperTemplate.getTeacherLateAttendiesTemplate().getDateTo());
    params.put(
        REPORT_PARA_TIMEINFROM,
        attendeesWrapperTemplate.getTeacherLateAttendiesTemplate().getTimeInFrom() + VAR_HR);
    params.put(
        REPORT_PARA_TIMEINTO,
        attendeesWrapperTemplate.getTeacherLateAttendiesTemplate().getTimeInTo() + VAR_HR);
    params.put(
        DATE_FROM,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, STUDENT_WISE_ATTENDEES_DATE_FROM));
    params.put(
        DATE_TO,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, STUDENT_WISE_ATTENDEES_DATE_TO));
    params.put(
        TIME_IN_FROM,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, STUDENT_WISE_ATTENDEES_TIME_IN_FROM));
    params.put(
        TIME_IN_TO,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, STUDENT_WISE_ATTENDEES_TIME_IN_TO));
    params.put(REPORT_PARA_LOGO_PATH, ReportUtil.getReportLogo());
    params.put(
        STYLE_TEMPLATE,
        PropertyReader.getPropertyValue(SYSTEM_CONFIG, APPSERVER_HOME)
            + PropertyReader.getPropertyValue(SYSTEM_CONFIG, STYLE_PATH));

    params.put(
        REPORT_GENERATED_ON,
        PropertyReader.getPropertyValue(ReportUtil.REPORT_TEMPLATE, REPORT_GENERATED_ON_TEXT));
    params.put(
        GENERATED_DATE,
        DateUtil.getReportGeneratedDate(
            PropertyReader.getPropertyValue(
                ReportUtil.REPORT_TEMPLATE, REPORT_GENERATED_DATE_LOCALE)));
    params.put(PAGE, PropertyReader.getPropertyValue(ReportUtil.REPORT_TEMPLATE, REPORT_PAGE));
    params.put(GPL, AkuraWebConstant.REPORT_GPL);

    JRBeanCollectionDataSource jrBeanDataSource =
        attendanceReportingService.getStudentLateAttendeesSummary(
            attendeesWrapperTemplate.getTeacherLateAttendiesTemplate());

    if (jrBeanDataSource.getRecordCount() != 0) {
      displayReportForm(response, jrBeanDataSource, params, REPORT_NAME);
    } else {
      setErrorMessage(map);
      return VIEW_PAGE;
    }
    return returnString;
  }
  /**
   * Generate Student Performance Reports .
   *
   * @param studentTemplate collect user input data to generate the report.
   * @param request of type HttpServletRequest
   * @param response of type HttpServletResponse
   * @param errors of type BindingResult
   * @return java.lang.String
   * @param map of type ModelMap
   * @throws AkuraAppException AkuraAppException
   */
  @RequestMapping(value = REQ_MAP_PERFORMANCE, method = RequestMethod.POST)
  public String onSubmit(
      HttpServletRequest request,
      HttpServletResponse response,
      @ModelAttribute(MODEL_ATT_STUDENT_PERFORMANCE_TEMPLATE)
          CRStudentPerformanceTemplate studentTemplate,
      BindingResult errors,
      ModelMap map)
      throws AkuraAppException {

    String returnString = STRING_EMPTY;

    // get the grade id of selected grade in UI
    int gradeId = Integer.parseInt(request.getParameter(REQUEST_PARA_GRADE_DESCRIPTION));

    LOG.info("Start processing user data for Student Perforance Report");
    Map<String, Object> params = new HashMap<String, Object>();

    // get the inserted marks range and assigned to variable for display in report
    String inBetweenText =
        studentTemplate.getInBetweenLessValue() >= 0
                && studentTemplate.getInBetweenGreaterValue() > 0
            ? MessageFormat.format(
                PropertyReader.getPropertyValue(
                    ReportUtil.REPORT_TEMPLATE, STU_PERFORMANCE_MARKS_RANGE_IN_BETWEEN),
                studentTemplate.getInBetweenLessValue(),
                studentTemplate.getInBetweenGreaterValue())
            : null;

    cRStudentPerformanceBetweenValidator.validate(studentTemplate, errors);
    if (errors.hasErrors()) {
      map.addAttribute(SELECTED_GRADE_ID, gradeId);
      return VIEW_METHOD_REPORTING_STUDENT_PERFORMANCE;
    }
    // set range marks in report
    params.put(REPORT_PARA_MARKS_RANGE_LABLE_TEXT, inBetweenText);

    // find grade object by grade id
    Grade gradeObj = commonService.findGradeById(gradeId);

    // get grade description of selected grade
    String gradeDescription = gradeObj.getDescription();

    // get term id as integer , getting from template
    int termId = Integer.parseInt(studentTemplate.getTerm());

    // list of grade subjects which is related to the grade
    List<GradeSubject> gradeSubjects = commonService.getGradeSubjectList(gradeId);

    // sort the grade subjects
    SortUtil.sortGradeSubjectList(gradeSubjects);

    // set the number of subject columns
    List<String> subjects = StaticDataUtil.getListWithEmptyValues(SUBJECT_COLUMNS);

    List<Integer> gradeSubjectsIds = new LinkedList<Integer>();

    // get all the subjects assigned for particular grade up to 20 subjects
    if (gradeSubjects.size() > 0) {
      for (int i = 0; i < SUBJECT_COLUMNS; i++) {

        Subject subject = gradeSubjects.get(i).getSubject();
        String subjectDescription = subject.getDescription();

        if (subject.getSubjectCode() == null) {

          if (subjectDescription.length() >= SUBJECT_NAME_DISPLAY_CRACTERS) {

            subjects.set(i, subjectDescription.substring(0, SUBJECT_NAME_DISPLAY_CRACTERS));
          } else {

            subjects.set(i, subjectDescription);
          }
        } else {
          subjects.set(i, subject.getSubjectCode());
        }
        gradeSubjectsIds.add(gradeSubjects.get(i).getGradeSubjectId());

        if (i > (gradeSubjects.size() - 2)) {
          break;
        }
      }
    }

    // get the system date - year
    Date currentDate = new Date();
    String year = DateUtil.getStringYear(currentDate);

    // get selected less than mark
    float lessMark = studentTemplate.getInBetweenLessValue();

    // get selected grater than mark
    float graterMark = studentTemplate.getInBetweenGreaterValue();

    // StudentTermMarkPerformance dto for hbm, DB map
    // get all students in selected grade, term, and with in marks range, for only current year
    List<StudentTermMarkPerformance> studentTermsMarksList =
        studentService.getTermMarksByGradeYear(
            gradeDescription, termId, year, lessMark, graterMark);

    // get the data source as for reporting data
    List<StudentPerformanceReportData> reportDataList =
        this.processReportData(studentTermsMarksList, gradeSubjectsIds);

    // set grade description for template
    studentTemplate.setGradeDescription(gradeDescription);

    // set subjects list for report parameter
    params.put(REPORT_PARA_SUBJECTS2, subjects);

    // set grade description as field
    params.put(REPORT_PARA_GRADE_DESCRIPTION, gradeDescription);

    // set parameter names for report attributes
    params.put(
        REPORT_PARA_TERM_DESCRIPTION_LABLE_TEXT,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STU_PERFORMANCE_TERM_DESCRIPTION_LABLE_TEXT));
    params.put(
        REPORT_PARA_STUDY_MEDIUM,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STU_PERFORMANCE_STUDY_MEDIUM_LABLE_TEXT));
    params.put(
        REPORT_PARA_STUDENT_PERFORMANCE_GENERAL_TITLE_TEXT,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STU_PERFORMANCE_TITLE_TEXT));
    params.put(
        REPORT_PARA_GRADE_CLASS_LABLE_TEXT,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STU_PERFORMANCE_GRADE_CLASS_LABLE_TEXT));
    params.put(
        REPORT_PARA_CLASS_LABEL_TEXT,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STU_PERFORMANCE_CLASS_LABEL_TEXT));
    params.put(
        REPORT_PARA_CLASS_LABEL_TEXT2,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STU_PERFORMANCE_CLASS_LABEL_TEXT2));
    params.put(
        REPORT_PARA_ADMISSION_NUMBER_LABLE_TEXT,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STU_PERFORMANCE_ADMISSION_NUMBER_LABLE_TEXT));
    params.put(
        REPORT_PARA_FULL_NAME_LABLE_TEXT,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STU_PERFORMANCE_FULL_NAME_LABLE_TEXT));
    params.put(
        REPORT_PARA_SUBJECT_DESCRIPTION_LABLE_TEXT,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE,
            REPORT_VALUE_STU_PERFORMANCE_SUBJECT_DESCRIPTION_LABLE_TEXT));
    params.put(
        REPORT_PARA_MARKS_LABEL_TEXT,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STU_PERFORMANCE_MARKS_LABLE_TEXT));
    params.put(
        REPORT_PARA_MARKS,
        PropertyReader.getPropertyValue(
            ReportUtil.REPORT_TEMPLATE, REPORT_VALUE_STU_PERFORMANCE_MARKS_LABLE_TEXT1));
    params.put(REPORT_PARA_LOGO_PATH, ReportUtil.getReportLogo());
    params.put(
        STYLE_TEMPLATE,
        PropertyReader.getPropertyValue(SYSTEM_CONFIG, APPSERVER_HOME)
            + PropertyReader.getPropertyValue(SYSTEM_CONFIG, STYLE_PATH));
    params.put(
        REPORT_GENERATED_ON,
        PropertyReader.getPropertyValue(ReportUtil.REPORT_TEMPLATE, REPORT_GENERATED_ON_TEXT));
    params.put(
        GENERATED_DATE,
        DateUtil.getReportGeneratedDate(
            PropertyReader.getPropertyValue(
                ReportUtil.REPORT_TEMPLATE, REPORT_GENERATED_DATE_LOCALE)));
    params.put(PAGE, PropertyReader.getPropertyValue(ReportUtil.REPORT_TEMPLATE, REPORT_PAGE));
    params.put(GPL, AkuraWebConstant.REPORT_GPL);
    params.put(
        NOTE_LABEL,
        PropertyReader.getPropertyValue(ReportUtil.REPORT_TEMPLATE, REPORT_MAXMARK_NOTE));
    // generate report - pass data source list to Jasper report
    JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(reportDataList);

    // check report data is empty
    if (dataSource.getRecordCount() != 0) {
      ReportUtil.displayReportInPdfForm(
          response, dataSource, params, REPORT_NAME_STUDENT_PERFORMANCE_GENERAL);
    } else {
      // set error message , no data message
      setErrorMessage(map, gradeId);
      returnString = VIEW_METHOD_REPORTING_STUDENT_PERFORMANCE;
    }
    return returnString;
  }