remove usage lookup data objects, formating of report java code, update api docs for center, groups.

This commit is contained in:
Keith Woodlock
2013-04-19 13:27:27 +01:00
parent 604f07f13e
commit dff53b9318
29 changed files with 986 additions and 1178 deletions
+91 -3
View File
@@ -299,6 +299,14 @@
<td><a href="#centers_delete">Delete a Center</a></td> <td><a href="#centers_delete">Delete a Center</a></td>
</tr> </tr>
<tr class="alt"> <tr class="alt">
<td></td>
<td>centers/{centerId}?command=activate</td>
<td><a href="#centers_activate">Activate a Center</a></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><a href="#groups">Group</a></td> <td><a href="#groups">Group</a></td>
<td>groups</td> <td>groups</td>
<td><a href="#groups_create">Create a Group</a></td> <td><a href="#groups_create">Create a Group</a></td>
@@ -306,7 +314,7 @@
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr class="alt">
<td></td> <td></td>
<td>groups/{group}</td> <td>groups/{group}</td>
<td></td> <td></td>
@@ -314,6 +322,14 @@
<td><a href="#groups_update">Update a Group</a></td> <td><a href="#groups_update">Update a Group</a></td>
<td><a href="#groups_delete">Delete a Group</a></td> <td><a href="#groups_delete">Delete a Group</a></td>
</tr> </tr>
<tr>
<td></td>
<td>groups/{groupId}?command=activate</td>
<td><a href="#groups_activate">Activate a Group</a></td>
<td></td>
<td></td>
<td></td>
</tr>
</table> </table>
</div> </div>
</div> </div>
@@ -1901,7 +1917,7 @@ Request Body:
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h2>Activate a Client</h2> <h2>Activate a Client</h2>
<p>Clients can be created in a <i>Pending</i> state if configuration is enabled. This API exists to enable client activation (for when a client becomes approved member of microfinance institue.</p> <p>Clients can be created in a <i>Pending</i> state. This API exists to enable client activation (for when a client becomes approved member of microfinance institue).</p>
<p>If the client happens to be alrady active this API will result in an error.</p> <p>If the client happens to be alrady active this API will result in an error.</p>
</div> </div>
<div class="method-example"> <div class="method-example">
@@ -2926,6 +2942,34 @@ Content-Type: application/json Request Body:
</div> </div>
</div> </div>
<a id="centers_activate" name="centers_activate" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h2>Activate a Center</h2>
<p>Centers can be created in a <i>Pending</i> state. This API exists to enable center activation.</p>
<p>If the center happens to be already active this API will result in an error.</p>
</div>
<div class="method-example">
<code class="method-declaration">POST https://Domain Name/api/v1/centers/{centerId}?command=activate</code>
<code class="method-request">POST centers/1?command=activate
Content-Type: application/json
Request Body:
{
"locale": "en",
"dateFormat": "dd MMMM yyyy",
"activationDate": "01 March 2011"
}
</code>
<code class="method-response">
{
"officeId": 1,
"groupId": 1,
"resourceId": 1
}
</code>
</div>
</div>
<a id="centers_update" name="centers_update" class="old-syle-anchor">&nbsp;</a> <a id="centers_update" name="centers_update" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
@@ -3322,6 +3366,34 @@ Content-Type: application/json Request Body:
</div> </div>
</div> </div>
<a id="groups_activate" name="groups_activate" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h2>Activate a Group</h2>
<p>Groups can be created in a <i>Pending</i> state. This API exists to enable group activation.</p>
<p>If the group happens to be already active this API will result in an error.</p>
</div>
<div class="method-example">
<code class="method-declaration">POST https://Domain Name/api/v1/groups/{groupId}?command=activate</code>
<code class="method-request">POST groups/1?command=activate
Content-Type: application/json
Request Body:
{
"locale": "en",
"dateFormat": "dd MMMM yyyy",
"activationDate": "01 March 2011"
}
</code>
<code class="method-response">
{
"officeId": 1,
"groupId": 1,
"resourceId": 1
}
</code>
</div>
</div>
<a id="groups_retrieve" name="groups_retrieve" class="old-syle-anchor">&nbsp;</a> <a id="groups_retrieve" name="groups_retrieve" class="old-syle-anchor">&nbsp;</a>
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
@@ -13163,6 +13235,14 @@ GET https://DomainName/api/v1/search?query=000000111
<td><a href="#centers_delete">Delete a Center</a></td> <td><a href="#centers_delete">Delete a Center</a></td>
</tr> </tr>
<tr class="alt"> <tr class="alt">
<td></td>
<td>centers/{centerId}?command=activate</td>
<td><a href="#centers_activate">Activate a Center</a></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><a href="#groups">Group</a></td> <td><a href="#groups">Group</a></td>
<td>groups</td> <td>groups</td>
<td><a href="#groups_create">Create a Group</a></td> <td><a href="#groups_create">Create a Group</a></td>
@@ -13170,7 +13250,7 @@ GET https://DomainName/api/v1/search?query=000000111
<td></td> <td></td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr class="alt">
<td></td> <td></td>
<td>groups/{group}</td> <td>groups/{group}</td>
<td></td> <td></td>
@@ -13178,6 +13258,14 @@ GET https://DomainName/api/v1/search?query=000000111
<td><a href="#groups_update">Update a Group</a></td> <td><a href="#groups_update">Update a Group</a></td>
<td><a href="#groups_delete">Delete a Group</a></td> <td><a href="#groups_delete">Delete a Group</a></td>
</tr> </tr>
<tr>
<td></td>
<td>groups/{groupId}?command=activate</td>
<td><a href="#groups_activate">Activate a Group</a></td>
<td></td>
<td></td>
<td></td>
</tr>
<!-- end of centers, groups api --> <!-- end of centers, groups api -->
<!-- loans api full matrix--> <!-- loans api full matrix-->
<tr class="alt"> <tr class="alt">
@@ -5,7 +5,6 @@
*/ */
package org.mifosplatform.accounting.closure.api; package org.mifosplatform.accounting.closure.api;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@@ -34,7 +33,6 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.data.OfficeLookup;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
@@ -95,7 +93,7 @@ public class GLClosuresApiResource {
final GLClosureData glClosureData = this.glClosureReadPlatformService.retrieveGLClosureById(glClosureId); final GLClosureData glClosureData = this.glClosureReadPlatformService.retrieveGLClosureById(glClosureId);
if (settings.isTemplate()) { if (settings.isTemplate()) {
glClosureData.setAllowedOffices(new ArrayList<OfficeLookup>(this.officeReadPlatformService.retrieveAllOfficesForLookup())); glClosureData.setAllowedOffices(this.officeReadPlatformService.retrieveAllOfficesForDropdown());
} }
return this.apiJsonSerializerService.serialize(settings, glClosureData, RESPONSE_DATA_PARAMETERS); return this.apiJsonSerializerService.serialize(settings, glClosureData, RESPONSE_DATA_PARAMETERS);
@@ -6,10 +6,10 @@
package org.mifosplatform.accounting.closure.data; package org.mifosplatform.accounting.closure.data;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.Collection;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.organisation.office.data.OfficeLookup; import org.mifosplatform.organisation.office.data.OfficeData;
/** /**
* Immutable object representing a General Ledger Account * Immutable object representing a General Ledger Account
@@ -44,7 +44,7 @@ public class GLClosureData {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String comments; private final String comments;
private List<OfficeLookup> allowedOffices = new ArrayList<OfficeLookup>(); private Collection<OfficeData> allowedOffices = new ArrayList<OfficeData>();
public GLClosureData(final Long id, final Long officeId, final String officeName, final LocalDate closingDate, final boolean deleted, public GLClosureData(final Long id, final Long officeId, final String officeName, final LocalDate closingDate, final boolean deleted,
final LocalDate createdDate, final LocalDate lastUpdatedDate, final Long createdByUserId, final String createdByUsername, final LocalDate createdDate, final LocalDate lastUpdatedDate, final Long createdByUserId, final String createdByUsername,
@@ -64,11 +64,11 @@ public class GLClosureData {
this.allowedOffices = null; this.allowedOffices = null;
} }
public List<OfficeLookup> getAllowedOffices() { public final Collection<OfficeData> getAllowedOffices() {
return this.allowedOffices; return this.allowedOffices;
} }
public void setAllowedOffices(final List<OfficeLookup> allowedOffices) { public void setAllowedOffices(final Collection<OfficeData> allowedOffices) {
this.allowedOffices = allowedOffices; this.allowedOffices = allowedOffices;
} }
@@ -1,44 +0,0 @@
/**
* 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.commands.data;
import org.joda.time.LocalDate;
/**
* Immutable data object representing maker-checker entry
*/
@Deprecated
final public class CommandSourceData {
@SuppressWarnings("unused")
private final Long id;
@SuppressWarnings("unused")
private final String actionName;
@SuppressWarnings("unused")
private final String entityName;
@SuppressWarnings("unused")
private final Long entityId;
@SuppressWarnings("unused")
private final String entityHref;
private final String commandJson;
@SuppressWarnings("unused")
private final LocalDate madeOnDate;
public CommandSourceData(final Long id, final String actionName, final String entityName, final Long entityId, final String entityHref,
final String commandJson, final LocalDate madeOnDate) {
this.id = id;
this.actionName = actionName;
this.entityName = entityName;
this.entityId = entityId;
this.entityHref = entityHref;
this.commandJson = commandJson;
this.madeOnDate = madeOnDate;
}
public String json() {
return this.commandJson;
}
}
@@ -7,7 +7,6 @@ package org.mifosplatform.infrastructure.dataqueries.data;
import java.util.List; import java.util.List;
/** /**
* Immutable data object for generic resultset data. * Immutable data object for generic resultset data.
*/ */
@@ -37,12 +37,9 @@ final public class ReportData {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private List<String> allowedReportSubTypes; private List<String> allowedReportSubTypes;
public ReportData(final Long id, final String reportName, public ReportData(final Long id, final String reportName, final String reportType, final String reportSubType,
final String reportType, final String reportSubType, final String reportCategory, final String description, final String reportSql, final Boolean coreReport,
final String reportCategory, final String description, final Boolean useReport, final Collection<ReportParameterData> reportParameters) {
final String reportSql, final Boolean coreReport,
final Boolean useReport,
final Collection<ReportParameterData> reportParameters) {
this.id = id; this.id = id;
this.reportName = reportName; this.reportName = reportName;
this.reportType = reportType; this.reportType = reportType;
@@ -14,11 +14,9 @@ final public class ReportParameterData {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String parameterName; private final String parameterName;
public ReportParameterData(final Long id, public ReportParameterData(final Long id, final String reportParameterName, final String parameterName) {
final String reportParameterName, final String parameterName) {
this.id = id; this.id = id;
this.reportParameterName = reportParameterName; this.reportParameterName = reportParameterName;
this.parameterName = parameterName; this.parameterName = parameterName;
} }
} }
@@ -21,12 +21,9 @@ final public class ReportParameterJoinData {
private final String reportParameterName; private final String reportParameterName;
private final String parameterName; private final String parameterName;
public ReportParameterJoinData(final Long reportId, public ReportParameterJoinData(final Long reportId, final String reportName, final String reportType, final String reportSubType,
final String reportName, final String reportType, final String reportCategory, final String description, final String reportSql, final Boolean coreReport,
final String reportSubType, final String reportCategory, final String description, final Boolean useReport, final Long reportParameterId, final String reportParameterName, final String parameterName) {
final String reportSql, final Boolean coreReport,
final Boolean useReport, final Long reportParameterId,
final String reportParameterName, final String parameterName) {
this.reportId = reportId; this.reportId = reportId;
this.reportName = reportName; this.reportName = reportName;
this.reportType = reportType; this.reportType = reportType;
@@ -88,5 +85,4 @@ final public class ReportParameterJoinData {
public String getDescription() { public String getDescription() {
return description; return description;
} }
} }
@@ -63,33 +63,23 @@ public class Report extends AbstractPersistable<Long> {
public static Report fromJson(final JsonCommand command) { public static Report fromJson(final JsonCommand command) {
final String reportName = command final String reportName = command.stringValueOfParameterNamed("reportName");
.stringValueOfParameterNamed("reportName"); final String reportType = command.stringValueOfParameterNamed("reportType");
final String reportType = command final String reportSubType = command.stringValueOfParameterNamed("reportSubType");
.stringValueOfParameterNamed("reportType"); final String reportCategory = command.stringValueOfParameterNamed("reportCategory");
final String reportSubType = command final String description = command.stringValueOfParameterNamed("description");
.stringValueOfParameterNamed("reportSubType"); final boolean useReport = command.booleanPrimitiveValueOfParameterNamed("useReport");
final String reportCategory = command final String reportSql = command.stringValueOfParameterNamed("reportSql");
.stringValueOfParameterNamed("reportCategory");
final String description = command
.stringValueOfParameterNamed("description");
final boolean useReport = command
.booleanPrimitiveValueOfParameterNamed("useReport");
final String reportSql = command
.stringValueOfParameterNamed("reportSql");
return new Report(reportName, reportType, reportSubType, return new Report(reportName, reportType, reportSubType, reportCategory, description, useReport, reportSql);
reportCategory, description, useReport, reportSql);
} }
protected Report() { protected Report() {
// //
} }
public Report(final String reportName, final String reportType, public Report(final String reportName, final String reportType, final String reportSubType, final String reportCategory,
final String reportSubType, final String reportCategory, final String description, final boolean useReport, final String reportSql) {
final String description, final boolean useReport,
final String reportSql) {
this.reportName = reportName; this.reportName = reportName;
this.reportType = reportType; this.reportType = reportType;
this.reportSubType = reportSubType; this.reportSubType = reportSubType;
@@ -103,57 +93,47 @@ public class Report extends AbstractPersistable<Long> {
public Map<String, Object> update(final JsonCommand command) { public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>( final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(8);
8);
String paramName = "reportName"; String paramName = "reportName";
if (command.isChangeInStringParameterNamed(paramName, this.reportName)) { if (command.isChangeInStringParameterNamed(paramName, this.reportName)) {
final String newValue = command final String newValue = command.stringValueOfParameterNamed(paramName);
.stringValueOfParameterNamed(paramName);
actualChanges.put(paramName, newValue); actualChanges.put(paramName, newValue);
this.reportName = StringUtils.defaultIfEmpty(newValue, null); this.reportName = StringUtils.defaultIfEmpty(newValue, null);
} }
paramName = "reportType"; paramName = "reportType";
if (command.isChangeInStringParameterNamed(paramName, this.reportType)) { if (command.isChangeInStringParameterNamed(paramName, this.reportType)) {
final String newValue = command final String newValue = command.stringValueOfParameterNamed(paramName);
.stringValueOfParameterNamed(paramName);
actualChanges.put(paramName, newValue); actualChanges.put(paramName, newValue);
this.reportType = StringUtils.defaultIfEmpty(newValue, null); this.reportType = StringUtils.defaultIfEmpty(newValue, null);
} }
paramName = "reportSubType"; paramName = "reportSubType";
if (command.isChangeInStringParameterNamed(paramName, if (command.isChangeInStringParameterNamed(paramName, this.reportSubType)) {
this.reportSubType)) { final String newValue = command.stringValueOfParameterNamed(paramName);
final String newValue = command
.stringValueOfParameterNamed(paramName);
actualChanges.put(paramName, newValue); actualChanges.put(paramName, newValue);
this.reportSubType = StringUtils.defaultIfEmpty(newValue, null); this.reportSubType = StringUtils.defaultIfEmpty(newValue, null);
} }
paramName = "reportCategory"; paramName = "reportCategory";
if (command.isChangeInStringParameterNamed(paramName, if (command.isChangeInStringParameterNamed(paramName, this.reportCategory)) {
this.reportCategory)) { final String newValue = command.stringValueOfParameterNamed(paramName);
final String newValue = command
.stringValueOfParameterNamed(paramName);
actualChanges.put(paramName, newValue); actualChanges.put(paramName, newValue);
this.reportCategory = StringUtils.defaultIfEmpty(newValue, null); this.reportCategory = StringUtils.defaultIfEmpty(newValue, null);
} }
paramName = "description"; paramName = "description";
if (command.isChangeInStringParameterNamed(paramName, this.description)) { if (command.isChangeInStringParameterNamed(paramName, this.description)) {
final String newValue = command final String newValue = command.stringValueOfParameterNamed(paramName);
.stringValueOfParameterNamed(paramName);
actualChanges.put(paramName, newValue); actualChanges.put(paramName, newValue);
this.description = StringUtils.defaultIfEmpty(newValue, null); this.description = StringUtils.defaultIfEmpty(newValue, null);
} }
paramName = "useReport"; paramName = "useReport";
if (command.isChangeInBooleanParameterNamed(paramName, this.useReport)) { if (command.isChangeInBooleanParameterNamed(paramName, this.useReport)) {
final boolean newValue = command final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(paramName);
.booleanPrimitiveValueOfParameterNamed(paramName);
actualChanges.put(paramName, newValue); actualChanges.put(paramName, newValue);
this.useReport = newValue; this.useReport = newValue;
} }
paramName = "reportSql"; paramName = "reportSql";
if (command.isChangeInStringParameterNamed(paramName, this.reportSql)) { if (command.isChangeInStringParameterNamed(paramName, this.reportSql)) {
final String newValue = command final String newValue = command.stringValueOfParameterNamed(paramName);
.stringValueOfParameterNamed(paramName);
actualChanges.put(paramName, newValue); actualChanges.put(paramName, newValue);
this.reportSql = StringUtils.defaultIfEmpty(newValue, null); this.reportSql = StringUtils.defaultIfEmpty(newValue, null);
} }
@@ -163,12 +143,9 @@ public class Report extends AbstractPersistable<Long> {
if (!actualChanges.isEmpty()) { if (!actualChanges.isEmpty()) {
if (isCoreReport()) { if (isCoreReport()) {
for (final String key : actualChanges.keySet()) { for (final String key : actualChanges.keySet()) {
if (!(key.equals("useReport"))) { if (!(key.equals("useReport"))) { throw new PlatformDataIntegrityException(
throw new PlatformDataIntegrityException(
"error.msg.only.use.report.can.be.updated.for.core.report", "error.msg.only.use.report.can.be.updated.for.core.report",
"Only the Use Report field can be updated for Core Reports", "Only the Use Report field can be updated for Core Reports", key); }
key);
}
} }
} }
} }
@@ -183,73 +160,43 @@ public class Report extends AbstractPersistable<Long> {
private void validate() { private void validate() {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder( final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("report");
dataValidationErrors).resource("report");
baseDataValidator.reset().parameter("reportName") baseDataValidator.reset().parameter("reportName").value(this.reportName).notBlank().notExceedingLengthOf(100);
.value(this.reportName).notBlank().notExceedingLengthOf(100);
baseDataValidator baseDataValidator.reset().parameter("reportType").value(this.reportType).notBlank()
.reset() .isOneOfTheseValues(new Object[] { "Table", "Pentaho", "Chart" });
.parameter("reportType")
.value(this.reportType)
.notBlank()
.isOneOfTheseValues(
new Object[] { "Table", "Pentaho", "Chart" });
baseDataValidator.reset().parameter("reportSubType") baseDataValidator.reset().parameter("reportSubType").value(this.reportSubType).notExceedingLengthOf(20);
.value(this.reportSubType).notExceedingLengthOf(20);
if (StringUtils.isNotBlank(this.reportType)) { if (StringUtils.isNotBlank(this.reportType)) {
if (this.reportType.equals("Chart")) { if (this.reportType.equals("Chart")) {
baseDataValidator baseDataValidator.reset().parameter("reportSubType").value(this.reportSubType)
.reset() .cantBeBlankWhenParameterProvidedIs("reportType", this.reportType)
.parameter("reportSubType")
.value(this.reportSubType)
.cantBeBlankWhenParameterProvidedIs("reportType",
this.reportType)
.isOneOfTheseValues(new Object[] { "Bar", "Pie" }); .isOneOfTheseValues(new Object[] { "Bar", "Pie" });
} else { } else {
baseDataValidator baseDataValidator.reset().parameter("reportSubType").value(this.reportSubType)
.reset() .mustBeBlankWhenParameterProvidedIs("reportType", this.reportType);
.parameter("reportSubType")
.value(this.reportSubType)
.mustBeBlankWhenParameterProvidedIs("reportType",
this.reportType);
} }
} }
baseDataValidator.reset().parameter("reportCategory") baseDataValidator.reset().parameter("reportCategory").value(this.reportCategory).notExceedingLengthOf(45);
.value(this.reportCategory).notExceedingLengthOf(45);
if (StringUtils.isNotBlank(this.reportType)) { if (StringUtils.isNotBlank(this.reportType)) {
if ((this.reportType.equals("Table")) if ((this.reportType.equals("Table")) || (this.reportType.equals("Chart"))) {
|| (this.reportType.equals("Chart"))) { baseDataValidator.reset().parameter("reportSql").value(this.reportSql)
baseDataValidator .cantBeBlankWhenParameterProvidedIs("reportType", this.reportType);
.reset()
.parameter("reportSql")
.value(this.reportSql)
.cantBeBlankWhenParameterProvidedIs("reportType",
this.reportType);
} else { } else {
baseDataValidator baseDataValidator.reset().parameter("reportSql").value(this.reportSql)
.reset() .mustBeBlankWhenParameterProvidedIs("reportType", this.reportType);
.parameter("reportSql")
.value(this.reportSql)
.mustBeBlankWhenParameterProvidedIs("reportType",
this.reportType);
} }
} }
throwExceptionIfValidationWarningsExist(dataValidationErrors); throwExceptionIfValidationWarningsExist(dataValidationErrors);
} }
private void throwExceptionIfValidationWarningsExist( private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
final List<ApiParameterError> dataValidationErrors) { if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
if (!dataValidationErrors.isEmpty()) { "Validation errors exist.", dataValidationErrors); }
throw new PlatformApiDataValidationException(
"validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors);
}
} }
public String getReportName() { public String getReportName() {
@@ -8,7 +8,7 @@ package org.mifosplatform.infrastructure.dataqueries.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
/** /**
* A {@link RuntimeException} thrown when client resources are not found. * A {@link RuntimeException} thrown when datatable resources are not found.
*/ */
public class DatatableNotFoundException extends AbstractPlatformResourceNotFoundException { public class DatatableNotFoundException extends AbstractPlatformResourceNotFoundException {
@@ -12,5 +12,4 @@ public class DatatableSystemErrorException extends AbstractPlatformDomainRuleExc
public DatatableSystemErrorException(final String msg) { public DatatableSystemErrorException(final String msg) {
super("error.msg.datatable.system.error", msg, msg); super("error.msg.datatable.system.error", msg, msg);
} }
} }
@@ -28,7 +28,8 @@ public class CreateDatatableEntryCommandHandler implements NewCommandSourceHandl
@Override @Override
public CommandProcessingResult processCommand(final JsonCommand command) { public CommandProcessingResult processCommand(final JsonCommand command) {
CommandProcessingResult commandProcessingResult = this.writePlatformService.createNewDatatableEntry(command.entityName(), command.entityId(), command); CommandProcessingResult commandProcessingResult = this.writePlatformService.createNewDatatableEntry(command.entityName(),
command.entityId(), command);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
@@ -19,8 +19,7 @@ public class CreateReportCommandHandler implements NewCommandSourceHandler {
private final ReportWritePlatformService writePlatformService; private final ReportWritePlatformService writePlatformService;
@Autowired @Autowired
public CreateReportCommandHandler( public CreateReportCommandHandler(final ReportWritePlatformService writePlatformService) {
final ReportWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService; this.writePlatformService = writePlatformService;
} }
@@ -28,7 +28,8 @@ public class DeleteOneToManyDatatableEntryCommandHandler implements NewCommandSo
@Override @Override
public CommandProcessingResult processCommand(final JsonCommand command) { public CommandProcessingResult processCommand(final JsonCommand command) {
CommandProcessingResult commandProcessingResult = this.writePlatformService.deleteDatatableEntry(command.entityName(), command.entityId(), command.subentityId()); CommandProcessingResult commandProcessingResult = this.writePlatformService.deleteDatatableEntry(command.entityName(),
command.entityId(), command.subentityId());
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
@@ -28,7 +28,8 @@ public class DeleteOneToOneDatatableEntryCommandHandler implements NewCommandSou
@Override @Override
public CommandProcessingResult processCommand(final JsonCommand command) { public CommandProcessingResult processCommand(final JsonCommand command) {
CommandProcessingResult commandProcessingResult = this.writePlatformService.deleteDatatableEntries(command.entityName(), command.entityId()); CommandProcessingResult commandProcessingResult = this.writePlatformService.deleteDatatableEntries(command.entityName(),
command.entityId());
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
@@ -20,8 +20,7 @@ public class DeleteReportCommandHandler implements NewCommandSourceHandler {
private final ReportWritePlatformService writePlatformService; private final ReportWritePlatformService writePlatformService;
@Autowired @Autowired
public DeleteReportCommandHandler( public DeleteReportCommandHandler(final ReportWritePlatformService writePlatformService) {
final ReportWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService; this.writePlatformService = writePlatformService;
} }
@@ -28,8 +28,8 @@ public class UpdateOneToManyDatatableEntryCommandHandler implements NewCommandSo
@Override @Override
public CommandProcessingResult processCommand(final JsonCommand command) { public CommandProcessingResult processCommand(final JsonCommand command) {
final CommandProcessingResult commandProcessingResult = this.writePlatformService.updateDatatableEntryOneToMany(command.entityName(), final CommandProcessingResult commandProcessingResult = this.writePlatformService.updateDatatableEntryOneToMany(
command.entityId(), command.subentityId(), command); command.entityName(), command.entityId(), command.subentityId(), command);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
@@ -28,8 +28,8 @@ public class UpdateOneToOneDatatableEntryCommandHandler implements NewCommandSou
@Override @Override
public CommandProcessingResult processCommand(final JsonCommand command) { public CommandProcessingResult processCommand(final JsonCommand command) {
final CommandProcessingResult commandProcessingResult = this.writePlatformService.updateDatatableEntryOneToOne(command.entityName(), command.entityId(), final CommandProcessingResult commandProcessingResult = this.writePlatformService.updateDatatableEntryOneToOne(
command); command.entityName(), command.entityId(), command);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
@@ -19,8 +19,7 @@ public class UpdateReportCommandHandler implements NewCommandSourceHandler {
private final ReportWritePlatformService writePlatformService; private final ReportWritePlatformService writePlatformService;
@Autowired @Autowired
public UpdateReportCommandHandler( public UpdateReportCommandHandler(final ReportWritePlatformService writePlatformService) {
final ReportWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService; this.writePlatformService = writePlatformService;
} }
@@ -28,7 +27,6 @@ public class UpdateReportCommandHandler implements NewCommandSourceHandler {
@Override @Override
public CommandProcessingResult processCommand(final JsonCommand command) { public CommandProcessingResult processCommand(final JsonCommand command) {
return this.writePlatformService.updateReport(command.entityId(), return this.writePlatformService.updateReport(command.entityId(), command);
command);
} }
} }
@@ -25,27 +25,21 @@ public final class ReportCommandFromApiJsonDeserializer {
/** /**
* The parameters supported for this command. * The parameters supported for this command.
*/ */
private final Set<String> supportedParameters = new HashSet<String>( private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("reportName", "reportType", "reportSubType",
Arrays.asList("reportName", "reportType", "reportSubType",
"reportCategory", "description", "reportSql", "useReport")); "reportCategory", "description", "reportSql", "useReport"));
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
@Autowired @Autowired
public ReportCommandFromApiJsonDeserializer( public ReportCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper; this.fromApiJsonHelper = fromApiJsonHelper;
} }
public void validate(final String json) { public void validate(final String json) {
if (StringUtils.isBlank(json)) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() { final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
supportedParameters);
} }
} }
@@ -16,17 +16,13 @@ import org.mifosplatform.infrastructure.dataqueries.data.ReportData;
public interface ReadReportingService { public interface ReadReportingService {
StreamingOutput retrieveReportCSV(String name, String type, StreamingOutput retrieveReportCSV(String name, String type, Map<String, String> extractedQueryParams);
Map<String, String> extractedQueryParams);
GenericResultsetData retrieveGenericResultset(String name, String type, GenericResultsetData retrieveGenericResultset(String name, String type, Map<String, String> extractedQueryParams);
Map<String, String> extractedQueryParams);
Response processPentahoRequest(String reportName, String outputType, Response processPentahoRequest(String reportName, String outputType, Map<String, String> queryParams);
Map<String, String> queryParams);
String retrieveReportPDF(String name, String type, String retrieveReportPDF(String name, String type, Map<String, String> extractedQueryParams);
Map<String, String> extractedQueryParams);
String getReportType(String reportName); String getReportType(String reportName);
@@ -68,8 +68,7 @@ import com.lowagie.text.pdf.PdfWriter;
@Service @Service
public class ReadReportingServiceImpl implements ReadReportingService { public class ReadReportingServiceImpl implements ReadReportingService {
private final static Logger logger = LoggerFactory private final static Logger logger = LoggerFactory.getLogger(ReadReportingServiceImpl.class);
.getLogger(ReadReportingServiceImpl.class);
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final DataSource dataSource; private final DataSource dataSource;
@@ -78,8 +77,7 @@ public class ReadReportingServiceImpl implements ReadReportingService {
private boolean noPentaho = false; private boolean noPentaho = false;
@Autowired @Autowired
public ReadReportingServiceImpl(final PlatformSecurityContext context, public ReadReportingServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
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();
@@ -92,8 +90,7 @@ public class ReadReportingServiceImpl implements ReadReportingService {
} }
@Override @Override
public StreamingOutput retrieveReportCSV(final String name, public StreamingOutput retrieveReportCSV(final String name, final String type, final Map<String, String> queryParams) {
final String type, final Map<String, String> queryParams) {
return new StreamingOutput() { return new StreamingOutput() {
@@ -101,12 +98,10 @@ public class ReadReportingServiceImpl implements ReadReportingService {
public void write(final OutputStream out) { public void write(final OutputStream out) {
try { try {
GenericResultsetData result = retrieveGenericResultset( GenericResultsetData result = retrieveGenericResultset(name, type, queryParams);
name, type, queryParams);
StringBuffer sb = generateCsvFileBuffer(result); StringBuffer sb = generateCsvFileBuffer(result);
InputStream in = new ByteArrayInputStream(sb.toString() InputStream in = new ByteArrayInputStream(sb.toString().getBytes("UTF-8"));
.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);
@@ -119,8 +114,7 @@ public class ReadReportingServiceImpl implements ReadReportingService {
// out.flush(); // out.flush();
// out.close(); // out.close();
} catch (Exception e) { } catch (Exception e) {
throw new PlatformDataIntegrityException( throw new PlatformDataIntegrityException("error.msg.exception.error", e.getMessage());
"error.msg.exception.error", e.getMessage());
} }
} }
}; };
@@ -130,14 +124,12 @@ 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 List<ResultsetColumnHeaderData> columnHeaders = result.getColumnHeaders();
.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)) if (i < (chSize - 1)) writer.append(",");
writer.append(",");
} }
writer.append('\n'); writer.append('\n');
@@ -158,19 +150,14 @@ 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") if (currColType.equals("DECIMAL") || currColType.equals("DOUBLE") || currColType.equals("BIGINT")
|| currColType.equals("DOUBLE") || currColType.equals("SMALLINT") || currColType.equals("INT"))
|| currColType.equals("BIGINT")
|| currColType.equals("SMALLINT")
|| currColType.equals("INT"))
writer.append(currVal); writer.append(currVal);
else else
writer.append('"' + genericDataService.replace(currVal, writer.append('"' + genericDataService.replace(currVal, doubleQuote, twoDoubleQuotes) + '"');
doubleQuote, twoDoubleQuotes) + '"');
} }
if (j < (rSize - 1)) if (j < (rSize - 1)) writer.append(",");
writer.append(",");
} }
writer.append('\n'); writer.append('\n');
} }
@@ -179,25 +166,21 @@ public class ReadReportingServiceImpl implements ReadReportingService {
} }
@Override @Override
public GenericResultsetData retrieveGenericResultset(final String name, public GenericResultsetData retrieveGenericResultset(final String name, final String type, final Map<String, String> queryParams) {
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);
String sql = getSQLtoRun(name, type, queryParams); String sql = getSQLtoRun(name, type, queryParams);
GenericResultsetData result = genericDataService GenericResultsetData result = genericDataService.fillGenericResultSet(sql);
.fillGenericResultSet(sql);
long elapsed = System.currentTimeMillis() - startTime; long elapsed = System.currentTimeMillis() - startTime;
logger.info("FINISHING Report/Request Name: " + name + " - " + type logger.info("FINISHING Report/Request Name: " + name + " - " + type + " Elapsed Time: " + elapsed);
+ " Elapsed Time: " + elapsed);
return result; return result;
} }
private String getSQLtoRun(final String name, final String type, private String getSQLtoRun(final String name, final String type, final Map<String, String> queryParams) {
final Map<String, String> queryParams) {
String sql = getSql(name, type); String sql = getSql(name, type);
@@ -210,13 +193,11 @@ 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}", sql = genericDataService.replace(sql, "${currentUserHierarchy}", currentUser.getOffice().getHierarchy());
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 sql = genericDataService.replace(sql, "${currentUserId}", currentUser.getId().toString());
.getId().toString());
sql = genericDataService.wrapSQL(sql); sql = genericDataService.wrapSQL(sql);
@@ -226,58 +207,42 @@ 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 final String inputSql = "select " + type + "_sql as the_sql from stretchy_" + type + " where " + type + "_name = '" + name + "'";
+ "_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()) { if (rs.next()) { return rs.getString("the_sql"); }
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 = '" final String sql = "SELECT ifnull(report_type,'') as report_type FROM `stretchy_report` where report_name = '" + reportName + "'";
+ 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()) { if (rs.next()) { return rs.getString("report_type"); }
return rs.getString("report_type");
}
throw new ReportNotFoundException(sql); throw new ReportNotFoundException(sql);
} }
@Override @Override
public Response processPentahoRequest(final String reportName, public Response processPentahoRequest(final String reportName, final String outputTypeParam, final Map<String, String> queryParams) {
final String outputTypeParam, final Map<String, String> queryParams) {
String outputType = "HTML"; String outputType = "HTML";
if (StringUtils.isNotBlank(outputTypeParam)) if (StringUtils.isNotBlank(outputTypeParam)) outputType = outputTypeParam;
outputType = outputTypeParam;
if (!(outputType.equalsIgnoreCase("HTML") if (!(outputType.equalsIgnoreCase("HTML") || outputType.equalsIgnoreCase("PDF") || outputType.equalsIgnoreCase("XLS") || outputType
|| outputType.equalsIgnoreCase("PDF")
|| outputType.equalsIgnoreCase("XLS") || outputType
.equalsIgnoreCase("CSV"))) .equalsIgnoreCase("CSV")))
throw new PlatformDataIntegrityException( throw new PlatformDataIntegrityException("error.msg.invalid.outputType", "No matching Output Type: " + outputType);
"error.msg.invalid.outputType", "No matching Output Type: "
+ outputType);
if (noPentaho) { if (noPentaho) { throw new PlatformDataIntegrityException("error.msg.no.pentaho", "Pentaho is not enabled",
throw new PlatformDataIntegrityException("error.msg.no.pentaho", "Pentaho is not enabled"); }
"Pentaho is not enabled", "Pentaho is not enabled");
}
final String reportPath = FileUtils.MIFOSX_BASE_DIR + File.separator final String reportPath = FileUtils.MIFOSX_BASE_DIR + File.separator + "pentahoReports" + File.separator + reportName + ".prpt";
+ "pentahoReports" + File.separator + reportName + ".prpt";
logger.info("Report path: " + reportPath); logger.info("Report path: " + reportPath);
// load report definition // load report definition
@@ -295,65 +260,44 @@ 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()) return Response.ok().entity(baos.toByteArray()).type("application/pdf").build();
.type("application/pdf").build();
} }
if ("XLS".equalsIgnoreCase(outputType)) { if ("XLS".equalsIgnoreCase(outputType)) {
ExcelReportUtil.createXLS(masterReport, baos); ExcelReportUtil.createXLS(masterReport, baos);
return Response return Response.ok().entity(baos.toByteArray()).type("application/vnd.ms-excel")
.ok() .header("Content-Disposition", "attachment;filename=" + reportName.replaceAll(" ", "") + ".xls").build();
.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 return Response.ok().entity(baos.toByteArray()).type("application/x-msdownload")
.ok() .header("Content-Disposition", "attachment;filename=" + reportName.replaceAll(" ", "") + ".csv").build();
.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()) return Response.ok().entity(baos.toByteArray()).type("text/html").build();
.type("text/html").build();
} }
} catch (ResourceException e) { } catch (ResourceException e) {
throw new PlatformDataIntegrityException( throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage());
"error.msg.reporting.error", e.getMessage());
} catch (ReportProcessingException e) { } catch (ReportProcessingException e) {
throw new PlatformDataIntegrityException( throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage());
"error.msg.reporting.error", e.getMessage());
} catch (IOException e) { } catch (IOException e) {
throw new PlatformDataIntegrityException( throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage());
"error.msg.reporting.error", e.getMessage());
} }
throw new PlatformDataIntegrityException( throw new PlatformDataIntegrityException("error.msg.invalid.outputType", "No matching Output Type: " + outputType);
"error.msg.invalid.outputType", "No matching Output Type: "
+ outputType);
} }
private void addParametersToReport(final MasterReport report, private void addParametersToReport(final MasterReport report, final Map<String, String> queryParams) {
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 ReportParameterDefinition paramsDefinition = report.getParameterDefinition();
.getParameterDefinition();
/* /*
* only allow integer, long, date and string parameter types and * only allow integer, long, date and string parameter types and
@@ -362,30 +306,22 @@ 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 for (ParameterDefinitionEntry paramDefEntry : paramsDefinition.getParameterDefinitions()) {
.getParameterDefinitions()) {
String paramName = paramDefEntry.getName(); String paramName = paramDefEntry.getName();
if (!((paramName.equals("tenantdb")) || (paramName if (!((paramName.equals("tenantdb")) || (paramName.equals("userhierarchy")))) {
.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( throw new PlatformDataIntegrityException("error.msg.reporting.error", "Pentaho Parameter: " + paramName
"error.msg.reporting.error",
"Pentaho Parameter: " + paramName
+ " - not Provided"); + " - not Provided");
Class<?> clazz = paramDefEntry.getValueType(); Class<?> clazz = paramDefEntry.getValueType();
logger.info("addParametersToReport(" + paramName + " : " logger.info("addParametersToReport(" + paramName + " : " + pValue + " : " + clazz.getCanonicalName() + ")");
+ pValue + " : " + clazz.getCanonicalName() + ")"); if (clazz.getCanonicalName().equalsIgnoreCase("java.lang.Integer"))
if (clazz.getCanonicalName().equalsIgnoreCase(
"java.lang.Integer"))
rptParamValues.put(paramName, Integer.parseInt(pValue)); rptParamValues.put(paramName, Integer.parseInt(pValue));
else if (clazz.getCanonicalName().equalsIgnoreCase( else if (clazz.getCanonicalName().equalsIgnoreCase("java.lang.Long"))
"java.lang.Long"))
rptParamValues.put(paramName, Long.parseLong(pValue)); rptParamValues.put(paramName, Long.parseLong(pValue));
else if (clazz.getCanonicalName().equalsIgnoreCase( else if (clazz.getCanonicalName().equalsIgnoreCase("java.sql.Date"))
"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);
@@ -399,35 +335,29 @@ 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:" logger.info("db name:" + tenantdb + " userhierarchy:" + 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( throw new PlatformDataIntegrityException("error.msg.reporting.error", e.getMessage());
"error.msg.reporting.error", e.getMessage());
} }
} }
@Override @Override
public String retrieveReportPDF(final String reportName, final String type, public String retrieveReportPDF(final String reportName, final String type, final Map<String, String> queryParams) {
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 String genaratePdf = fileLocation + File.separator + reportName + ".pdf";
+ ".pdf";
try { try {
GenericResultsetData result = retrieveGenericResultset(reportName, GenericResultsetData result = retrieveGenericResultset(reportName, type, queryParams);
type, queryParams);
List<ResultsetColumnHeaderData> columnHeaders = result List<ResultsetColumnHeaderData> columnHeaders = result.getColumnHeaders();
.getColumnHeaders();
List<ResultsetRowData> data = result.getData(); List<ResultsetRowData> data = result.getData();
List<String> row; List<String> row;
@@ -436,8 +366,7 @@ 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( PdfWriter.getInstance(document, new FileOutputStream(new File(fileLocation + reportName + ".pdf")));
fileLocation + reportName + ".pdf")));
document.open(); document.open();
PdfPTable table = new PdfPTable(chSize); PdfPTable table = new PdfPTable(chSize);
@@ -461,11 +390,8 @@ 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") if (currColType.equals("DECIMAL") || currColType.equals("DOUBLE") || currColType.equals("BIGINT")
|| currColType.equals("DOUBLE") || currColType.equals("SMALLINT") || currColType.equals("INT")) {
|| currColType.equals("BIGINT")
|| currColType.equals("SMALLINT")
|| currColType.equals("INT")) {
table.addCell(currVal.toString()); table.addCell(currVal.toString());
} else { } else {
@@ -480,13 +406,12 @@ 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( throw new PlatformDataIntegrityException("error.msg.exception.error", e.getMessage());
"error.msg.exception.error", e.getMessage());
} }
} }
@Override @Override
public ReportData retrieveReport(Long id) { public ReportData retrieveReport(final Long id) {
Collection<ReportData> reports = retrieveReports(id); Collection<ReportData> reports = retrieveReports(id);
for (ReportData report : reports) { for (ReportData report : reports) {
@@ -506,12 +431,10 @@ public class ReadReportingServiceImpl implements ReadReportingService {
String sql = rm.schema(id); String sql = rm.schema(id);
Collection<ReportParameterJoinData> rpJoins = this.jdbcTemplate.query( Collection<ReportParameterJoinData> rpJoins = this.jdbcTemplate.query(sql, rm, new Object[] {});
sql, rm, new Object[] {});
Collection<ReportData> reportList = new ArrayList<ReportData>(); Collection<ReportData> reportList = new ArrayList<ReportData>();
if (rpJoins == null || rpJoins.size() == 0) if (rpJoins == null || rpJoins.size() == 0) return reportList;
return reportList;
Collection<ReportParameterData> reportParameters = null; Collection<ReportParameterData> reportParameters = null;
@@ -531,19 +454,19 @@ public class ReadReportingServiceImpl implements ReadReportingService {
if (rpJoin.getReportId().equals(prevReportId)) { if (rpJoin.getReportId().equals(prevReportId)) {
// more than one parameter for report // more than one parameter for report
reportParameters.add(new ReportParameterData(rpJoin if (reportParameters == null) {
.getReportParameterId(), rpJoin reportParameters = new ArrayList<ReportParameterData>();
.getReportParameterName(), rpJoin.getParameterName())); }
reportParameters.add(new ReportParameterData(rpJoin.getReportParameterId(), rpJoin.getReportParameterName(), rpJoin
.getParameterName()));
} else { } else {
if (firstReport) { if (firstReport) {
firstReport = false; firstReport = false;
} else { } else {
// write report entry // write report entry
reportList.add(new ReportData(reportId, reportName, reportList.add(new ReportData(reportId, reportName, reportType, reportSubType, reportCategory, description, reportSql,
reportType, reportSubType, reportCategory, coreReport, useReport, reportParameters));
description, reportSql, coreReport, useReport,
reportParameters));
} }
prevReportId = rpJoin.getReportId(); prevReportId = rpJoin.getReportId();
@@ -561,9 +484,7 @@ public class ReadReportingServiceImpl implements ReadReportingService {
if (rpJoin.getReportParameterId() != null) { if (rpJoin.getReportParameterId() != null) {
// report has at least one parameter // report has at least one parameter
reportParameters = new ArrayList<ReportParameterData>(); reportParameters = new ArrayList<ReportParameterData>();
reportParameters.add(new ReportParameterData(rpJoin reportParameters.add(new ReportParameterData(rpJoin.getReportParameterId(), rpJoin.getReportParameterName(), rpJoin
.getReportParameterId(), rpJoin
.getReportParameterName(), rpJoin
.getParameterName())); .getParameterName()));
} else { } else {
reportParameters = null; reportParameters = null;
@@ -572,27 +493,23 @@ public class ReadReportingServiceImpl implements ReadReportingService {
} }
// write last report // write last report
reportList.add(new ReportData(reportId, reportName, reportType, reportList.add(new ReportData(reportId, reportName, reportType, reportSubType, reportCategory, description, reportSql, coreReport,
reportSubType, reportCategory, description, reportSql, useReport, reportParameters));
coreReport, useReport, reportParameters));
return reportList; return reportList;
} }
private static final class ReportParameterJoinMapper implements private static final class ReportParameterJoinMapper implements RowMapper<ReportParameterJoinData> {
RowMapper<ReportParameterJoinData> {
public String schema(Long reportId) { public String schema(final Long reportId) {
String sql = "select r.id as reportId, r.report_name as reportName, r.report_type as reportType, " String sql = "select r.id as reportId, r.report_name as reportName, r.report_type as reportType, "
+ " r.report_subtype as reportSubType, r.report_category as reportCategory, r.description, r.core_report as coreReport, r.use_report as useReport, " + " r.report_subtype as reportSubType, r.report_category as reportCategory, r.description, 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"; + " rp.parameter_id as reportParameterId, rp.report_parameter_name as reportParameterName, p.parameter_name as parameterName";
if (reportId != null) if (reportId != null) sql += ", r.report_sql as reportSql ";
sql += ", r.report_sql as reportSql ";
sql += " from stretchy_report r" sql += " from stretchy_report r" + " left join stretchy_report_parameter rp on rp.report_id = r.id"
+ " left join stretchy_report_parameter rp on rp.report_id = r.id"
+ " left join stretchy_parameter p on p.id = rp.parameter_id"; + " left join stretchy_parameter p on p.id = rp.parameter_id";
if (reportId != null) if (reportId != null)
sql += " where r.id = " + reportId; sql += " where r.id = " + reportId;
@@ -601,24 +518,22 @@ public class ReadReportingServiceImpl implements ReadReportingService {
return sql; return sql;
/* used to only return reports that the use can run as done in report UI but not necessary as there is a read_report permission /*
* which should give user access to look all reports * used to only return reports that the use can run as done in
+ " where exists" * report UI but not necessary as there is a read_report permission
+ " (select 'f'" * which should give user access to look all reports +
+ " from m_appuser_role ur " * " where exists" + " (select 'f'" + " from m_appuser_role ur " +
+ " join m_role r on r.id = ur.role_id" * " 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_role_permission rp on rp.role_id = r.id" +
+ " left join m_permission p on p.id = rp.permission_id" * " left join m_permission p on p.id = rp.permission_id" +
+ " where ur.appuser_id = " * " where ur.appuser_id = " + userId +
+ userId * " 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))) "; * ;
*/ */
} }
@Override @Override
public ReportParameterJoinData mapRow(final ResultSet rs, public ReportParameterJoinData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
@SuppressWarnings("unused") final int rowNum)
throws SQLException {
final Long reportId = rs.getLong("reportId"); final Long reportId = rs.getLong("reportId");
final String reportName = rs.getString("reportName"); final String reportName = rs.getString("reportName");
@@ -637,18 +552,12 @@ public class ReadReportingServiceImpl implements ReadReportingService {
reportSql = null; reportSql = null;
} }
final Long reportParameterId = JdbcSupport.getLong(rs, final Long reportParameterId = JdbcSupport.getLong(rs, "reportParameterId");
"reportParameterId"); final String reportParameterName = rs.getString("reportParameterName");
final String reportParameterName = rs
.getString("reportParameterName");
final String parameterName = rs.getString("parameterName"); final String parameterName = rs.getString("parameterName");
return new ReportParameterJoinData(reportId, reportName, return new ReportParameterJoinData(reportId, reportName, reportType, reportSubType, reportCategory, description, reportSql,
reportType, reportSubType, reportCategory, description, coreReport, useReport, reportParameterId, reportParameterName, parameterName);
reportSql, coreReport, useReport, reportParameterId,
reportParameterName, parameterName);
} }
} }
} }
@@ -1,29 +0,0 @@
/**
* 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.organisation.office.data;
/**
* Immutable data object used for office lookups (will remove eventually and just use {@link OfficeData}.
*/
@Deprecated
public class OfficeLookup {
private final Long id;
@SuppressWarnings("unused")
private final String name;
@SuppressWarnings("unused")
private final String nameDecorated;
public OfficeLookup(final Long id, final String name, final String nameDecorated) {
this.id = id;
this.name = name;
this.nameDecorated = nameDecorated;
}
public boolean hasIdentifyOf(final Long officeId) {
return this.id.equals(officeId);
}
}
@@ -8,7 +8,6 @@ package org.mifosplatform.organisation.office.service;
import java.util.Collection; import java.util.Collection;
import org.mifosplatform.organisation.office.data.OfficeData; import org.mifosplatform.organisation.office.data.OfficeData;
import org.mifosplatform.organisation.office.data.OfficeLookup;
import org.mifosplatform.organisation.office.data.OfficeTransactionData; import org.mifosplatform.organisation.office.data.OfficeTransactionData;
public interface OfficeReadPlatformService { public interface OfficeReadPlatformService {
@@ -17,13 +16,6 @@ public interface OfficeReadPlatformService {
Collection<OfficeData> retrieveAllOfficesForDropdown(); Collection<OfficeData> retrieveAllOfficesForDropdown();
/*
* Deprecated so cane eventually remove need for OfficeLookup type - so use
* retrieveAllOfficesForDropdown instead.
*/
@Deprecated
Collection<OfficeLookup> retrieveAllOfficesForLookup();
OfficeData retrieveOffice(Long officeId); OfficeData retrieveOffice(Long officeId);
OfficeData retrieveNewOfficeTemplate(); OfficeData retrieveNewOfficeTemplate();
@@ -18,7 +18,6 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
import org.mifosplatform.organisation.monetary.data.CurrencyData; import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService; import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService;
import org.mifosplatform.organisation.office.data.OfficeData; import org.mifosplatform.organisation.office.data.OfficeData;
import org.mifosplatform.organisation.office.data.OfficeLookup;
import org.mifosplatform.organisation.office.data.OfficeTransactionData; import org.mifosplatform.organisation.office.data.OfficeTransactionData;
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.AppUser;
@@ -86,23 +85,6 @@ public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService
} }
} }
private static final class OfficeLookupMapper implements RowMapper<OfficeLookup> {
public String officeLookupSchema() {
return " o.id as id, " + nameDecoratedBaseOnHierarchy + " as nameDecorated, o.name as name from m_office o ";
}
@Override
public OfficeLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
Long id = rs.getLong("id");
String name = rs.getString("name");
String nameDecorated = rs.getString("nameDecorated");
return new OfficeLookup(id, name, nameDecorated);
}
}
private static final class OfficeTransactionMapper implements RowMapper<OfficeTransactionData> { private static final class OfficeTransactionMapper implements RowMapper<OfficeTransactionData> {
public String schema() { public String schema() {
@@ -137,8 +119,8 @@ public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService
BigDecimal transactionAmount = rs.getBigDecimal("transactionAmount"); BigDecimal transactionAmount = rs.getBigDecimal("transactionAmount");
String description = rs.getString("description"); String description = rs.getString("description");
return OfficeTransactionData.instance(id, transactionDate, fromOfficeId, fromOfficeName, toOfficeId, toOfficeName, currencyData, return OfficeTransactionData.instance(id, transactionDate, fromOfficeId, fromOfficeName, toOfficeId, toOfficeName,
transactionAmount, description); currencyData, transactionAmount, description);
} }
} }
@@ -169,19 +151,6 @@ public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService
return this.jdbcTemplate.query(sql, rm, new Object[] { hierarchySearchString }); return this.jdbcTemplate.query(sql, rm, new Object[] { hierarchySearchString });
} }
@Override
public Collection<OfficeLookup> retrieveAllOfficesForLookup() {
AppUser currentUser = context.authenticatedUser();
String hierarchy = currentUser.getOffice().getHierarchy();
String hierarchySearchString = hierarchy + "%";
OfficeLookupMapper rm = new OfficeLookupMapper();
String sql = "select " + rm.officeLookupSchema() + "where o.hierarchy like ? order by o.hierarchy";
return this.jdbcTemplate.query(sql, rm, new Object[] { hierarchySearchString });
}
@Override @Override
public OfficeData retrieveOffice(final Long officeId) { public OfficeData retrieveOffice(final Long officeId) {
@@ -5,11 +5,11 @@
*/ */
package org.mifosplatform.organisation.staff.data; package org.mifosplatform.organisation.staff.data;
import org.joda.time.LocalDate;
import org.mifosplatform.organisation.office.data.OfficeLookup;
import java.util.Collection; import java.util.Collection;
import org.joda.time.LocalDate;
import org.mifosplatform.organisation.office.data.OfficeData;
/** /**
* Immutable data object returned for loan-officer bulk transfer screens. * Immutable data object returned for loan-officer bulk transfer screens.
*/ */
@@ -24,14 +24,14 @@ public class BulkTransferLoanOfficerData {
// template // template
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Collection<OfficeLookup> officeOptions; private final Collection<OfficeData> officeOptions;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Collection<StaffData> loanOfficerOptions; private final Collection<StaffData> loanOfficerOptions;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final StaffAccountSummaryCollectionData accountSummaryCollection; private final StaffAccountSummaryCollectionData accountSummaryCollection;
public static BulkTransferLoanOfficerData templateForBulk(final Long officeId, final Long fromLoanOfficerId, public static BulkTransferLoanOfficerData templateForBulk(final Long officeId, final Long fromLoanOfficerId,
final LocalDate assignmentDate, final Collection<OfficeLookup> officeOptions, final Collection<StaffData> loanOfficerOptions, final LocalDate assignmentDate, final Collection<OfficeData> officeOptions, final Collection<StaffData> loanOfficerOptions,
final StaffAccountSummaryCollectionData accountSummaryCollection) { final StaffAccountSummaryCollectionData accountSummaryCollection) {
return new BulkTransferLoanOfficerData(officeId, fromLoanOfficerId, assignmentDate, officeOptions, loanOfficerOptions, return new BulkTransferLoanOfficerData(officeId, fromLoanOfficerId, assignmentDate, officeOptions, loanOfficerOptions,
accountSummaryCollection); accountSummaryCollection);
@@ -43,7 +43,7 @@ public class BulkTransferLoanOfficerData {
} }
private BulkTransferLoanOfficerData(final Long officeId, final Long fromLoanOfficerId, final LocalDate assignmentDate, private BulkTransferLoanOfficerData(final Long officeId, final Long fromLoanOfficerId, final LocalDate assignmentDate,
final Collection<OfficeLookup> officeOptions, final Collection<StaffData> loanOfficerOptions, final Collection<OfficeData> officeOptions, final Collection<StaffData> loanOfficerOptions,
final StaffAccountSummaryCollectionData accountSummaryCollection) { final StaffAccountSummaryCollectionData accountSummaryCollection) {
this.officeId = officeId; this.officeId = officeId;
this.fromLoanOfficerId = fromLoanOfficerId; this.fromLoanOfficerId = fromLoanOfficerId;
@@ -29,7 +29,7 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.data.OfficeLookup; import org.mifosplatform.organisation.office.data.OfficeData;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.organisation.staff.data.BulkTransferLoanOfficerData; import org.mifosplatform.organisation.staff.data.BulkTransferLoanOfficerData;
import org.mifosplatform.organisation.staff.data.StaffAccountSummaryCollectionData; import org.mifosplatform.organisation.staff.data.StaffAccountSummaryCollectionData;
@@ -82,7 +82,7 @@ public class BulkLoansApiResource {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
final Collection<OfficeLookup> offices = this.officeReadPlatformService.retrieveAllOfficesForLookup(); final Collection<OfficeData> offices = this.officeReadPlatformService.retrieveAllOfficesForDropdown();
Collection<StaffData> loanOfficers = null; Collection<StaffData> loanOfficers = null;
StaffAccountSummaryCollectionData staffAccountSummaryCollectionData = null; StaffAccountSummaryCollectionData staffAccountSummaryCollectionData = null;