diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java index c71de32f0..8fed138eb 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java @@ -207,6 +207,22 @@ public class CommandWrapperBuilder { return this; } + public CommandWrapperBuilder updateReport(final Long id) { + this.actionName = "UPDATE"; + this.entityName = "REPORT"; + this.entityId = id; + this.href = "/reports/" + id; + return this; + } + + public CommandWrapperBuilder deleteReport(final Long id) { + this.actionName = "DELETE"; + this.entityName = "REPORT"; + this.entityId = id; + this.href = "/reports/" + id; + return this; + } + public CommandWrapperBuilder updateCurrencies() { this.actionName = "UPDATE"; this.entityName = "CURRENCY"; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/DataValidatorBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/DataValidatorBuilder.java index 04db8a832..48449c38a 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/DataValidatorBuilder.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/DataValidatorBuilder.java @@ -357,6 +357,37 @@ public class DataValidatorBuilder { return this; } + public DataValidatorBuilder mustBeBlankWhenParameterProvidedIs(final String parameterName, final Object parameterValue) { + if (value == null && ignoreNullValue) { return this; } + + if (value == null && parameterValue != null) { return this; } + + if (value != null && StringUtils.isBlank(value.toString()) && parameterValue != null + && StringUtils.isNotBlank(parameterValue.toString())) { return this; } + + StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(resource).append(".").append(parameter) + .append(".cannot.also.be.provided.when.").append(parameterName).append(".is.").append(parameterValue); + StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(parameter) + .append(" cannot also be provided when ").append(parameterName).append(" is ").append(parameterValue); + ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), + parameter, value, parameterName, parameterValue); + dataValidationErrors.add(error); + return this; + } + + public DataValidatorBuilder cantBeBlankWhenParameterProvidedIs(final String parameterName, final Object parameterValue) { + if (value != null) { return this; } + + StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(resource).append(".").append(parameter) + .append(".must.be.provided.when.").append(parameterName).append(".is.").append(parameterValue); + StringBuilder defaultEnglishMessage = new StringBuilder("The parameter ").append(parameter) + .append(" must be provided when ").append(parameterName).append(" is ").append(parameterValue); + ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), + parameter, value, parameterName, parameterValue); + dataValidationErrors.add(error); + return this; + } + public DataValidatorBuilder comapareMinimumAndMaximumAmounts(final BigDecimal minimumBalance, final BigDecimal maximumBalance) { if (minimumBalance != null && maximumBalance != null) if (maximumBalance.compareTo(minimumBalance) == -1) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/ReportsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/ReportsApiResource.java index aa94ba2e1..d2c6481f8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/ReportsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/ReportsApiResource.java @@ -14,8 +14,10 @@ import java.util.Map; import java.util.Set; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -111,6 +113,36 @@ public class ReportsApiResource { return this.toApiJsonSerializer.serialize(result); } + @PUT + @Path("{id}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String updateReport(@PathParam("id") final Long id, final String apiRequestBodyAsJson) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder() + .updateReport(id).withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService + .logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + } + + @DELETE + @Path("{id}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String deleteReport(@PathParam("id") final Long id) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder() + .deleteReport(id).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService + .logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + } + @GET @Path("{reportName}") @Consumes({ MediaType.APPLICATION_JSON }) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/domain/Report.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/domain/Report.java index 64b2945c5..c5efb1309 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/domain/Report.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/domain/Report.java @@ -66,15 +66,13 @@ public class Report extends AbstractPersistable { .stringValueOfParameterNamed("reportCategory"); final String description = command .stringValueOfParameterNamed("description"); - final boolean coreReport = command - .booleanPrimitiveValueOfParameterNamed("coreReport"); final boolean useReport = command .booleanPrimitiveValueOfParameterNamed("useReport"); final String reportSql = command .stringValueOfParameterNamed("reportSql"); return new Report(reportName, reportType, reportSubType, - reportCategory, description, coreReport, useReport, reportSql); + reportCategory, description, useReport, reportSql); } protected Report() { @@ -83,14 +81,14 @@ public class Report extends AbstractPersistable { public Report(final String reportName, final String reportType, final String reportSubType, final String reportCategory, - final String description, final boolean coreReport, + final String description, final boolean useReport, final String reportSql) { this.reportName = reportName; this.reportType = reportType; this.reportSubType = reportSubType; this.reportCategory = reportCategory; this.description = description; - this.coreReport = coreReport; + this.coreReport = false; this.useReport = useReport; this.reportSql = reportSql; } @@ -100,7 +98,7 @@ public class Report extends AbstractPersistable { final Map actualChanges = new LinkedHashMap(8); String paramName = "reportName"; - if (command.isChangeInStringParameterNamed(paramName, this.reportName)) { + if (command.isChangeInStringParameterNamed(paramName, this.reportName)) { final String newValue = command.stringValueOfParameterNamed(paramName); actualChanges.put(paramName, newValue); this.reportName = StringUtils.defaultIfEmpty(newValue, null); @@ -129,12 +127,6 @@ public class Report extends AbstractPersistable { actualChanges.put(paramName, newValue); this.description = StringUtils.defaultIfEmpty(newValue, null); } - paramName = "coreReport"; - if (command.isChangeInBooleanParameterNamed(paramName, this.coreReport)) { - final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(paramName); - actualChanges.put(paramName, newValue); - this.coreReport = newValue; - } paramName = "useReport"; if (command.isChangeInBooleanParameterNamed(paramName, this.useReport)) { final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(paramName); @@ -150,5 +142,9 @@ public class Report extends AbstractPersistable { return actualChanges; } + + public boolean isCoreReport() { + return coreReport; + } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/CreateReportCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/CreateReportCommandHandler.java new file mode 100644 index 000000000..497ad616a --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/CreateReportCommandHandler.java @@ -0,0 +1,33 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.infrastructure.dataqueries.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.dataqueries.service.ReportWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class CreateReportCommandHandler implements NewCommandSourceHandler { + + private final ReportWritePlatformService writePlatformService; + + @Autowired + public CreateReportCommandHandler( + final ReportWritePlatformService writePlatformService) { + this.writePlatformService = writePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + + return this.writePlatformService.createReport(command); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/DeleteReportCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/DeleteReportCommandHandler.java new file mode 100644 index 000000000..497e42f07 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/DeleteReportCommandHandler.java @@ -0,0 +1,39 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.infrastructure.dataqueries.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; +import org.mifosplatform.infrastructure.dataqueries.service.ReportWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class DeleteReportCommandHandler implements NewCommandSourceHandler { + + private final ReportWritePlatformService writePlatformService; + + @Autowired + public DeleteReportCommandHandler( + final ReportWritePlatformService writePlatformService) { + this.writePlatformService = writePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + + this.writePlatformService.deleteReport(command.entityId()); + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(command.entityId()) // + .build(); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/UpdateReportCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/UpdateReportCommandHandler.java new file mode 100644 index 000000000..66fc1d6fb --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/UpdateReportCommandHandler.java @@ -0,0 +1,34 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.infrastructure.dataqueries.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.dataqueries.service.ReportWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class UpdateReportCommandHandler implements NewCommandSourceHandler { + + private final ReportWritePlatformService writePlatformService; + + @Autowired + public UpdateReportCommandHandler( + final ReportWritePlatformService writePlatformService) { + this.writePlatformService = writePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + + return this.writePlatformService.updateReport(command.entityId(), + command); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/serialization/ReportCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/serialization/ReportCommandFromApiJsonDeserializer.java index d2b4d14d4..01e8552ba 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/serialization/ReportCommandFromApiJsonDeserializer.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/serialization/ReportCommandFromApiJsonDeserializer.java @@ -43,38 +43,15 @@ public final class ReportCommandFromApiJsonDeserializer { this.fromApiJsonHelper = fromApiJsonHelper; } - public void validateForCreate(final String json) { - if (StringUtils.isBlank(json)) { - throw new InvalidJsonException(); - } - - final Type typeOfMap = new TypeToken>() { - }.getType(); - fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, - supportedParameters); - - final List dataValidationErrors = new ArrayList(); - final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder( - dataValidationErrors).resource("report"); - - final JsonElement element = fromApiJsonHelper.parse(json); -/* WIP JPW - Arrays.asList("reportName", "reportType", "reportSubType", - "reportCategory", "reportSql", "useReport")); - final String name = fromApiJsonHelper.extractStringNamed("name", - element); - baseDataValidator.reset().parameter("name").value(name).notBlank() - .notExceedingLengthOf(100); - - final String externalId = fromApiJsonHelper.extractStringNamed( - "externalId", element); - baseDataValidator.reset().parameter("externalId").value(externalId) - .notExceedingLengthOf(100); -*/ - throwExceptionIfValidationWarningsExist(dataValidationErrors); + public void validate_for_create(final String json) { + validate(json, "create"); } - public void validateForUpdate(final String json) { + public void validate_for_update(final String json) { + validate(json, "update"); + } + + private void validate(final String json, final String commandType) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } @@ -83,28 +60,82 @@ public final class ReportCommandFromApiJsonDeserializer { }.getType(); fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); + // wip jpw + boolean isCreate = false; + if (commandType.equals("create")) + isCreate = true; final List dataValidationErrors = new ArrayList(); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder( dataValidationErrors).resource("report"); final JsonElement element = fromApiJsonHelper.parse(json); - - /* wip jpw - if (fromApiJsonHelper.parameterExists("name", element)) { - final String name = fromApiJsonHelper.extractStringNamed("name", - element); - baseDataValidator.reset().parameter("name").value(name).notBlank() - .notExceedingLengthOf(100); + + String paramName = "reportName"; + String paramValueStr = fromApiJsonHelper.extractStringNamed(paramName, + element); + + baseDataValidator.reset().parameter(paramName).value(paramValueStr) + .notBlank().notExceedingLengthOf(100); + + String paramReportType = fromApiJsonHelper.extractStringNamed( + "reportType", element); + paramName = "reportType"; + paramValueStr = fromApiJsonHelper + .extractStringNamed(paramName, element); + baseDataValidator + .reset() + .parameter(paramName) + .value(paramValueStr) + .notBlank() + .notExceedingLengthOf(20) + .isOneOfTheseValues( + new Object[] { "Table", "Pentaho", "Chart" }); + + paramName = "reportSubType"; + paramValueStr = fromApiJsonHelper + .extractStringNamed(paramName, element); + baseDataValidator.reset().parameter(paramName).value(paramValueStr) + .notExceedingLengthOf(20); + if (paramReportType != null) { + if (paramReportType.equals("Chart")) { + baseDataValidator + .reset() + .parameter(paramName) + .value(paramValueStr) + .cantBeBlankWhenParameterProvidedIs("reportType", + paramReportType) + .isOneOfTheseValues(new Object[] { "Bar", "Pie" }); + } } - if (fromApiJsonHelper.parameterExists("externalId", element)) { - final String externalId = fromApiJsonHelper.extractStringNamed( - "externalId", element); - baseDataValidator.reset().parameter("externalId").value(externalId) - .notExceedingLengthOf(100); + paramName = "reportCategory"; + paramValueStr = fromApiJsonHelper + .extractStringNamed(paramName, element); + baseDataValidator.reset().parameter(paramName).value(paramValueStr) + .notExceedingLengthOf(45); + + paramName = "reportSql"; + paramValueStr = fromApiJsonHelper + .extractStringNamed(paramName, element); + if (paramReportType != null) { + if ((paramReportType.equals("Table")) + || (paramReportType.equals("Chart"))) { + baseDataValidator + .reset() + .parameter(paramName) + .value(paramValueStr) + .cantBeBlankWhenParameterProvidedIs("reportType", + paramReportType); + } else { + baseDataValidator + .reset() + .parameter(paramName) + .value(paramValueStr) + .mustBeBlankWhenParameterProvidedIs("reportType", + paramReportType); + } } -*/ throwExceptionIfValidationWarningsExist(dataValidationErrors); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReportWritePlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReportWritePlatformServiceImpl.java index a8d1f6d85..953ae4014 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReportWritePlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReportWritePlatformServiceImpl.java @@ -51,7 +51,7 @@ public class ReportWritePlatformServiceImpl implements try { context.authenticatedUser(); - this.fromApiJsonDeserializer.validateForCreate(command.json()); + this.fromApiJsonDeserializer.validate_for_create(command.json()); final Report report = Report.fromJson(command); @@ -74,7 +74,7 @@ public class ReportWritePlatformServiceImpl implements try { context.authenticatedUser(); - this.fromApiJsonDeserializer.validateForUpdate(command.json()); + this.fromApiJsonDeserializer.validate_for_update(command.json()); final Report report = this.reportRepository.findOne(reportId); if (report == null) { @@ -83,6 +83,16 @@ public class ReportWritePlatformServiceImpl implements final Map changes = report.update(command); if (!changes.isEmpty()) { + if (report.isCoreReport()) { + for (final String key : changes.keySet()) { + if (!(key.equals("useReport"))) { + throw new PlatformDataIntegrityException( + "error.msg.only.use.report.can.be.updated.for.core.report", + "Only the Use Report field can be updated for Core Reports", + key); + } + } + } this.reportRepository.saveAndFlush(report); } @@ -104,6 +114,12 @@ public class ReportWritePlatformServiceImpl implements throw new ReportNotFoundException(reportId); } + if (report.isCoreReport()) { + throw new PlatformDataIntegrityException( + "error.msg.cant.delete.core.report", + "Core Reports Can't be Deleted", ""); + } + this.reportRepository.delete(report); return new CommandProcessingResultBuilder().withEntityId(reportId)