/**
   * Method is to return GradeClass list.
   *
   * @param request - HttpServletRequest
   * @param modelMap - ModelMap attribute.
   * @return list of classGrade
   * @throws AkuraAppException - Detailed exception
   */
  @RequestMapping(value = ATTENDANCE_GRADE_CLASS_LIST_HTM)
  @ResponseBody
  public String populateGradeClass(ModelMap modelMap, HttpServletRequest request)
      throws AkuraAppException {

    StringBuilder allGradeClass = new StringBuilder();
    int gradeId = Integer.parseInt(request.getParameter(SELECTED_VALUE));
    Grade grade = commonService.findGradeById(gradeId);
    List<ClassGrade> classGrades =
        SortUtil.sortClassGradeList(commonService.getClassGradeListByGrade(grade));
    boolean isFirst = true;
    StringBuilder classes = new StringBuilder();

    for (ClassGrade classGrade : classGrades) {
      classes.append(classGrade.getDescription());
      classes.append(AkuraWebConstant.UNDERSCORE_STRING);
      classes.append(classGrade.getClassGradeId());

      if (isFirst) {
        allGradeClass.append(classes.toString()); // no comma
        isFirst = false;
      } else {
        allGradeClass.append(AkuraWebConstant.STRING_COMMA); // comma
        allGradeClass.append(classes.toString());
      }
      classes.delete(0, classes.length());
    }
    return allGradeClass.toString();
  }
  /**
   * 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;
  }
  /**
   * Method is to return Grade list reference data.
   *
   * @return GradeList - Grade reference data.
   * @throws AkuraAppException - throw SMSExeption.
   */
  @ModelAttribute(MODEL_ATT_GRADE_LIST)
  public List<Grade> populateGradeList() throws AkuraAppException {

    return SortUtil.sortGradeList(commonService.getGradeList());
  }
  /**
   * Returns list of terms.
   *
   * @return the term list.
   * @throws AkuraAppException AkuraAppException
   */
  @ModelAttribute(TERM_LIST)
  public List<Term> populateTermList() throws AkuraAppException {

    return SortUtil.sortTermList(commonService.getTermList());
  }