private String getHierarchyOrgunit(OrganisationUnit orgunit) {
    String hierarchyOrgunit = orgunit.getName();

    while (orgunit.getParent() != null) {
      hierarchyOrgunit = orgunit.getParent().getName() + " / " + hierarchyOrgunit;

      orgunit = orgunit.getParent();
    }

    return hierarchyOrgunit;
  }
  protected void addValues(Object object) {
    OrganisationUnit unit = (OrganisationUnit) object;

    statementBuilder.setInt(unit.getId());
    statementBuilder.setString(unit.getUuid());
    statementBuilder.setString(unit.getName());
    statementBuilder.setString(
        unit.getParent() != null ? String.valueOf(unit.getParent().getId()) : null);
    statementBuilder.setString(unit.getShortName());
    statementBuilder.setString(unit.getOrganisationUnitCode());
    statementBuilder.setDate(unit.getOpeningDate());
    statementBuilder.setDate(unit.getClosedDate());
    statementBuilder.setBoolean(unit.isActive());
    statementBuilder.setString(unit.getComment());
    statementBuilder.setString(unit.getGeoCode());
    statementBuilder.setString(unit.getLatitude());
    statementBuilder.setString(unit.getLongitude());
  }
  @Ignore
  @Test
  public void testImportOrganisationUnitRelationships() {
    importObjectService.addImportObject(ImportObjectStatus.NEW, organisationUnitAModified, null);
    importObjectService.addImportObject(ImportObjectStatus.NEW, organisationUnitBModified, null);
    importObjectService.addImportObject(ImportObjectStatus.NEW, organisationUnitCModified, null);

    importObjectService.addImportObject(
        ImportObjectStatus.NEW,
        GroupMemberType.ORGANISATIONUNITRELATIONSHIP,
        relationshipAssociationA);
    importObjectService.addImportObject(
        ImportObjectStatus.NEW,
        GroupMemberType.ORGANISATIONUNITRELATIONSHIP,
        relationshipAssociationB);

    dbmsManager.clearSession();

    importObjectService.importAll();

    organisationUnitAModified =
        organisationUnitService.getOrganisationUnitByName(organisationUnitAModified.getName());
    organisationUnitBModified =
        organisationUnitService.getOrganisationUnitByName(organisationUnitBModified.getName());
    organisationUnitCModified =
        organisationUnitService.getOrganisationUnitByName(organisationUnitCModified.getName());

    assertNotNull(organisationUnitAModified);
    assertNotNull(organisationUnitBModified);
    assertNotNull(organisationUnitCModified);

    assertNull(organisationUnitAModified.getParent());
    assertNotNull(organisationUnitBModified.getParent());
    assertNotNull(organisationUnitCModified.getParent());

    assertTrue(organisationUnitBModified.getParent().equals(organisationUnitAModified));
    assertTrue(organisationUnitCModified.getParent().equals(organisationUnitBModified));

    assertEquals(importObjectService.getImportObjects(OrganisationUnit.class).size(), 0);
    assertEquals(importObjectService.getImportObjects(GroupMemberAssociation.class).size(), 0);
  }
  @Override
  public OrganisationUnit getRootOrganisationUnitsParent() {
    Collection<OrganisationUnit> rootUnits = getCollectionFromSession(SESSION_KEY_ROOT_ORG_UNITS);

    if (rootUnits == null || rootUnits.isEmpty()) {
      return null;
    }

    OrganisationUnit randomRootUnit = rootUnits.iterator().next();

    OrganisationUnit reloadedRootUnit = reloadOrganisationUnit(randomRootUnit);

    return reloadedRootUnit.getParent();
  }
  private Collection<OrganisationUnit> getUnitsInTree(
      Collection<OrganisationUnit> rootUnits, Collection<OrganisationUnit> selectedUnits) {
    Collection<OrganisationUnit> unitsInTree = new ArrayList<>();

    for (OrganisationUnit selectedUnit : selectedUnits) {
      if (rootUnits.contains(selectedUnit)) {
        unitsInTree.add(selectedUnit);
        continue;
      }

      OrganisationUnit parent = selectedUnit.getParent();

      while (parent != null) {
        if (rootUnits.contains(parent)) {
          unitsInTree.add(selectedUnit);
        }

        parent = parent.getParent();
      }
    }

    return unitsInTree;
  }
  public static void updateParents(Collection<OrganisationUnit> organisationUnits) {
    Map<String, OrganisationUnit> organisationUnitMap = getOrganisationUnitMap(organisationUnits);

    for (OrganisationUnit organisationUnit : organisationUnits) {
      OrganisationUnit parent = organisationUnit.getParent();

      if (parent != null) {
        if (parent.getUid() != null) {
          parent = organisationUnitMap.get(parent.getUid());
        } else if (parent.getCode() != null) {
          parent = organisationUnitMap.get(parent.getCode());
        } else if (parent.getName() != null) {
          parent = organisationUnitMap.get(parent.getName());
        } else if (parent.getShortName() != null) {
          parent = organisationUnitMap.get(parent.getShortName());
        }
      }

      if (parent != null) {
        organisationUnit.setParent(parent);
      }
    }
  }
  // -------------------------------------------------------------------------
  // Action Implementation
  // -------------------------------------------------------------------------
  public String execute() throws Exception {
    statementManager.initialise();

    // Initialization
    raFolderName = reportService.getRAFolderName();
    String deCodesXMLFileName = "";
    simpleDateFormat = new SimpleDateFormat("MMM-yyyy");
    monthFormat = new SimpleDateFormat("MMMM");
    yearFormat = new SimpleDateFormat("yyyy");
    simpleMonthFormat = new SimpleDateFormat("MMM");
    String parentUnit = "";

    Report_in selReportObj = reportService.getReport(Integer.parseInt(reportList));

    deCodesXMLFileName = selReportObj.getXmlTemplateName();

    reportModelTB = selReportObj.getModel();
    reportFileNameTB = selReportObj.getExcelTemplateName();

    String inputTemplatePath =
        System.getenv("DHIS2_HOME")
            + File.separator
            + raFolderName
            + File.separator
            + "template"
            + File.separator
            + reportFileNameTB;
    // String outputReportFolderPath = System.getenv( "DHIS2_HOME" ) + File.separator + raFolderName
    // + File.separator + "output" + File.separator + UUID.randomUUID().toString();
    String outputReportFolderPath =
        System.getenv("DHIS2_HOME")
            + File.separator
            + Configuration_IN.DEFAULT_TEMPFOLDER
            + File.separator
            + UUID.randomUUID().toString();
    File newdir = new File(outputReportFolderPath);
    if (!newdir.exists()) {
      newdir.mkdirs();
    }

    if (reportModelTB.equalsIgnoreCase("STATIC")
        || reportModelTB.equalsIgnoreCase("STATIC-DATAELEMENTS")
        || reportModelTB.equalsIgnoreCase("STATIC-FINANCIAL")) {
      orgUnitList =
          new ArrayList<OrganisationUnit>(
              organisationUnitService.getOrganisationUnitWithChildren(ouIDTB));
      OrganisationUnitGroup orgUnitGroup = selReportObj.getOrgunitGroup();

      orgUnitList.retainAll(orgUnitGroup.getMembers());
    } else {
      return INPUT;
    }

    // System.out.println(  "---Size of Org Unit List ----: " + orgUnitList.size() + ",Report Group
    // name is :---" + selReportObj.getOrgunitGroup().getName() + ", Size of Group member is ----:"
    // + selReportObj.getOrgunitGroup().getMembers().size()  );

    System.out.println(" ---- Size of OrgUnit List is ---- " + orgUnitList.size());

    OrganisationUnit selOrgUnit = organisationUnitService.getOrganisationUnit(ouIDTB);

    System.out.println(
        selOrgUnit.getName()
            + " : "
            + selReportObj.getName()
            + " : Report Generation Start Time is : "
            + new Date());

    selectedPeriod = periodService.getPeriod(availablePeriods);

    sDate = format.parseDate(String.valueOf(selectedPeriod.getStartDate()));

    eDate = format.parseDate(String.valueOf(selectedPeriod.getEndDate()));

    Workbook templateWorkbook = Workbook.getWorkbook(new File(inputTemplatePath));

    // collect periodId by commaSepareted
    List<Period> tempPeriodList =
        new ArrayList<Period>(periodService.getIntersectingPeriods(sDate, eDate));

    Collection<Integer> tempPeriodIds =
        new ArrayList<Integer>(getIdentifiers(Period.class, tempPeriodList));

    String periodIdsByComma = getCommaDelimitedString(tempPeriodIds);

    // Getting DataValues
    List<Report_inDesign> reportDesignList = reportService.getReportDesign(deCodesXMLFileName);

    // collect dataElementIDs by commaSepareted
    String dataElmentIdsByComma = reportService.getDataelementIds(reportDesignList);

    int orgUnitCount = 0;

    Iterator<OrganisationUnit> it = orgUnitList.iterator();
    while (it.hasNext()) {
      OrganisationUnit currentOrgUnit = (OrganisationUnit) it.next();

      String outPutFileName = reportFileNameTB.replace(".xls", "");
      outPutFileName += "_" + currentOrgUnit.getShortName();
      outPutFileName += "_" + simpleDateFormat.format(selectedPeriod.getStartDate()) + ".xls";

      String outputReportPath = outputReportFolderPath + File.separator + outPutFileName;
      WritableWorkbook outputReportWorkbook =
          Workbook.createWorkbook(new File(outputReportPath), templateWorkbook);

      Map<String, String> aggDeMap = new HashMap<String, String>();
      if (aggData.equalsIgnoreCase(USEEXISTINGAGGDATA)) {
        aggDeMap.putAll(
            reportService.getResultDataValueFromAggregateTable(
                currentOrgUnit.getId(), dataElmentIdsByComma, periodIdsByComma));
      } else if (aggData.equalsIgnoreCase(GENERATEAGGDATA)) {
        List<OrganisationUnit> childOrgUnitTree =
            new ArrayList<OrganisationUnit>(
                organisationUnitService.getOrganisationUnitWithChildren(currentOrgUnit.getId()));
        List<Integer> childOrgUnitTreeIds =
            new ArrayList<Integer>(getIdentifiers(OrganisationUnit.class, childOrgUnitTree));
        String childOrgUnitsByComma = getCommaDelimitedString(childOrgUnitTreeIds);

        aggDeMap.putAll(
            reportService.getAggDataFromDataValueTable(
                childOrgUnitsByComma, dataElmentIdsByComma, periodIdsByComma));
      } else if (aggData.equalsIgnoreCase(USECAPTUREDDATA)) {
        aggDeMap.putAll(
            reportService.getAggDataFromDataValueTable(
                "" + currentOrgUnit.getId(), dataElmentIdsByComma, periodIdsByComma));
      }

      int count1 = 0;
      Iterator<Report_inDesign> reportDesignIterator = reportDesignList.iterator();
      while (reportDesignIterator.hasNext()) {
        Report_inDesign report_inDesign = (Report_inDesign) reportDesignIterator.next();

        String deType = report_inDesign.getPtype();
        String sType = report_inDesign.getStype();
        String deCodeString = report_inDesign.getExpression();
        String tempStr = "";

        Calendar tempStartDate = Calendar.getInstance();
        Calendar tempEndDate = Calendar.getInstance();
        List<Calendar> calendarList =
            new ArrayList<Calendar>(reportService.getStartingEndingPeriods(deType, selectedPeriod));
        if (calendarList == null || calendarList.isEmpty()) {
          tempStartDate.setTime(selectedPeriod.getStartDate());
          tempEndDate.setTime(selectedPeriod.getEndDate());
          return SUCCESS;
        } else {
          tempStartDate = calendarList.get(0);
          tempEndDate = calendarList.get(1);
        }

        if (deCodeString.equalsIgnoreCase("FACILITY")) {
          tempStr = currentOrgUnit.getName();
        } else if (deCodeString.equalsIgnoreCase("FACILITY-NOREPEAT")) {
          tempStr = parentUnit;
        } else if (deCodeString.equalsIgnoreCase("FACILITYP")) {
          tempStr = currentOrgUnit.getParent().getName();
        } else if (deCodeString.equalsIgnoreCase("FACILITYPP")) {
          tempStr = currentOrgUnit.getParent().getParent().getName();
        } else if (deCodeString.equalsIgnoreCase("FACILITYPPP")) {
          tempStr = currentOrgUnit.getParent().getParent().getParent().getName();
        } else if (deCodeString.equalsIgnoreCase("FACILITYPPPP")) {
          tempStr = currentOrgUnit.getParent().getParent().getParent().getParent().getName();
        } else if (deCodeString.equalsIgnoreCase("PERIOD")
            || deCodeString.equalsIgnoreCase("PERIOD-NOREPEAT")) {
          tempStr = simpleDateFormat.format(sDate);
        } else if (deCodeString.equalsIgnoreCase("PERIOD-MONTH")) {
          tempStr = monthFormat.format(sDate);
        } else if (deCodeString.equalsIgnoreCase("PERIOD-YEAR")) {
          tempStr = yearFormat.format(sDate);
        } else if (deCodeString.equalsIgnoreCase("MONTH-START-SHORT")) {
          tempStr = simpleMonthFormat.format(sDate);
        } else if (deCodeString.equalsIgnoreCase("MONTH-END-SHORT")) {
          tempStr = simpleMonthFormat.format(eDate);
        } else if (deCodeString.equalsIgnoreCase("MONTH-START")) {
          tempStr = monthFormat.format(sDate);
        } else if (deCodeString.equalsIgnoreCase("MONTH-END")) {
          tempStr = monthFormat.format(eDate);
        } else if (deCodeString.equalsIgnoreCase("SLNO")) {
          tempStr = "" + (orgUnitCount + 1);
        } else if (deCodeString.equalsIgnoreCase("NA")) {
          tempStr = " ";
        } else {
          if (sType.equalsIgnoreCase("dataelement")) {
            if (aggData.equalsIgnoreCase(USECAPTUREDDATA)) {
              tempStr = getAggVal(deCodeString, aggDeMap);
              // tempStr = reportService.getIndividualResultDataValue(deCodeString,
              // tempStartDate.getTime(), tempEndDate.getTime(), currentOrgUnit, reportModelTB );
            } else if (aggData.equalsIgnoreCase(GENERATEAGGDATA)) {
              tempStr = getAggVal(deCodeString, aggDeMap);
              // tempStr = reportService.getResultDataValue( deCodeString, tempStartDate.getTime(),
              // tempEndDate.getTime(), currentOrgUnit, reportModelTB );
            } else if (aggData.equalsIgnoreCase(USEEXISTINGAGGDATA)) {

              tempStr = getAggVal(deCodeString, aggDeMap);
              /*
              List<Period> periodList = new ArrayList<Period>( periodService.getPeriodsBetweenDates( tempStartDate.getTime(), tempEndDate.getTime() ) );
              Collection<Integer> periodIds = new ArrayList<Integer>( getIdentifiers(Period.class, periodList ) );
              tempStr = reportService.getResultDataValueFromAggregateTable( deCodeString, periodIds, currentOrgUnit, reportModelTB );
              */
            }
          } else if (sType.equalsIgnoreCase("dataelement-boolean")) {
            if (aggData.equalsIgnoreCase(USECAPTUREDDATA)) {
              tempStr =
                  reportService.getBooleanDataValue(
                      deCodeString,
                      tempStartDate.getTime(),
                      tempEndDate.getTime(),
                      currentOrgUnit,
                      reportModelTB);
            } else if (aggData.equalsIgnoreCase(GENERATEAGGDATA)) {
              tempStr =
                  reportService.getBooleanDataValue(
                      deCodeString,
                      tempStartDate.getTime(),
                      tempEndDate.getTime(),
                      currentOrgUnit,
                      reportModelTB);
            } else if (aggData.equalsIgnoreCase(USEEXISTINGAGGDATA)) {
              tempStr =
                  reportService.getBooleanDataValue(
                      deCodeString,
                      tempStartDate.getTime(),
                      tempEndDate.getTime(),
                      currentOrgUnit,
                      reportModelTB);
            }
          } else {
            if (aggData.equalsIgnoreCase(USECAPTUREDDATA)) {
              tempStr =
                  reportService.getIndividualResultIndicatorValue(
                      deCodeString, tempStartDate.getTime(), tempEndDate.getTime(), currentOrgUnit);
            } else if (aggData.equalsIgnoreCase(GENERATEAGGDATA)) {
              tempStr =
                  reportService.getResultIndicatorValue(
                      deCodeString, tempStartDate.getTime(), tempEndDate.getTime(), currentOrgUnit);
            } else if (aggData.equalsIgnoreCase(USEEXISTINGAGGDATA)) {
              // List<Period> periodList = new ArrayList<Period>(
              // periodService.getPeriodsBetweenDates( tempStartDate.getTime(),
              // tempEndDate.getTime() ) );
              // Collection<Integer> periodIds = new ArrayList<Integer>(
              // getIdentifiers(Period.class, periodList ) );
              tempStr =
                  reportService.getResultIndicatorValue(
                      deCodeString, tempStartDate.getTime(), tempEndDate.getTime(), currentOrgUnit);
            }
          }
        }

        int tempRowNo = report_inDesign.getRowno();
        int tempColNo = report_inDesign.getColno();
        int sheetNo = report_inDesign.getSheetno();
        WritableSheet sheet0 = outputReportWorkbook.getSheet(sheetNo);

        if (tempStr == null || tempStr.equals(" ")) {
          tempColNo += orgUnitCount;

          WritableCellFormat wCellformat = new WritableCellFormat();
          wCellformat.setBorder(Border.ALL, BorderLineStyle.THIN);
          wCellformat.setWrap(true);
          wCellformat.setAlignment(Alignment.CENTRE);

          sheet0.addCell(new Blank(tempColNo, tempRowNo, wCellformat));
        } else {
          if (reportModelTB.equalsIgnoreCase("DYNAMIC-ORGUNIT")) {
            if (deCodeString.equalsIgnoreCase("FACILITYP")
                || deCodeString.equalsIgnoreCase("FACILITYPP")
                || deCodeString.equalsIgnoreCase("FACILITYPPP")
                || deCodeString.equalsIgnoreCase("FACILITYPPPP")) {
            } else if (deCodeString.equalsIgnoreCase("PERIOD")
                || deCodeString.equalsIgnoreCase("PERIOD-NOREPEAT")
                || deCodeString.equalsIgnoreCase("PERIOD-WEEK")
                || deCodeString.equalsIgnoreCase("PERIOD-MONTH")
                || deCodeString.equalsIgnoreCase("PERIOD-QUARTER")
                || deCodeString.equalsIgnoreCase("PERIOD-YEAR")
                || deCodeString.equalsIgnoreCase("MONTH-START")
                || deCodeString.equalsIgnoreCase("MONTH-END")
                || deCodeString.equalsIgnoreCase("MONTH-START-SHORT")
                || deCodeString.equalsIgnoreCase("MONTH-END-SHORT")
                || deCodeString.equalsIgnoreCase("SIMPLE-QUARTER")
                || deCodeString.equalsIgnoreCase("QUARTER-MONTHS-SHORT")
                || deCodeString.equalsIgnoreCase("QUARTER-MONTHS")
                || deCodeString.equalsIgnoreCase("QUARTER-START-SHORT")
                || deCodeString.equalsIgnoreCase("QUARTER-END-SHORT")
                || deCodeString.equalsIgnoreCase("QUARTER-START")
                || deCodeString.equalsIgnoreCase("QUARTER-END")
                || deCodeString.equalsIgnoreCase("SIMPLE-YEAR")
                || deCodeString.equalsIgnoreCase("YEAR-END")
                || deCodeString.equalsIgnoreCase("YEAR-FROMTO")) {
            } else {
              tempColNo += orgUnitCount;
            }
          } else if (reportModelTB.equalsIgnoreCase("dynamicwithrootfacility")) {
            if (deCodeString.equalsIgnoreCase("FACILITYP")
                || deCodeString.equalsIgnoreCase("FACILITY-NOREPEAT")
                || deCodeString.equalsIgnoreCase("FACILITYPP")
                || deCodeString.equalsIgnoreCase("FACILITYPPP")
                || deCodeString.equalsIgnoreCase("FACILITYPPPP")) {
            } else if (deCodeString.equalsIgnoreCase("PERIOD")
                || deCodeString.equalsIgnoreCase("PERIOD-NOREPEAT")
                || deCodeString.equalsIgnoreCase("PERIOD-WEEK")
                || deCodeString.equalsIgnoreCase("PERIOD-MONTH")
                || deCodeString.equalsIgnoreCase("PERIOD-QUARTER")
                || deCodeString.equalsIgnoreCase("PERIOD-YEAR")
                || deCodeString.equalsIgnoreCase("MONTH-START")
                || deCodeString.equalsIgnoreCase("MONTH-END")
                || deCodeString.equalsIgnoreCase("MONTH-START-SHORT")
                || deCodeString.equalsIgnoreCase("MONTH-END-SHORT")
                || deCodeString.equalsIgnoreCase("SIMPLE-QUARTER")
                || deCodeString.equalsIgnoreCase("QUARTER-MONTHS-SHORT")
                || deCodeString.equalsIgnoreCase("QUARTER-MONTHS")
                || deCodeString.equalsIgnoreCase("QUARTER-START-SHORT")
                || deCodeString.equalsIgnoreCase("QUARTER-END-SHORT")
                || deCodeString.equalsIgnoreCase("QUARTER-START")
                || deCodeString.equalsIgnoreCase("QUARTER-END")
                || deCodeString.equalsIgnoreCase("SIMPLE-YEAR")
                || deCodeString.equalsIgnoreCase("YEAR-END")
                || deCodeString.equalsIgnoreCase("YEAR-FROMTO")) {
            } else {
              tempRowNo += orgUnitCount;
            }
          }

          WritableCell cell = sheet0.getWritableCell(tempColNo, tempRowNo);

          CellFormat cellFormat = cell.getCellFormat();
          WritableCellFormat wCellformat = new WritableCellFormat();
          wCellformat.setBorder(Border.ALL, BorderLineStyle.THIN);
          wCellformat.setWrap(true);
          wCellformat.setAlignment(Alignment.CENTRE);

          if (cell.getType() == CellType.LABEL) {
            Label l = (Label) cell;
            l.setString(tempStr);
            l.setCellFormat(cellFormat);
          } else {
            try {
              sheet0.addCell(
                  new Number(tempColNo, tempRowNo, Double.parseDouble(tempStr), wCellformat));
            } catch (Exception e) {
              sheet0.addCell(new Label(tempColNo, tempRowNo, tempStr, wCellformat));
            }
          }
        }

        count1++;
      } // inner while loop end

      outputReportWorkbook.write();
      outputReportWorkbook.close();

      orgUnitCount++;
    } // outer while loop end

    statementManager.destroy();

    if (zipDirectory(outputReportFolderPath, outputReportFolderPath + ".zip")) {
      System.out.println(
          selOrgUnit.getName()
              + " : "
              + selReportObj.getName()
              + " Report Generation End Time is : "
              + new Date());

      fileName = reportFileNameTB.replace(".xls", "");
      fileName += "_" + selOrgUnit.getShortName();
      fileName += "_" + simpleDateFormat.format(selectedPeriod.getStartDate()) + ".zip";

      File outputReportFile = new File(outputReportFolderPath + ".zip");
      inputStream = new BufferedInputStream(new FileInputStream(outputReportFile));

      return SUCCESS;
    } else {
      return INPUT;
    }
  }
  public String execute() throws Exception {
    type = StringUtils.trimToNull(type);

    // ---------------------------------------------------------------------
    // Get group sets
    // ---------------------------------------------------------------------

    groupSets =
        new ArrayList<OrganisationUnitGroupSet>(
            organisationUnitGroupService.getCompulsoryOrganisationUnitGroupSets());

    Collections.sort(groupSets, IdentifiableObjectNameComparator.INSTANCE);

    // ---------------------------------------------------------------------
    // Assemble groups and get search result
    // ---------------------------------------------------------------------

    if (!skipSearch) {
      name = StringUtils.trimToNull(name);

      selectedOrganisationUnit = selectionManager.getSelectedOrganisationUnit();

      log.debug("Name: " + name + ", Orgunit: " + selectedOrganisationUnit + ", type: " + type);

      // -----------------------------------------------------------------
      // Set orgunit to null if root to avoid subquery and improve perf
      // -----------------------------------------------------------------

      selectedOrganisationUnit =
          selectedOrganisationUnit != null && selectedOrganisationUnit.getParent() == null
              ? null
              : selectedOrganisationUnit;

      Collection<OrganisationUnitGroup> groups = new HashSet<OrganisationUnitGroup>();

      for (Integer id : groupId) {
        if (id != ANY) {
          OrganisationUnitGroup group = organisationUnitGroupService.getOrganisationUnitGroup(id);
          groups.add(group);
        }
      }

      boolean limit = type == null; // Only limit for HTML view since browser is memory constrained

      organisationUnits =
          new ArrayList<OrganisationUnit>(
              organisationUnitService.getOrganisationUnitsByNameAndGroups(
                  name, groups, selectedOrganisationUnit, limit));

      limited =
          organisationUnits != null
              && organisationUnits.size() == OrganisationUnitService.MAX_LIMIT;

      Collections.sort(organisationUnits, IdentifiableObjectNameComparator.INSTANCE);

      if (type != null && !type.equalsIgnoreCase(DEFAULT_TYPE)) {
        grid = generateGrid();
      }
    }

    return type != null ? type : SUCCESS;
  }
  public void generateReport(
      Program selProgram, List<OrganisationUnit> orgUnitList, Date sDate, Date eDate)
      throws Exception {
    String raFolderName = reportService.getRAFolderName();
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    String query = "";
    int rowStart = 3;
    int colStart = 1;
    int rowCount = rowStart;
    int colCount = colStart;

    // String outputReportPath = System.getenv( "DHIS2_HOME" ) + File.separator + raFolderName +
    // File.separator + "output" + File.separator + UUID.randomUUID().toString() + ".xls";

    String outputReportPath =
        System.getenv("DHIS2_HOME") + File.separator + Configuration_IN.DEFAULT_TEMPFOLDER;
    File newdir = new File(outputReportPath);
    if (!newdir.exists()) {
      newdir.mkdirs();
    }
    outputReportPath += File.separator + UUID.randomUUID().toString() + ".xls";

    WritableWorkbook outputReportWorkbook = Workbook.createWorkbook(new File(outputReportPath));
    WritableSheet sheet0 = outputReportWorkbook.createSheet(selProgram.getName(), 0);

    try {
      List<PatientIdentifierType> patientIdentifierTypes =
          new ArrayList<PatientIdentifierType>(
              patientIdentifierTypeService.getAllPatientIdentifierTypes());
      Collections.sort(patientIdentifierTypes, new PatientIdentifierTypeComparator());

      List<PatientAttribute> patientAttributes =
          new ArrayList<PatientAttribute>(patientAttributeService.getAllPatientAttributes());
      Collections.sort(patientAttributes, new PatientAttributeComparator());

      List<ProgramStage> programStages = new ArrayList<ProgramStage>(selProgram.getProgramStages());
      Collections.sort(programStages, new ProgramStageOrderComparator());

      Map<ProgramStage, List<DataElement>> programStageDataElementMap =
          new HashMap<ProgramStage, List<DataElement>>();
      for (ProgramStage programStage : programStages) {
        List<ProgramStageDataElement> programStageDataElements =
            new ArrayList<ProgramStageDataElement>(programStage.getProgramStageDataElements());

        List<DataElement> dataElements = new ArrayList<DataElement>();
        for (ProgramStageDataElement programStageDataElement : programStageDataElements) {
          dataElements.add(programStageDataElement.getDataElement());
        }

        Collections.sort(dataElements, new IdentifiableObjectNameComparator());
        programStageDataElementMap.put(programStage, dataElements);
      }

      // Printing Header Information
      sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
      sheet0.addCell(new Label(colCount, rowCount - 1, "OrgUnit Hierarchy", getCellFormat1()));
      colCount++;
      sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
      sheet0.addCell(new Label(colCount, rowCount - 1, "OrgUnit", getCellFormat1()));
      colCount++;
      for (PatientIdentifierType patientIdentifierType : patientIdentifierTypes) {
        sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
        sheet0.addCell(
            new Label(colCount, rowCount - 1, patientIdentifierType.getName(), getCellFormat1()));
        colCount++;
      }

      sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
      sheet0.addCell(new Label(colCount, rowCount - 1, "Benificiary ID", getCellFormat1()));
      colCount++;

      sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
      sheet0.addCell(new Label(colCount, rowCount - 1, "Benificiary Name", getCellFormat1()));
      colCount++;
      sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
      sheet0.addCell(new Label(colCount, rowCount - 1, "Gender", getCellFormat1()));
      colCount++;
      sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
      sheet0.addCell(new Label(colCount, rowCount - 1, "Age", getCellFormat1()));
      colCount++;
      sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
      sheet0.addCell(new Label(colCount, rowCount - 1, "Data of Birth", getCellFormat1()));
      colCount++;
      sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
      sheet0.addCell(new Label(colCount, rowCount - 1, "Blood Group", getCellFormat1()));
      colCount++;
      sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
      sheet0.addCell(new Label(colCount, rowCount - 1, "Registration Date", getCellFormat1()));
      colCount++;

      for (PatientAttribute patientAttribute : patientAttributes) {
        sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
        sheet0.addCell(
            new Label(colCount, rowCount - 1, patientAttribute.getName(), getCellFormat1()));
        colCount++;
      }

      sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
      sheet0.addCell(new Label(colCount, rowCount - 1, "Incident Date", getCellFormat1()));
      colCount++;

      sheet0.mergeCells(colCount, rowCount - 1, colCount, rowCount);
      sheet0.addCell(new Label(colCount, rowCount - 1, "Enrollment Date", getCellFormat1()));
      colCount++;
      for (ProgramStage programStage : programStages) {
        List<DataElement> dataElementList =
            new ArrayList<DataElement>(programStageDataElementMap.get(programStage));
        sheet0.mergeCells(
            colCount, rowCount - 1, colCount + dataElementList.size() + 1, rowCount - 1);
        sheet0.addCell(new Label(colCount, rowCount - 1, programStage.getName(), getCellFormat1()));

        sheet0.addCell(new Label(colCount, rowCount, "Due Date", getCellFormat1()));
        colCount++;
        sheet0.addCell(new Label(colCount, rowCount, "Execution Date", getCellFormat1()));
        colCount++;

        for (DataElement dataElement : dataElementList) {
          sheet0.addCell(
              new Label(
                  colCount,
                  rowCount,
                  dataElement.getName() + "--" + dataElement.getType(),
                  getCellFormat1()));
          colCount++;
        }
      }

      rowCount++;

      for (OrganisationUnit orgUnit : orgUnitList) {
        if (sDate != null && eDate != null) {
          query =
              "SELECT patient.patientid, programinstance.programinstanceid,programinstance.dateofincident,programinstance.enrollmentdate FROM programinstance INNER JOIN patient "
                  + " ON programinstance.patientid = patient.patientid "
                  + " WHERE patient.organisationunitid = "
                  + orgUnit.getId()
                  + " AND programinstance.programid = "
                  + selProgram.getId()
                  + " AND patient.registrationdate >= '"
                  + startDate
                  + "'"
                  + " AND patient.registrationdate <= '"
                  + endDate
                  + "' "
                  + " AND enddate IS NULL";
        } else {
          query =
              "SELECT patient.patientid, programinstance.programinstanceid,programinstance.dateofincident,programinstance.enrollmentdate FROM programinstance INNER JOIN patient "
                  + " ON programinstance.patientid = patient.patientid "
                  + " WHERE patient.organisationunitid = "
                  + orgUnit.getId()
                  + " AND programinstance.programid = "
                  + selProgram.getId()
                  + " AND enddate IS NULL";
        }

        SqlRowSet sqlResultSet = jdbcTemplate.queryForRowSet(query);

        if (sqlResultSet != null) {
          int count = 1;
          String orgUnitBranch = "";
          sqlResultSet.beforeFirst();
          while (sqlResultSet.next()) {
            colCount = colStart;

            if (orgUnit.getParent() != null) {
              orgUnitBranch = getOrgunitBranch(orgUnit.getParent());
            } else {
              orgUnitBranch = " ";
            }

            sheet0.addCell(new Label(colCount, rowCount, orgUnitBranch, getCellFormat2()));
            colCount++;
            sheet0.addCell(new Label(colCount, rowCount, orgUnit.getName(), getCellFormat2()));
            colCount++;

            int patientId = sqlResultSet.getInt(1);
            int programInstanceId = sqlResultSet.getInt(2);
            Date dateOfIncident = sqlResultSet.getDate(3);
            Date dateOfEnrollment = sqlResultSet.getDate(4);

            Patient patient = patientService.getPatient(patientId);

            // Patient Identifier Details
            for (PatientIdentifierType patientIdentifierType : patientIdentifierTypes) {
              query =
                  "SELECT identifier from patientidentifier WHERE patientidentifiertypeid = "
                      + patientIdentifierType.getId()
                      + " AND patientid = "
                      + patient.getId();

              SqlRowSet sqlResultSet1 = jdbcTemplate.queryForRowSet(query);
              if (sqlResultSet1 != null && sqlResultSet1.next()) {
                String value = sqlResultSet1.getString(1);
                if (value != null && !value.trim().equalsIgnoreCase("")) {
                  sheet0.addCell(new Label(colCount, rowCount, value, getCellFormat2()));
                } else {
                  sheet0.addCell(new Label(colCount, rowCount, "-", getCellFormat2()));
                }
              } else {
                sheet0.addCell(new Label(colCount, rowCount, "-", getCellFormat2()));
              }

              colCount++;
            }

            // Patient Properties

            sheet0.addCell(
                new Label(colCount, rowCount, patient.getId().toString(), getCellFormat2()));
            colCount++;
            sheet0.addCell(new Label(colCount, rowCount, patient.getFullName(), getCellFormat2()));
            colCount++;
            sheet0.addCell(
                new Label(colCount, rowCount, patient.getTextGender(), getCellFormat2()));
            colCount++;
            sheet0.addCell(new Label(colCount, rowCount, patient.getAge(), getCellFormat2()));
            colCount++;
            sheet0.addCell(
                new Label(
                    colCount,
                    rowCount,
                    simpleDateFormat.format(patient.getBirthDate()),
                    getCellFormat2()));
            colCount++;
            /**
             * TODO BloodGroup is removed from Patient Object, so need to change this accordingly
             */
            sheet0.addCell(
                new Label(colCount, rowCount, "" /*patient.getBloodGroup()*/, getCellFormat2()));
            colCount++;
            sheet0.addCell(
                new Label(
                    colCount,
                    rowCount,
                    simpleDateFormat.format(patient.getRegistrationDate()),
                    getCellFormat2()));
            colCount++;

            // Patient Attribute Values
            for (PatientAttribute patientAttribute : patientAttributes) {
              query =
                  "SELECT value from patientattributevalue WHERE patientid = "
                      + patient.getId()
                      + " AND patientattributeid = "
                      + patientAttribute.getId();

              SqlRowSet sqlResultSet1 = jdbcTemplate.queryForRowSet(query);
              if (sqlResultSet1 != null && sqlResultSet1.next()) {
                String value = sqlResultSet1.getString(1);
                if (value != null && !value.trim().equalsIgnoreCase("")) {
                  sheet0.addCell(new Label(colCount, rowCount, value, getCellFormat2()));
                } else {
                  sheet0.addCell(new Label(colCount, rowCount, "-", getCellFormat2()));
                }
              } else {
                sheet0.addCell(new Label(colCount, rowCount, "-", getCellFormat2()));
              }

              colCount++;
            }

            // Program Enrollment Details
            sheet0.addCell(
                new Label(
                    colCount, rowCount, simpleDateFormat.format(dateOfIncident), getCellFormat2()));
            colCount++;
            sheet0.addCell(
                new Label(
                    colCount,
                    rowCount,
                    simpleDateFormat.format(dateOfEnrollment),
                    getCellFormat2()));
            colCount++;

            // ProgramStage Values
            for (ProgramStage programStage : programStages) {
              query =
                  "SELECT programstageinstanceid,duedate,executiondate from programstageinstance "
                      + " WHERE programinstanceid = "
                      + programInstanceId
                      + " AND programstageid = "
                      + programStage.getId();

              SqlRowSet sqlResultSet2 = jdbcTemplate.queryForRowSet(query);
              Integer programStageInstanceId = 0;
              if (sqlResultSet2 != null && sqlResultSet2.next()) {
                programStageInstanceId = sqlResultSet2.getInt(1);

                // ProgramStage DueDate and Execution Date
                Date dueDate = sqlResultSet2.getDate(2);
                Date exeDate = sqlResultSet2.getDate(3);

                if (dueDate != null) {
                  String dueDateStr = simpleDateFormat.format(dueDate);
                  sheet0.addCell(new Label(colCount, rowCount, dueDateStr, getCellFormat3()));
                } else {
                  sheet0.addCell(new Label(colCount, rowCount, "-", getCellFormat3()));
                }
                colCount++;

                if (exeDate != null) {
                  String exeDateStr = simpleDateFormat.format(exeDate);
                  sheet0.addCell(new Label(colCount, rowCount, exeDateStr, getCellFormat3()));
                } else {
                  sheet0.addCell(new Label(colCount, rowCount, "-", getCellFormat3()));
                }

                colCount++;
              } else {
                sheet0.addCell(new Label(colCount, rowCount, "-", getCellFormat3()));
                colCount++;
                sheet0.addCell(new Label(colCount, rowCount, "-", getCellFormat3()));
                colCount++;
              }

              for (DataElement dataElement : programStageDataElementMap.get(programStage)) {
                query =
                    "SELECT value from patientdatavalue WHERE programstageinstanceid = "
                        + programStageInstanceId
                        + " AND dataelementid = "
                        + dataElement.getId();
                // " AND organisationunitid = " + orgUnit.getId();

                SqlRowSet sqlResultSet3 = jdbcTemplate.queryForRowSet(query);

                if (sqlResultSet3 != null && sqlResultSet3.next()) {
                  String value = sqlResultSet3.getString(1);

                  if (dataElement.getType().equalsIgnoreCase(DataElement.VALUE_TYPE_BOOL)) {
                    if (value.equalsIgnoreCase("false")) value = "No";
                    else value = "Yes";
                  }

                  if (value != null && !value.trim().equalsIgnoreCase("")) {
                    sheet0.addCell(new Label(colCount, rowCount, value, getCellFormat2()));
                  } else {
                    sheet0.addCell(new Label(colCount, rowCount, "-", getCellFormat2()));
                  }
                } else {
                  sheet0.addCell(new Label(colCount, rowCount, "-", getCellFormat2()));
                }

                colCount++;
              }
            }

            rowCount++;
          }
        }
      }
    } catch (Exception e) {
      System.out.println("Exception: " + e.getMessage());
      e.printStackTrace();
    }

    outputReportWorkbook.write();
    outputReportWorkbook.close();
    fileName = selProgram.getName() + ".xls";
    File outputReportFile = new File(outputReportPath);
    inputStream = new BufferedInputStream(new FileInputStream(outputReportFile));
    outputReportFile.deleteOnExit();
  }