remove usage lookup data objects, formating of report java code, update api docs for center, groups.
This commit is contained in:
+91
-3
@@ -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"> </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"> </a>
|
<a id="centers_update" name="centers_update" class="old-syle-anchor"> </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"> </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"> </a>
|
<a id="groups_retrieve" name="groups_retrieve" class="old-syle-anchor"> </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">
|
||||||
|
|||||||
+1
-3
@@ -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);
|
||||||
|
|||||||
+5
-5
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-1
@@ -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.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+3
-6
@@ -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;
|
||||||
|
|||||||
+1
-3
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+3
-7
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+40
-93
@@ -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() {
|
||||||
|
|||||||
+1
-1
@@ -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 {
|
||||||
|
|
||||||
|
|||||||
-1
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-1
@@ -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()) //
|
||||||
|
|||||||
+1
-2
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -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()) //
|
||||||
|
|||||||
+2
-1
@@ -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()) //
|
||||||
|
|||||||
+1
-2
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -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()) //
|
||||||
|
|||||||
+2
-2
@@ -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()) //
|
||||||
|
|||||||
+2
-4
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+5
-11
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-8
@@ -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);
|
||||||
|
|
||||||
|
|||||||
+91
-182
@@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
-29
@@ -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
@@ -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();
|
||||||
|
|||||||
+2
-33
@@ -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) {
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -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;
|
||||||
|
|||||||
+2
-2
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user