@Override
  public Collection<MifosEntityAccessData> retrieveEntityAccessFor(
      Long firstEntityId,
      MifosEntityType firstEntityType,
      MifosEntityAccessType accessType,
      MifosEntityType secondEntityType,
      boolean includeAllSubOffices) {
    final AppUser currentUser = this.context.authenticatedUser();

    final String hierarchy = currentUser.getOffice().getHierarchy();
    String hierarchySearchString = null;
    if (includeAllSubOffices) {
      hierarchySearchString = "." + "%";
    } else {
      hierarchySearchString = hierarchy + "%";
    }
    String sql = getSQLForRetriveEntityAccessFor(firstEntityType, accessType, secondEntityType);

    Collection<MifosEntityAccessData> entityAccessData = null;
    MifosEntityAccessDataMapper mapper = new MifosEntityAccessDataMapper();

    if (includeAllSubOffices && (firstEntityType.getTable().equals("m_office"))) {
      sql += " where firstentity.hierarchy like ? order by firstEntity.hierarchy";
      entityAccessData =
          this.jdbcTemplate.query(sql, mapper, new Object[] {firstEntityId, hierarchySearchString});
    } else {
      entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] {firstEntityId});
    }

    return entityAccessData;
  }
 private String getSQLForRetriveEntityAccessFor(
     MifosEntityType firstEntityType,
     MifosEntityAccessType accessType,
     MifosEntityType secondEntityType) {
   StringBuffer str =
       new StringBuffer("select eea.entity_id as entity_id, entity_type as entity_type, ");
   str.append(
       "access_type_code_value_id as access_id, cv.code_value as access_type_desc, c.code_name as code, ");
   str.append("firstentity.id as first_entity_id, firstentity.name as entity_name, ");
   str.append("otherentity.id as second_entity_id, otherentity.name as second_entity_name, ");
   str.append("eea.second_entity_type as second_entity_type ");
   str.append("from m_entity_to_entity_access eea ");
   str.append("left join m_code_value cv on (cv.code_value = ");
   str.append("'");
   str.append(accessType.toStr());
   str.append("' ");
   str.append("and eea.access_type_code_value_id = cv.id) ");
   str.append("left join m_code c on (c.code_name = '");
   str.append(MifosEntityAccessConstants.ENTITY_ACCESS_CODENAME);
   str.append("' and cv.code_id = c.id) ");
   str.append("left join ");
   str.append(firstEntityType.getTable());
   str.append(" firstentity on (eea.entity_type = ");
   str.append("'");
   str.append(firstEntityType.getType());
   str.append("'");
   str.append(" and eea.entity_id = firstentity.id)        left join ");
   str.append(secondEntityType.getTable());
   str.append(" otherentity on (eea.second_entity_type = ");
   str.append("'");
   str.append(secondEntityType.getType());
   str.append("' ");
   str.append("and eea.second_entity_id = otherentity.id) ");
   str.append("where eea.access_type_code_value_id = cv.id ");
   str.append("and eea.entity_id = ? ");
   logger.debug(str.toString());
   return str.toString();
 }