wip mifosx-195 refactor list reports api for maintenance function use and change api-docs

This commit is contained in:
John Woodlock
2013-04-13 19:33:43 +01:00
parent 9cc6abd6c4
commit e777491d76
7 changed files with 836 additions and 1145 deletions
+61 -747
View File
@@ -10254,19 +10254,6 @@ No Request Body:
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h3>Reports</h3> <h3>Reports</h3>
<p>The reports resource allows you to run and receive output
from pre-defined Mifos X reports. The default output is a JSON
formatted "Generic Resultset". The Generic Resultset contains
Column Heading as well as Data information. However, you can
export to CSV format by simply adding "&exportCSV=true" to the end
of your URL.</p>
<p>If Pentaho reports have been pre-defined, they can also be
run through this resource. Pentaho reports can return HTML, PDF or
CSV formats.</p>
<p>The Mifos X Individual Lending client application uses a
JQuery plugin called stretchyreporting which, itself, uses this
reports resource to provide a pretty flexible reporting User
Interface (UI).</p>
</div> </div>
</div> </div>
@@ -10276,752 +10263,66 @@ No Request Body:
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>List Reports</h4> <h4>List Reports</h4>
<p>Lists all reports and their parameters. If a report has more <p>Lists all reports and their parameters. </p>
than one parameter it will be listed the same number of times as
it has parameters.</p>
<h5>Arguments</h5> <p>Example Request:</p>
<dl class="argument-list">
<dt>exportCSV</dt>
<dd>
optional, <span>The only valid value is 'true'. If any
other value is provided the argument will be ignored</span>
</dd>
<dd>Output will be delivered as a CSV file instead of JSON.</dd>
</dl>
<p>Example Requests:</p>
<div class=apiClick>reports</div> <div class=apiClick>reports</div>
<br>
<br>
<div class=apiClick>reports?exportCSV=true</div>
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration"> <code class="method-declaration">
GET https://DomainName/api/v1/reports GET https://DomainName/api/v1/reports
</code> </code>
<code class="method-response"> <code class="method-response">
[
{ {
"columnHeaders": [ "reportId": 1,
"reportName": "Client Listing",
"reportType": "Table",
"reportCategory": "Client",
"coreReport": true,
"useReport": true,
"reportParameters": [
{ {
"columnName": "report_id", "reportParameterId": 5,
"columnType": "INT", "parameterName": "OfficeIdSelectOne"
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "report_name",
"columnType": "VARCHAR",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "report_type",
"columnType": "VARCHAR",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "report_subtype",
"columnType": "VARCHAR",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "report_category",
"columnType": "VARCHAR",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "parameter_id",
"columnType": "INT",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "report_parameter_name",
"columnType": "VARCHAR",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
},
{
"columnName": "parameter_name",
"columnType": "VARCHAR",
"isColumnNullable": false,
"isColumnPrimaryKey": false,
"columnValues": []
}
],
"data": [
{
"row": [
"10",
"Active Loans Portfolio Status",
"Table",
null,
"Loan",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"10",
"Active Loans Portfolio Status",
"Table",
null,
"Loan",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"10",
"Active Loans Portfolio Status",
"Table",
null,
"Loan",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"10",
"Active Loans Portfolio Status",
"Table",
null,
"Loan",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"10",
"Active Loans Portfolio Status",
"Table",
null,
"Loan",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"11",
"Active Loans Summary per Branch",
"Table",
null,
"Loan Portfolio",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"11",
"Active Loans Summary per Branch",
"Table",
null,
"Loan Portfolio",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"48",
"Balance Sheet",
"Pentaho",
null,
"Accounting",
"5",
"branch",
"OfficeIdSelectOne"
]
},
{
"row": [
"48",
"Balance Sheet",
"Pentaho",
null,
"Accounting",
"41",
"date",
"endDateSelect"
]
},
{
"row": [
"1",
"Client Listing",
"Table",
null,
"Client",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"2",
"Client Loans Listing",
"Table",
null,
"Client",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"2",
"Client Loans Listing",
"Table",
null,
"Client",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"2",
"Client Loans Listing",
"Table",
null,
"Client",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"2",
"Client Loans Listing",
"Table",
null,
"Client",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"2",
"Client Loans Listing",
"Table",
null,
"Client",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"20",
"Funds Disbursed Between Dates Summary",
"Table",
null,
"Fund",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"20",
"Funds Disbursed Between Dates Summary",
"Table",
null,
"Fund",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"20",
"Funds Disbursed Between Dates Summary",
"Table",
null,
"Fund",
"40",
null,
"startDateSelect"
]
},
{
"row": [
"20",
"Funds Disbursed Between Dates Summary",
"Table",
null,
"Fund",
"41",
null,
"endDateSelect"
]
},
{
"row": [
"21",
"Funds Disbursed Between Dates Summary by Office",
"Table",
null,
"Fund",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"21",
"Funds Disbursed Between Dates Summary by Office",
"Table",
null,
"Fund",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"21",
"Funds Disbursed Between Dates Summary by Office",
"Table",
null,
"Fund",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"21",
"Funds Disbursed Between Dates Summary by Office",
"Table",
null,
"Fund",
"40",
null,
"startDateSelect"
]
},
{
"row": [
"21",
"Funds Disbursed Between Dates Summary by Office",
"Table",
null,
"Fund",
"41",
null,
"endDateSelect"
]
},
{
"row": [
"49",
"Income Statement",
"Pentaho",
null,
"Accounting",
"5",
"branch",
"OfficeIdSelectOne"
]
},
{
"row": [
"49",
"Income Statement",
"Pentaho",
null,
"Accounting",
"40",
"fromDate",
"startDateSelect"
]
},
{
"row": [
"49",
"Income Statement",
"Pentaho",
null,
"Accounting",
"41",
"toDate",
"endDateSelect"
]
},
{
"row": [
"5",
"Loans Awaiting Disbursal",
"Table",
null,
"Loan Portfolio",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"5",
"Loans Awaiting Disbursal",
"Table",
null,
"Loan Portfolio",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"5",
"Loans Awaiting Disbursal",
"Table",
null,
"Loan Portfolio",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"5",
"Loans Awaiting Disbursal",
"Table",
null,
"Loan Portfolio",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"5",
"Loans Awaiting Disbursal",
"Table",
null,
"Loan Portfolio",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"6",
"Loans Awaiting Disbursal Summary",
"Table",
null,
"Loan Portfolio",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"6",
"Loans Awaiting Disbursal Summary",
"Table",
null,
"Loan Portfolio",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"6",
"Loans Awaiting Disbursal Summary",
"Table",
null,
"Loan Portfolio",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"6",
"Loans Awaiting Disbursal Summary",
"Table",
null,
"Loan Portfolio",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"6",
"Loans Awaiting Disbursal Summary",
"Table",
null,
"Loan Portfolio",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"7",
"Loans Awaiting Disbursal Summary by Month",
"Table",
null,
"Loan Portfolio",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"7",
"Loans Awaiting Disbursal Summary by Month",
"Table",
null,
"Loan Portfolio",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"7",
"Loans Awaiting Disbursal Summary by Month",
"Table",
null,
"Loan Portfolio",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"7",
"Loans Awaiting Disbursal Summary by Month",
"Table",
null,
"Loan Portfolio",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"7",
"Loans Awaiting Disbursal Summary by Month",
"Table",
null,
"Loan Portfolio",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"15",
"Portfolio at Risk",
"Table",
null,
"Loan Portfolio",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"15",
"Portfolio at Risk",
"Table",
null,
"Loan Portfolio",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"15",
"Portfolio at Risk",
"Table",
null,
"Loan Portfolio",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"15",
"Portfolio at Risk",
"Table",
null,
"Loan Portfolio",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"15",
"Portfolio at Risk",
"Table",
null,
"Loan Portfolio",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"16",
"Portfolio at Risk by Branch",
"Table",
null,
"Loan Portfolio",
"5",
null,
"OfficeIdSelectOne"
]
},
{
"row": [
"16",
"Portfolio at Risk by Branch",
"Table",
null,
"Loan Portfolio",
"6",
null,
"loanOfficerIdSelectAll"
]
},
{
"row": [
"16",
"Portfolio at Risk by Branch",
"Table",
null,
"Loan Portfolio",
"10",
null,
"currencyIdSelectAll"
]
},
{
"row": [
"16",
"Portfolio at Risk by Branch",
"Table",
null,
"Loan Portfolio",
"20",
null,
"fundIdSelectAll"
]
},
{
"row": [
"16",
"Portfolio at Risk by Branch",
"Table",
null,
"Loan Portfolio",
"25",
null,
"loanProductIdSelectAll"
]
},
{
"row": [
"50",
"Trial Balance",
"Pentaho",
null,
"Accounting",
"5",
"branch",
"OfficeIdSelectOne"
]
},
{
"row": [
"50",
"Trial Balance",
"Pentaho",
null,
"Accounting",
"40",
"fromDate",
"startDateSelect"
]
},
{
"row": [
"50",
"Trial Balance",
"Pentaho",
null,
"Accounting",
"41",
"toDate",
"endDateSelect"
]
} }
] ]
},
{
"reportId": 2,
"reportName": "Client Loans Listing",
"reportType": "Table",
"reportCategory": "Client",
"coreReport": true,
"useReport": true,
"reportParameters": [
{
"reportParameterId": 5,
"parameterName": "OfficeIdSelectOne"
},
{
"reportParameterId": 6,
"parameterName": "loanOfficerIdSelectAll"
},
{
"reportParameterId": 10,
"parameterName": "currencyIdSelectAll"
},
{
"reportParameterId": 20,
"parameterName": "fundIdSelectAll"
},
{
"reportParameterId": 25,
"parameterName": "loanProductIdSelectAll"
},
{
"reportParameterId": 26,
"parameterName": "loanPurposeIdSelectAll"
} }
]
},...
]
</code> </code>
</div> </div>
</div> </div>
@@ -11030,7 +10331,20 @@ GET https://DomainName/api/v1/reports
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Running a Report</h4> <h4>Running a Report</h4>
<p>Runs a report and returns the report output.</p> <p>This resource allows you to run and receive output from pre-defined Mifos X reports. </p>
<p>Reports can also be used to provide data for searching and workflow functionality.</p>
<p>
The default output is a JSON formatted "Generic Resultset". The Generic Resultset contains
Column Heading as well as Data information. However, you can
export to CSV format by simply adding "&exportCSV=true" to the end
of your URL.</p>
<p>If Pentaho reports have been pre-defined, they can also be
run through this resource. Pentaho reports can return HTML, PDF or
CSV formats.</p>
<p>The Mifos X reference application uses a
JQuery plugin called stretchyreporting which, itself, uses this
reports resource to provide a pretty flexible reporting User
Interface (UI).</p>
<h5>Arguments</h5> <h5>Arguments</h5>
<dl class="argument-list"> <dl class="argument-list">
<dt>R_'parameter names' ...</dt> <dt>R_'parameter names' ...</dt>
@@ -6,6 +6,7 @@
package org.mifosplatform.infrastructure.dataqueries.api; package org.mifosplatform.infrastructure.dataqueries.api;
import java.io.File; import java.io.File;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -26,6 +27,7 @@ import javax.ws.rs.core.UriInfo;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
import org.mifosplatform.infrastructure.dataqueries.data.ReportData;
import org.mifosplatform.infrastructure.dataqueries.service.GenericDataService; import org.mifosplatform.infrastructure.dataqueries.service.GenericDataService;
import org.mifosplatform.infrastructure.dataqueries.service.ReadReportingService; import org.mifosplatform.infrastructure.dataqueries.service.ReadReportingService;
import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException; import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException;
@@ -56,34 +58,18 @@ public class ReportsApiResource {
@GET @GET
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON, "application/x-msdownload" }) @Produces({ MediaType.APPLICATION_JSON })
public Response retrieveReportList(@Context final UriInfo uriInfo) { public Response retrieveReportList(@Context final UriInfo uriInfo) {
Map<String, String> extractedQueryParams = new HashMap<String, String>();
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
boolean exportCsv = ApiParameterHelper.exportCsv(uriInfo.getQueryParameters());
boolean exportPdf = ApiParameterHelper.exportPdf(uriInfo.getQueryParameters());
if (exportPdf) {
String result = this.readExtraDataAndReportingService.retrieveReportPDF(".", ".", extractedQueryParams);
return Response.ok().entity(result).header("Content-Disposition", "attachment;filename=ReportList.pdf").build();
}
if (!exportCsv) {
GenericResultsetData result = this.readExtraDataAndReportingService.retrieveGenericResultset(".", ".", extractedQueryParams);
final Collection<ReportData> result = this.readExtraDataAndReportingService.retrieveReportList();
final String json = this.toApiJsonSerializer.serializePretty(prettyPrint, result); final String json = this.toApiJsonSerializer.serializePretty(prettyPrint, result);
return Response.ok().entity(json).build(); return Response.ok().entity(json).build();
} }
StreamingOutput result = this.readExtraDataAndReportingService.retrieveReportCSV(".", ".", extractedQueryParams);
return Response.ok().entity(result).header("Content-Disposition", "attachment;filename=ReportList.csv").build();
}
@GET @GET
@Path("{reportName}") @Path("{reportName}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@@ -0,0 +1,47 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.dataqueries.data;
import java.util.Collection;
final public class ReportData {
@SuppressWarnings("unused")
private final Long reportId;
@SuppressWarnings("unused")
private final String reportName;
@SuppressWarnings("unused")
private final String reportType;
@SuppressWarnings("unused")
private final String reportSubType;
@SuppressWarnings("unused")
private final String reportCategory;
@SuppressWarnings("unused")
private final String reportSql;
@SuppressWarnings("unused")
private final Boolean coreReport;
@SuppressWarnings("unused")
private final Boolean useReport;
@SuppressWarnings("unused")
private final Collection<ReportParameterData> reportParameters;
public ReportData(final Long reportId, final String reportName,
final String reportType, final String reportSubType,
final String reportCategory, final String reportSql,
final Boolean coreReport, final Boolean useReport,
final Collection<ReportParameterData> reportParameters) {
this.reportId = reportId;
this.reportName = reportName;
this.reportType = reportType;
this.reportSubType = reportSubType;
this.reportCategory = reportCategory;
this.reportParameters = reportParameters;
this.reportSql = reportSql;
this.coreReport = coreReport;
this.useReport = useReport;
}
}
@@ -0,0 +1,24 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.dataqueries.data;
final public class ReportParameterData {
@SuppressWarnings("unused")
private final Long reportParameterId;
@SuppressWarnings("unused")
private final String reportParameterName;
@SuppressWarnings("unused")
private final String parameterName;
public ReportParameterData(final Long reportParameterId,
final String reportParameterName, final String parameterName) {
this.reportParameterId = reportParameterId;
this.reportParameterName = reportParameterName;
this.parameterName = parameterName;
}
}
@@ -0,0 +1,86 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.dataqueries.data;
final public class ReportParameterJoinData {
private final Long reportId;
private final String reportName;
private final String reportType;
private final String reportSubType;
private final String reportCategory;
private final String reportSql;
private final Boolean coreReport;
private final Boolean useReport;
private final Long reportParameterId;
private final String reportParameterName;
private final String parameterName;
public ReportParameterJoinData(final Long reportId,
final String reportName, final String reportType,
final String reportSubType, final String reportCategory,
final String reportSql, final Boolean coreReport,
final Boolean useReport, final Long reportParameterId,
final String reportParameterName, final String parameterName) {
this.reportId = reportId;
this.reportName = reportName;
this.reportType = reportType;
this.reportSubType = reportSubType;
this.reportCategory = reportCategory;
this.reportSql = reportSql;
this.coreReport = coreReport;
this.useReport = useReport;
this.reportParameterId = reportParameterId;
this.reportParameterName = reportParameterName;
this.parameterName = parameterName;
}
public Long getReportId() {
return reportId;
}
public String getReportName() {
return reportName;
}
public String getReportType() {
return reportType;
}
public String getReportSubType() {
return reportSubType;
}
public String getReportCategory() {
return reportCategory;
}
public String getReportSql() {
return reportSql;
}
public Boolean getCoreReport() {
return coreReport;
}
public Boolean getUseReport() {
return useReport;
}
public Long getReportParameterId() {
return reportParameterId;
}
public String getReportParameterName() {
return reportParameterName;
}
public String getParameterName() {
return parameterName;
}
}
@@ -5,22 +5,30 @@
*/ */
package org.mifosplatform.infrastructure.dataqueries.service; package org.mifosplatform.infrastructure.dataqueries.service;
import java.util.Collection;
import java.util.Map; import java.util.Map;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput; import javax.ws.rs.core.StreamingOutput;
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
import org.mifosplatform.infrastructure.dataqueries.data.ReportData;
public interface ReadReportingService { public interface ReadReportingService {
StreamingOutput retrieveReportCSV(String name, String type, Map<String, String> extractedQueryParams); StreamingOutput retrieveReportCSV(String name, String type,
Map<String, String> extractedQueryParams);
GenericResultsetData retrieveGenericResultset(String name, String type, Map<String, String> extractedQueryParams); GenericResultsetData retrieveGenericResultset(String name, String type,
Map<String, String> extractedQueryParams);
Response processPentahoRequest(String reportName, String outputType, Map<String, String> queryParams); Response processPentahoRequest(String reportName, String outputType,
Map<String, String> queryParams);
String retrieveReportPDF(String name, String type, Map<String, String> extractedQueryParams); String retrieveReportPDF(String name, String type,
Map<String, String> extractedQueryParams);
String getReportType(String reportName); String getReportType(String reportName);
Collection<ReportData> retrieveReportList();
} }
@@ -13,6 +13,10 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.sql.Date; import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -22,10 +26,14 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput; import javax.ws.rs.core.StreamingOutput;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.core.service.FileUtils; import org.mifosplatform.infrastructure.core.service.FileUtils;
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData; import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
import org.mifosplatform.infrastructure.dataqueries.data.ReportData;
import org.mifosplatform.infrastructure.dataqueries.data.ReportParameterData;
import org.mifosplatform.infrastructure.dataqueries.data.ReportParameterJoinData;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeaderData; import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetRowData; import org.mifosplatform.infrastructure.dataqueries.data.ResultsetRowData;
import org.mifosplatform.infrastructure.dataqueries.exception.ReportNotFoundException; import org.mifosplatform.infrastructure.dataqueries.exception.ReportNotFoundException;
@@ -48,6 +56,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -59,7 +68,8 @@ import com.lowagie.text.pdf.PdfWriter;
@Service @Service
public class ReadReportingServiceImpl implements ReadReportingService { public class ReadReportingServiceImpl implements ReadReportingService {
private final static Logger logger = LoggerFactory.getLogger(ReadReportingServiceImpl.class); private final static Logger logger = LoggerFactory
.getLogger(ReadReportingServiceImpl.class);
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final DataSource dataSource; private final DataSource dataSource;
@@ -68,7 +78,8 @@ public class ReadReportingServiceImpl implements ReadReportingService {
private boolean noPentaho = false; private boolean noPentaho = false;
@Autowired @Autowired
public ReadReportingServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, public ReadReportingServiceImpl(final PlatformSecurityContext context,
final TenantAwareRoutingDataSource dataSource,
final GenericDataService genericDataService) { final GenericDataService genericDataService) {
// kick off pentaho reports server // kick off pentaho reports server
ClassicEngineBoot.getInstance().start(); ClassicEngineBoot.getInstance().start();
@@ -81,7 +92,8 @@ public class ReadReportingServiceImpl implements ReadReportingService {
} }
@Override @Override
public StreamingOutput retrieveReportCSV(final String name, final String type, final Map<String, String> queryParams) { public StreamingOutput retrieveReportCSV(final String name,
final String type, final Map<String, String> queryParams) {
return new StreamingOutput() { return new StreamingOutput() {
@@ -89,10 +101,12 @@ public class ReadReportingServiceImpl implements ReadReportingService {
public void write(final OutputStream out) { public void write(final OutputStream out) {
try { try {
GenericResultsetData result = retrieveGenericResultset(name, type, queryParams); GenericResultsetData result = retrieveGenericResultset(
name, type, queryParams);
StringBuffer sb = generateCsvFileBuffer(result); StringBuffer sb = generateCsvFileBuffer(result);
InputStream in = new ByteArrayInputStream(sb.toString().getBytes("UTF-8")); InputStream in = new ByteArrayInputStream(sb.toString()
.getBytes("UTF-8"));
byte[] outputByte = new byte[4096]; byte[] outputByte = new byte[4096];
Integer readLen = in.read(outputByte, 0, 4096); Integer readLen = in.read(outputByte, 0, 4096);
@@ -105,7 +119,8 @@ public class ReadReportingServiceImpl implements ReadReportingService {
// out.flush(); // out.flush();
// out.close(); // out.close();
} catch (Exception e) { } catch (Exception e) {
throw new PlatformDataIntegrityException("error.msg.exception.error", e.getMessage()); throw new PlatformDataIntegrityException(
"error.msg.exception.error", e.getMessage());
} }
} }
}; };
@@ -115,12 +130,14 @@ public class ReadReportingServiceImpl implements ReadReportingService {
private StringBuffer generateCsvFileBuffer(final GenericResultsetData result) { private StringBuffer generateCsvFileBuffer(final GenericResultsetData result) {
StringBuffer writer = new StringBuffer(); StringBuffer writer = new StringBuffer();
List<ResultsetColumnHeaderData> columnHeaders = result.getColumnHeaders(); List<ResultsetColumnHeaderData> columnHeaders = result
.getColumnHeaders();
logger.info("NO. of Columns: " + columnHeaders.size()); logger.info("NO. of Columns: " + columnHeaders.size());
Integer chSize = columnHeaders.size(); Integer chSize = columnHeaders.size();
for (int i = 0; i < chSize; i++) { for (int i = 0; i < chSize; i++) {
writer.append('"' + columnHeaders.get(i).getColumnName() + '"'); writer.append('"' + columnHeaders.get(i).getColumnName() + '"');
if (i < (chSize - 1)) writer.append(","); if (i < (chSize - 1))
writer.append(",");
} }
writer.append('\n'); writer.append('\n');
@@ -141,14 +158,19 @@ public class ReadReportingServiceImpl implements ReadReportingService {
currColType = columnHeaders.get(j).getColumnType(); currColType = columnHeaders.get(j).getColumnType();
currVal = row.get(j); currVal = row.get(j);
if (currVal != null) { if (currVal != null) {
if (currColType.equals("DECIMAL") || currColType.equals("DOUBLE") || currColType.equals("BIGINT") if (currColType.equals("DECIMAL")
|| currColType.equals("SMALLINT") || currColType.equals("INT")) || currColType.equals("DOUBLE")
|| currColType.equals("BIGINT")
|| currColType.equals("SMALLINT")
|| currColType.equals("INT"))
writer.append(currVal); writer.append(currVal);
else else
writer.append('"' + genericDataService.replace(currVal, doubleQuote, twoDoubleQuotes) + '"'); writer.append('"' + genericDataService.replace(currVal,
doubleQuote, twoDoubleQuotes) + '"');
} }
if (j < (rSize - 1)) writer.append(","); if (j < (rSize - 1))
writer.append(",");
} }
writer.append('\n'); writer.append('\n');
} }
@@ -157,7 +179,8 @@ public class ReadReportingServiceImpl implements ReadReportingService {
} }
@Override @Override
public GenericResultsetData retrieveGenericResultset(final String name, final String type, final Map<String, String> queryParams) { public GenericResultsetData retrieveGenericResultset(final String name,
final String type, final Map<String, String> queryParams) {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
logger.info("STARTING REPORT: " + name + " Type: " + type); logger.info("STARTING REPORT: " + name + " Type: " + type);
@@ -169,26 +192,35 @@ public class ReadReportingServiceImpl implements ReadReportingService {
// need to provide an api that does bring back 'permitted' reports // need to provide an api that does bring back 'permitted' reports
// PERMITTED REPORTS SQL // PERMITTED REPORTS SQL
sql = "select r.report_id, r.report_name, r.report_type, r.report_subtype, r.report_category," sql = "select r.report_id, r.report_name, r.report_type, r.report_subtype, r.report_category,"
+ " rp.parameter_id, rp.report_parameter_name, p.parameter_name" + " from stretchy_report r" + " rp.parameter_id, rp.report_parameter_name, p.parameter_name"
+ " from stretchy_report r"
+ " left join stretchy_report_parameter rp on rp.report_id = r.report_id" + " left join stretchy_report_parameter rp on rp.report_id = r.report_id"
+ " left join stretchy_parameter p on p.parameter_id = rp.parameter_id" + " where exists" + " (select 'f'" + " left join stretchy_parameter p on p.parameter_id = rp.parameter_id"
+ " from m_appuser_role ur " + " join m_role r on r.id = ur.role_id" + " where exists"
+ " left join m_role_permission rp on rp.role_id = r.id" + " left join m_permission p on p.id = rp.permission_id" + " (select 'f'"
+ " where ur.appuser_id = " + context.authenticatedUser().getId() + " from m_appuser_role ur "
+ " join m_role r on r.id = ur.role_id"
+ " left join m_role_permission rp on rp.role_id = r.id"
+ " left join m_permission p on p.id = rp.permission_id"
+ " where ur.appuser_id = "
+ context.authenticatedUser().getId()
+ " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', r.report_name))) " + " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', r.report_name))) "
+ " order by r.report_name, rp.parameter_id"; + " order by r.report_name, rp.parameter_id";
} else { } else {
sql = getSQLtoRun(name, type, queryParams); sql = getSQLtoRun(name, type, queryParams);
} }
GenericResultsetData result = genericDataService.fillGenericResultSet(sql); GenericResultsetData result = genericDataService
.fillGenericResultSet(sql);
long elapsed = System.currentTimeMillis() - startTime; long elapsed = System.currentTimeMillis() - startTime;
logger.info("FINISHING Report/Request Name: " + name + " - " + type + " Elapsed Time: " + elapsed); logger.info("FINISHING Report/Request Name: " + name + " - " + type
+ " Elapsed Time: " + elapsed);
return result; return result;
} }
private String getSQLtoRun(final String name, final String type, final Map<String, String> queryParams) { private String getSQLtoRun(final String name, final String type,
final Map<String, String> queryParams) {
String sql = getSql(name, type); String sql = getSql(name, type);
@@ -201,11 +233,13 @@ public class ReadReportingServiceImpl implements ReadReportingService {
AppUser currentUser = context.authenticatedUser(); AppUser currentUser = context.authenticatedUser();
// Allows sql query to restrict data by office hierarchy if required // Allows sql query to restrict data by office hierarchy if required
sql = genericDataService.replace(sql, "${currentUserHierarchy}", currentUser.getOffice().getHierarchy()); sql = genericDataService.replace(sql, "${currentUserHierarchy}",
currentUser.getOffice().getHierarchy());
// Allows sql query to restrict data by current user Id if required // Allows sql query to restrict data by current user Id if required
// (typically used to return report lists containing only reports // (typically used to return report lists containing only reports
// permitted to be run by the user // permitted to be run by the user
sql = genericDataService.replace(sql, "${currentUserId}", currentUser.getId().toString()); sql = genericDataService.replace(sql, "${currentUserId}", currentUser
.getId().toString());
sql = genericDataService.wrapSQL(sql); sql = genericDataService.wrapSQL(sql);
@@ -215,52 +249,58 @@ public class ReadReportingServiceImpl implements ReadReportingService {
private String getSql(final String name, final String type) { private String getSql(final String name, final String type) {
final String inputSql = "select " + type + "_sql as the_sql from stretchy_" + type + " where " + type + "_name = '" + name + "'"; final String inputSql = "select " + type
+ "_sql as the_sql from stretchy_" + type + " where " + type
+ "_name = '" + name + "'";
final String inputSqlWrapped = genericDataService.wrapSQL(inputSql); final String inputSqlWrapped = genericDataService.wrapSQL(inputSql);
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(inputSqlWrapped); final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(inputSqlWrapped);
if (rs.next()) { return rs.getString("the_sql"); } if (rs.next()) {
return rs.getString("the_sql");
}
throw new ReportNotFoundException(inputSql); throw new ReportNotFoundException(inputSql);
} }
@Override @Override
public String getReportType(final String reportName) { public String getReportType(final String reportName) {
final String sql = "SELECT ifnull(report_type,'') as report_type FROM `stretchy_report` where report_name = '" + reportName + "'"; final String sql = "SELECT ifnull(report_type,'') as report_type FROM `stretchy_report` where report_name = '"
+ reportName + "'";
final String sqlWrapped = genericDataService.wrapSQL(sql); final String sqlWrapped = genericDataService.wrapSQL(sql);
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(sqlWrapped); final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(sqlWrapped);
if (rs.next()) { return rs.getString("report_type"); } if (rs.next()) {
return rs.getString("report_type");
}
throw new ReportNotFoundException(sql); throw new ReportNotFoundException(sql);
} }
@Override @Override
public Response processPentahoRequest(final String reportName, final String outputTypeParam, final Map<String, String> queryParams) { public Response processPentahoRequest(final String reportName,
final String outputTypeParam, final Map<String, String> queryParams) {
String outputType = "HTML"; String outputType = "HTML";
if (StringUtils.isNotBlank(outputTypeParam)) outputType = outputTypeParam; if (StringUtils.isNotBlank(outputTypeParam))
outputType = outputTypeParam;
if (!(outputType.equalsIgnoreCase("HTML") || outputType.equalsIgnoreCase("PDF") || outputType.equalsIgnoreCase("XLS") || outputType if (!(outputType.equalsIgnoreCase("HTML")
|| outputType.equalsIgnoreCase("PDF")
|| outputType.equalsIgnoreCase("XLS") || outputType
.equalsIgnoreCase("CSV"))) .equalsIgnoreCase("CSV")))
throw new PlatformDataIntegrityException("error.msg.invalid.outputType", "No matching Output Type: " + outputType); throw new PlatformDataIntegrityException(
"error.msg.invalid.outputType", "No matching Output Type: "
+ outputType);
if (noPentaho) { throw new PlatformDataIntegrityException("error.msg.no.pentaho", "Pentaho is not enabled", if (noPentaho) {
"Pentaho is not enabled"); } throw new PlatformDataIntegrityException("error.msg.no.pentaho",
"Pentaho is not enabled", "Pentaho is not enabled");
}
// TODO - JW - use pentaho location finder like Pawel does in Mifos final String reportPath = FileUtils.MIFOSX_BASE_DIR + File.separator
// String reportPath = + "pentahoReports" + File.separator + reportName + ".prpt";
// "C:\\dev\\apache-tomcat-7.0.25\\webapps\\ROOT\\PentahoReports\\"
// + reportName + ".prpt";
/*
* String reportPath = FileUtils.MIFOSX_BASE_DIR + File.separator +
* ThreadLocalContextUtil.getTenant().getName() .replaceAll(" ",
* "").trim() + File.separator + "reports" + File.separator + reportName
* + ".prpt";
*/
final String reportPath = FileUtils.MIFOSX_BASE_DIR + File.separator + "pentahoReports" + File.separator + reportName + ".prpt";
logger.info("Report path: " + reportPath); logger.info("Report path: " + reportPath);
// load report definition // load report definition
@@ -278,44 +318,65 @@ public class ReadReportingServiceImpl implements ReadReportingService {
if ("PDF".equalsIgnoreCase(outputType)) { if ("PDF".equalsIgnoreCase(outputType)) {
PdfReportUtil.createPDF(masterReport, baos); PdfReportUtil.createPDF(masterReport, baos);
return Response.ok().entity(baos.toByteArray()).type("application/pdf").build(); return Response.ok().entity(baos.toByteArray())
.type("application/pdf").build();
} }
if ("XLS".equalsIgnoreCase(outputType)) { if ("XLS".equalsIgnoreCase(outputType)) {
ExcelReportUtil.createXLS(masterReport, baos); ExcelReportUtil.createXLS(masterReport, baos);
return Response.ok().entity(baos.toByteArray()).type("application/vnd.ms-excel") return Response
.header("Content-Disposition", "attachment;filename=" + reportName.replaceAll(" ", "") + ".xls").build(); .ok()
.entity(baos.toByteArray())
.type("application/vnd.ms-excel")
.header("Content-Disposition",
"attachment;filename="
+ reportName.replaceAll(" ", "")
+ ".xls").build();
} }
if ("CSV".equalsIgnoreCase(outputType)) { if ("CSV".equalsIgnoreCase(outputType)) {
CSVReportUtil.createCSV(masterReport, baos, "UTF-8"); CSVReportUtil.createCSV(masterReport, baos, "UTF-8");
return Response.ok().entity(baos.toByteArray()).type("application/x-msdownload") return Response
.header("Content-Disposition", "attachment;filename=" + reportName.replaceAll(" ", "") + ".csv").build(); .ok()
.entity(baos.toByteArray())
.type("application/x-msdownload")
.header("Content-Disposition",
"attachment;filename="
+ reportName.replaceAll(" ", "")
+ ".csv").build();
} }
if ("HTML".equalsIgnoreCase(outputType)) { if ("HTML".equalsIgnoreCase(outputType)) {
HtmlReportUtil.createStreamHTML(masterReport, baos); HtmlReportUtil.createStreamHTML(masterReport, baos);
return Response.ok().entity(baos.toByteArray()).type("text/html").build(); return Response.ok().entity(baos.toByteArray())
.type("text/html").build();
} }
} catch (ResourceException e) { } catch (ResourceException e) {
throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage()); throw new PlatformDataIntegrityException(
"error.msg.reporting.error", e.getMessage());
} catch (ReportProcessingException e) { } catch (ReportProcessingException e) {
throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage()); throw new PlatformDataIntegrityException(
"error.msg.reporting.error", e.getMessage());
} catch (IOException e) { } catch (IOException e) {
throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage()); throw new PlatformDataIntegrityException(
"error.msg.reporting.error", e.getMessage());
} }
throw new PlatformDataIntegrityException("error.msg.invalid.outputType", "No matching Output Type: " + outputType); throw new PlatformDataIntegrityException(
"error.msg.invalid.outputType", "No matching Output Type: "
+ outputType);
} }
private void addParametersToReport(final MasterReport report, final Map<String, String> queryParams) { private void addParametersToReport(final MasterReport report,
final Map<String, String> queryParams) {
AppUser currentUser = context.authenticatedUser(); AppUser currentUser = context.authenticatedUser();
try { try {
ReportParameterValues rptParamValues = report.getParameterValues(); ReportParameterValues rptParamValues = report.getParameterValues();
ReportParameterDefinition paramsDefinition = report.getParameterDefinition(); ReportParameterDefinition paramsDefinition = report
.getParameterDefinition();
/* /*
* only allow integer, long, date and string parameter types and * only allow integer, long, date and string parameter types and
@@ -324,22 +385,30 @@ public class ReadReportingServiceImpl implements ReadReportingService {
* better... currently assuming they come in ok... and if not an * better... currently assuming they come in ok... and if not an
* error * error
*/ */
for (ParameterDefinitionEntry paramDefEntry : paramsDefinition.getParameterDefinitions()) { for (ParameterDefinitionEntry paramDefEntry : paramsDefinition
.getParameterDefinitions()) {
String paramName = paramDefEntry.getName(); String paramName = paramDefEntry.getName();
if (!((paramName.equals("tenantdb")) || (paramName.equals("userhierarchy")))) { if (!((paramName.equals("tenantdb")) || (paramName
.equals("userhierarchy")))) {
logger.info("paramName:" + paramName); logger.info("paramName:" + paramName);
String pValue = queryParams.get(paramName); String pValue = queryParams.get(paramName);
if (StringUtils.isBlank(pValue)) if (StringUtils.isBlank(pValue))
throw new PlatformDataIntegrityException("error.msg.reporting.error", "Pentaho Parameter: " + paramName throw new PlatformDataIntegrityException(
"error.msg.reporting.error",
"Pentaho Parameter: " + paramName
+ " - not Provided"); + " - not Provided");
Class<?> clazz = paramDefEntry.getValueType(); Class<?> clazz = paramDefEntry.getValueType();
logger.info("addParametersToReport(" + paramName + " : " + pValue + " : " + clazz.getCanonicalName() + ")"); logger.info("addParametersToReport(" + paramName + " : "
if (clazz.getCanonicalName().equalsIgnoreCase("java.lang.Integer")) + pValue + " : " + clazz.getCanonicalName() + ")");
if (clazz.getCanonicalName().equalsIgnoreCase(
"java.lang.Integer"))
rptParamValues.put(paramName, Integer.parseInt(pValue)); rptParamValues.put(paramName, Integer.parseInt(pValue));
else if (clazz.getCanonicalName().equalsIgnoreCase("java.lang.Long")) else if (clazz.getCanonicalName().equalsIgnoreCase(
"java.lang.Long"))
rptParamValues.put(paramName, Long.parseLong(pValue)); rptParamValues.put(paramName, Long.parseLong(pValue));
else if (clazz.getCanonicalName().equalsIgnoreCase("java.sql.Date")) else if (clazz.getCanonicalName().equalsIgnoreCase(
"java.sql.Date"))
rptParamValues.put(paramName, Date.valueOf(pValue)); rptParamValues.put(paramName, Date.valueOf(pValue));
else else
rptParamValues.put(paramName, pValue); rptParamValues.put(paramName, pValue);
@@ -353,29 +422,35 @@ public class ReadReportingServiceImpl implements ReadReportingService {
// data scoping // data scoping
String tenantdb = dataSource.getConnection().getCatalog(); String tenantdb = dataSource.getConnection().getCatalog();
String userhierarchy = currentUser.getOffice().getHierarchy(); String userhierarchy = currentUser.getOffice().getHierarchy();
logger.info("db name:" + tenantdb + " userhierarchy:" + userhierarchy); logger.info("db name:" + tenantdb + " userhierarchy:"
+ userhierarchy);
rptParamValues.put("tenantdb", tenantdb); rptParamValues.put("tenantdb", tenantdb);
rptParamValues.put("userhierarchy", userhierarchy); rptParamValues.put("userhierarchy", userhierarchy);
} catch (Exception e) { } catch (Exception e) {
logger.error("error.msg.reporting.error:" + e.getMessage()); logger.error("error.msg.reporting.error:" + e.getMessage());
throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage()); throw new PlatformDataIntegrityException(
"error.msg.reporting.error", e.getMessage());
} }
} }
@Override @Override
public String retrieveReportPDF(final String reportName, final String type, final Map<String, String> queryParams) { public String retrieveReportPDF(final String reportName, final String type,
final Map<String, String> queryParams) {
String fileLocation = FileUtils.MIFOSX_BASE_DIR + File.separator + ""; String fileLocation = FileUtils.MIFOSX_BASE_DIR + File.separator + "";
if (!new File(fileLocation).isDirectory()) { if (!new File(fileLocation).isDirectory()) {
new File(fileLocation).mkdirs(); new File(fileLocation).mkdirs();
} }
String genaratePdf = fileLocation + File.separator + reportName + ".pdf"; String genaratePdf = fileLocation + File.separator + reportName
+ ".pdf";
try { try {
GenericResultsetData result = retrieveGenericResultset(reportName, type, queryParams); GenericResultsetData result = retrieveGenericResultset(reportName,
type, queryParams);
List<ResultsetColumnHeaderData> columnHeaders = result.getColumnHeaders(); List<ResultsetColumnHeaderData> columnHeaders = result
.getColumnHeaders();
List<ResultsetRowData> data = result.getData(); List<ResultsetRowData> data = result.getData();
List<String> row; List<String> row;
@@ -384,7 +459,8 @@ public class ReadReportingServiceImpl implements ReadReportingService {
Document document = new Document(PageSize.B0.rotate()); Document document = new Document(PageSize.B0.rotate());
PdfWriter.getInstance(document, new FileOutputStream(new File(fileLocation + reportName + ".pdf"))); PdfWriter.getInstance(document, new FileOutputStream(new File(
fileLocation + reportName + ".pdf")));
document.open(); document.open();
PdfPTable table = new PdfPTable(chSize); PdfPTable table = new PdfPTable(chSize);
@@ -408,8 +484,11 @@ public class ReadReportingServiceImpl implements ReadReportingService {
currColType = columnHeaders.get(j).getColumnType(); currColType = columnHeaders.get(j).getColumnType();
currVal = row.get(j); currVal = row.get(j);
if (currVal != null) { if (currVal != null) {
if (currColType.equals("DECIMAL") || currColType.equals("DOUBLE") || currColType.equals("BIGINT") if (currColType.equals("DECIMAL")
|| currColType.equals("SMALLINT") || currColType.equals("INT")) { || currColType.equals("DOUBLE")
|| currColType.equals("BIGINT")
|| currColType.equals("SMALLINT")
|| currColType.equals("INT")) {
table.addCell(currVal.toString()); table.addCell(currVal.toString());
} else { } else {
@@ -424,7 +503,154 @@ public class ReadReportingServiceImpl implements ReadReportingService {
return genaratePdf; return genaratePdf;
} catch (Exception e) { } catch (Exception e) {
logger.error("error.msg.reporting.error:" + e.getMessage()); logger.error("error.msg.reporting.error:" + e.getMessage());
throw new PlatformDataIntegrityException("error.msg.exception.error", e.getMessage()); throw new PlatformDataIntegrityException(
"error.msg.exception.error", e.getMessage());
} }
} }
@Override
public Collection<ReportData> retrieveReportList() {
ReportParameterJoinMapper rm = new ReportParameterJoinMapper();
String sql = rm.schema(false, context.authenticatedUser().getId());
Collection<ReportParameterJoinData> rpJoins = this.jdbcTemplate.query(
sql, rm, new Object[] {});
Collection<ReportData> reportList = new ArrayList<ReportData>();
if (rpJoins == null)
return reportList;
Collection<ReportParameterData> reportParameters = null;
Long reportId = null;
String reportName = null;
String reportType = null;
String reportSubType = null;
String reportCategory = null;
Boolean coreReport = null;
Boolean useReport = null;
String reportSql = null;
Long prevReportId = (long) -1234;
Boolean firstReport = true;
for (ReportParameterJoinData rpJoin : rpJoins) {
if (rpJoin.getReportId().equals(prevReportId)) {
// more than one parameter for report
reportParameters.add(new ReportParameterData(rpJoin
.getReportParameterId(), rpJoin
.getReportParameterName(), rpJoin.getParameterName()));
} else {
if (firstReport) {
firstReport = false;
}
else
{
// write report entry
reportList
.add(new ReportData(reportId, reportName,
reportType, reportSubType, reportCategory,
reportSql, coreReport, useReport,
reportParameters));
}
prevReportId = rpJoin.getReportId();
reportId = rpJoin.getReportId();
reportName = rpJoin.getReportName();
reportType = rpJoin.getReportType();
reportSubType = rpJoin.getReportSubType();
reportCategory = rpJoin.getReportCategory();
reportSql = rpJoin.getReportSql();
coreReport = rpJoin.getCoreReport();
useReport = rpJoin.getUseReport();
if (rpJoin.getReportParameterId() != null) {
// report has at least one parameter
reportParameters = new ArrayList<ReportParameterData>();
reportParameters.add(new ReportParameterData(rpJoin
.getReportParameterId(), rpJoin
.getReportParameterName(), rpJoin
.getParameterName()));
} else {
reportParameters = null;
}
}
}
// write last report
reportList.add(new ReportData(reportId, reportName, reportType,
reportSubType, reportCategory, reportSql, coreReport,
useReport, reportParameters));
return reportList;
}
private static final class ReportParameterJoinMapper implements
RowMapper<ReportParameterJoinData> {
public String schema(boolean includeSql, Long userId) {
String sql = "select r.report_id as reportId, r.report_name as reportName, r.report_type as reportType, "
+ " r.report_subtype as reportSubType, r.report_category as reportCategory, r.core_report as coreReport, r.use_report as useReport, "
+ " rp.parameter_id as reportParameterId, rp.report_parameter_name as reportParameterName, p.parameter_name as parameterName";
if (includeSql)
sql += ", r.report_sql as reportSql ";
sql += " from stretchy_report r"
+ " left join stretchy_report_parameter rp on rp.report_id = r.report_id"
+ " left join stretchy_parameter p on p.parameter_id = rp.parameter_id"
+ " where exists"
+ " (select 'f'"
+ " from m_appuser_role ur "
+ " join m_role r on r.id = ur.role_id"
+ " left join m_role_permission rp on rp.role_id = r.id"
+ " left join m_permission p on p.id = rp.permission_id"
+ " where ur.appuser_id = "
+ userId
+ " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', r.report_name))) "
+ " order by r.report_id, rp.parameter_id";
return sql;
}
@Override
public ReportParameterJoinData mapRow(final ResultSet rs,
@SuppressWarnings("unused") final int rowNum)
throws SQLException {
final Long reportId = rs.getLong("reportId");
final String reportName = rs.getString("reportName");
final String reportType = rs.getString("reportType");
final String reportSubType = rs.getString("reportSubType");
final String reportCategory = rs.getString("reportCategory");
final Boolean coreReport = rs.getBoolean("coreReport");
final Boolean useReport = rs.getBoolean("useReport");
String reportSql;
// reportSql might not be on the select list of columns
try {
reportSql = rs.getString("reportSql");
} catch (SQLException e) {
reportSql = null;
}
final Long reportParameterId = JdbcSupport.getLong(rs,
"reportParameterId");
final String reportParameterName = rs
.getString("reportParameterName");
final String parameterName = rs.getString("parameterName");
return new ReportParameterJoinData(reportId, reportName,
reportType, reportSubType, reportCategory, reportSql,
coreReport, useReport, reportParameterId,
reportParameterName, parameterName);
}
}
} }