MIFOSX-97: add status for processing result of commands.

This commit is contained in:
Keith Woodlock
2012-12-14 13:46:24 +00:00
parent 8424d52325
commit 7a7654e75f
24 changed files with 541 additions and 437 deletions
@@ -0,0 +1,22 @@
drop table if exists `m_portfolio_command_source`;
CREATE TABLE `m_portfolio_command_source` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`action_name` varchar(50) NOT NULL,
`entity_name` varchar(50) NOT NULL,
`api_operation` varchar(30) NOT NULL,
`api_resource` varchar(100) NOT NULL,
`resource_id` bigint(20) DEFAULT NULL,
`api_subresource` varchar(100) DEFAULT NULL,
`subresource_id` bigint(20) DEFAULT NULL,
`command_as_json` text NOT NULL,
`maker_id` bigint(20) NOT NULL,
`made_on_date` datetime NOT NULL,
`checker_id` bigint(20) DEFAULT NULL,
`checked_on_date` datetime DEFAULT NULL,
`processing_result_enum` smallint(5) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_m_maker_m_appuser` (`maker_id`),
KEY `FK_m_checker_m_appuser` (`checker_id`),
CONSTRAINT `FK_m_checker_m_appuser` FOREIGN KEY (`checker_id`) REFERENCES `m_appuser` (`id`),
CONSTRAINT `FK_m_maker_m_appuser` FOREIGN KEY (`maker_id`) REFERENCES `m_appuser` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -60,7 +60,7 @@ public class CommandsApiResource {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveCodes(@Context final UriInfo uriInfo) {
public String retrieveCommands(@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
@@ -0,0 +1,41 @@
package org.mifosplatform.commands.domain;
public enum CommandProcessingResultType {
INVALID(0, "commandProcessingResultType.invalid"), //
PROCESSED(1, "commandProcessingResultType.processed"), //
AWAITING_APPROVAL(2, "commandProcessingResultType.awaiting.approval"), //
REJECTED(3, "commandProcessingResultType.rejected");
private final Integer value;
private final String code;
private CommandProcessingResultType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
public Integer getValue() {
return value;
}
public String getCode() {
return code;
}
public static CommandProcessingResultType fromInt(final Integer typeValue) {
CommandProcessingResultType type = CommandProcessingResultType.INVALID;
switch (typeValue) {
case 1:
type = PROCESSED;
break;
case 2:
type = AWAITING_APPROVAL;
break;
case 3:
type = REJECTED;
break;
}
return type;
}
}
@@ -20,8 +20,11 @@ import org.springframework.data.jpa.domain.AbstractPersistable;
@Table(name = "m_portfolio_command_source")
public class CommandSource extends AbstractPersistable<Long> {
@Column(name = "permission_code", length = 50)
private String permissionCode;
@Column(name = "action_name", nullable = true, length = 100)
private String actionName;
@Column(name = "entity_name", nullable = true, length = 100)
private String entityName;
@Column(name = "api_operation", length = 30)
private String apiOperation;
@@ -60,9 +63,12 @@ public class CommandSource extends AbstractPersistable<Long> {
@Column(name = "checked_on_date", nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date checkedOnDate;
@Column(name = "processing_result_enum", nullable = false)
private Integer processingResult;
public static CommandSource fullEntryFrom(final CommandWrapper wrapper, final JsonCommand command, final AppUser maker) {
return new CommandSource(wrapper.taskPermissionName(), wrapper.operation(), wrapper.resourceName(), command.resourceId(),
return new CommandSource(wrapper.actionName(), wrapper.entityName(), wrapper.operation(), wrapper.resourceName(), command.resourceId(),
wrapper.subResourceName(), command.subResourceId(), command.json(), maker, DateTime.now());
}
@@ -70,10 +76,11 @@ public class CommandSource extends AbstractPersistable<Long> {
//
}
private CommandSource(final String permissionCode, final String apiOperation, final String resource, final Long resourceId,
private CommandSource(final String actionName, final String entityName, final String apiOperation, final String resource, final Long resourceId,
final String subResource, final Long subResourceId, final String commandSerializedAsJson, final AppUser maker,
final DateTime madeOnDateTime) {
this.permissionCode = permissionCode;
this.actionName = actionName;
this.entityName = entityName;
this.apiOperation = StringUtils.defaultIfEmpty(apiOperation, null);
this.resource = StringUtils.defaultIfEmpty(resource, null);
this.resourceId = resourceId;
@@ -82,11 +89,13 @@ public class CommandSource extends AbstractPersistable<Long> {
this.commandAsJson = commandSerializedAsJson;
this.maker = maker;
this.madeOnDate = madeOnDateTime.toDate();
this.processingResult = CommandProcessingResultType.PROCESSED.getValue();
}
public void markAsChecked(final AppUser checker, final DateTime checkedOnDate) {
this.checker = checker;
this.checkedOnDate = checkedOnDate.toDate();
this.processingResult = CommandProcessingResultType.PROCESSED.getValue();
}
public void updateResourceId(final Long resourceId) {
@@ -124,9 +133,17 @@ public class CommandSource extends AbstractPersistable<Long> {
public String operation() {
return this.apiOperation;
}
public String getActionName() {
return this.actionName;
}
public String getEntityName() {
return this.entityName;
}
public String getPermissionCode() {
return this.permissionCode;
return this.actionName + "_" + this.entityName;
}
public String getResource() {
@@ -144,4 +161,8 @@ public class CommandSource extends AbstractPersistable<Long> {
public Long getSubResourceId() {
return this.subResourceId;
}
public void markAsAwaitingApproval() {
this.processingResult = CommandProcessingResultType.AWAITING_APPROVAL.getValue();
}
}
@@ -3,32 +3,34 @@ package org.mifosplatform.commands.domain;
public class CommandWrapper {
private final Long commandId;
private final String actionName;
private final String entityName;
private final String apiOperation;
private final String resource;
private final Long resourceId;
private final String taskPermissionName;
private final String subResource;
private final Long subResourceId;
public static CommandWrapper wrap(final String taskPermissionName, final String apiOperation, final String resource,
public static CommandWrapper wrap(final String actionName, final String enityName, final String apiOperation, final String resource,
final Long resourceId) {
return new CommandWrapper(null, taskPermissionName, apiOperation, resource, resourceId, null, null);
return new CommandWrapper(null, actionName, enityName, apiOperation, resource, resourceId, null, null);
}
public static CommandWrapper wrap(final String taskPermissionName, final String apiOperation, final String resource,
public static CommandWrapper wrap(final String actionName, final String enityName, final String apiOperation, final String resource,
final Long resourceId, final String subResource, final Long subRescourceId) {
return new CommandWrapper(null, taskPermissionName, apiOperation, resource, resourceId, subResource, subRescourceId);
}
public static CommandWrapper fromExistingCommand(final Long commandId, final String taskPermissionName, final String apiOperation, final String resource,
final Long resourceId, final String subResource, final Long subRescourceId) {
return new CommandWrapper(commandId, taskPermissionName, apiOperation, resource, resourceId, subResource, subRescourceId);
return new CommandWrapper(null, actionName, enityName, apiOperation, resource, resourceId, subResource, subRescourceId);
}
private CommandWrapper(final Long commandId, final String taskPermissionName, final String apiOperation, final String resource,
final Long resourceId, final String subResource, final Long subResourceId) {
public static CommandWrapper fromExistingCommand(final Long commandId, final String actionName, final String enityName,
final String apiOperation, final String resource, final Long resourceId, final String subResource, final Long subRescourceId) {
return new CommandWrapper(commandId, actionName, enityName, apiOperation, resource, resourceId, subResource, subRescourceId);
}
private CommandWrapper(final Long commandId, final String actionName, final String enityName, final String apiOperation,
final String resource, final Long resourceId, final String subResource, final Long subResourceId) {
this.commandId = commandId;
this.taskPermissionName = taskPermissionName;
this.actionName = actionName;
this.entityName = enityName;
this.apiOperation = apiOperation;
this.resource = resource;
this.resourceId = resourceId;
@@ -44,6 +46,14 @@ public class CommandWrapper {
return this.commandId;
}
public String actionName() {
return this.actionName;
}
public String entityName() {
return this.entityName;
}
public Long resourceId() {
return this.resourceId;
}
@@ -61,7 +71,7 @@ public class CommandWrapper {
}
public String taskPermissionName() {
return this.taskPermissionName;
return this.actionName + "_" + this.entityName;
}
public String operation() {
@@ -149,7 +159,7 @@ public class CommandWrapper {
public boolean isNotesSubResource() {
return "NOTES".equalsIgnoreCase(this.subResource);
}
public boolean isIdentifiersSubResource() {
return "IDENTIFIERS".equalsIgnoreCase(this.subResource);
}
@@ -4,10 +4,10 @@ import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
public interface PortfolioCommandSourceWritePlatformService {
EntityIdentifier logCommandSource(String taskPermissionName, String apiOperation, String resource, Long resourceId, String subResource,
EntityIdentifier logCommandSource(String actionName, String entityName, String apiOperation, String resource, Long resourceId, String subResource,
Long subRescourceId, String json);
EntityIdentifier logCommandSource(String taskPermissionName, String apiOperation, String resource, Long resourceId, String json);
EntityIdentifier logCommandSource(String actionName, String entityName, String apiOperation, String resource, Long resourceId, String json);
EntityIdentifier approveEntry(Long id);
@@ -32,14 +32,16 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
this.fromApiJsonHelper = fromApiJsonHelper;
this.processAndLogCommandService = processAndLogCommandService;
}
@Override
public EntityIdentifier logCommandSource(final String taskPermissionName, final String apiOperation, final String resource,
final Long resourceId, final String subResource, final Long subRescourceId, final String json) {
public EntityIdentifier logCommandSource(final String actionName, final String entityName, final String apiOperation,
final String resource, final Long resourceId, final String subResource, final Long subRescourceId, final String json) {
final String taskPermissionName = actionName + "_" + entityName;
context.authenticatedUser().validateHasPermissionTo(taskPermissionName);
final CommandWrapper wrapper = CommandWrapper.wrap(taskPermissionName, apiOperation, resource, resourceId, subResource, subRescourceId);
final CommandWrapper wrapper = CommandWrapper.wrap(actionName, entityName, apiOperation, resource, resourceId, subResource,
subRescourceId);
EntityIdentifier result = null;
try {
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
@@ -47,12 +49,12 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
final boolean isApprovedByChecker = false;
result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
final String jsonToUse = StringUtils.defaultIfEmpty(e.getJsonOfChangesOnly(), json);
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonToUse);
final JsonCommand command = JsonCommand.from(jsonToUse, parsedCommand, this.fromApiJsonHelper, resourceId, subRescourceId);
result = this.processAndLogCommandService.logCommand(wrapper, command);
}
@@ -60,33 +62,34 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
}
@Override
public EntityIdentifier logCommandSource(final String taskPermissionName, final String apiOperation, final String resource,
public EntityIdentifier logCommandSource(final String actionName, final String entityName, final String apiOperation, final String resource,
final Long resourceId, final String json) {
final String taskPermissionName = actionName + "_" + entityName;
context.authenticatedUser().validateHasPermissionTo(taskPermissionName);
final CommandWrapper wrapper = CommandWrapper.wrap(taskPermissionName, apiOperation, resource, resourceId);
final CommandWrapper wrapper = CommandWrapper.wrap(actionName, entityName, apiOperation, resource, resourceId);
EntityIdentifier result = null;
try {
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
final JsonCommand command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, resourceId, null);
final boolean isApprovedByChecker = false;
result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
final String jsonToUse = StringUtils.defaultIfEmpty(e.getJsonOfChangesOnly(), json);
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonToUse);
final JsonCommand command = JsonCommand.from(jsonToUse, parsedCommand, this.fromApiJsonHelper, resourceId, null);
result = this.processAndLogCommandService.logCommand(wrapper, command);
}
return result;
}
@Override
public EntityIdentifier approveEntry(final Long commandId) {
@@ -94,11 +97,13 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio
context.authenticatedUser().validateHasCheckerPermissionTo(commandSourceInput.getPermissionCode());
final CommandWrapper wrapper = CommandWrapper.fromExistingCommand(commandId, commandSourceInput.getPermissionCode(), commandSourceInput.operation(),
commandSourceInput.resourceName(), commandSourceInput.resourceId(), commandSourceInput.getSubResource(), commandSourceInput.getSubResourceId());
final CommandWrapper wrapper = CommandWrapper.fromExistingCommand(commandId, commandSourceInput.getActionName(),
commandSourceInput.getEntityName(), commandSourceInput.operation(), commandSourceInput.resourceName(),
commandSourceInput.resourceId(), commandSourceInput.getSubResource(), commandSourceInput.getSubResourceId());
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSourceInput.json());
final JsonCommand command = JsonCommand.fromExistingCommand(commandId, commandSourceInput.json(), parsedCommand, this.fromApiJsonHelper, commandSourceInput.resourceId(), commandSourceInput.getSubResourceId());
final JsonCommand command = JsonCommand.fromExistingCommand(commandId, commandSourceInput.json(), parsedCommand,
this.fromApiJsonHelper, commandSourceInput.resourceId(), commandSourceInput.getSubResourceId());
final boolean makerCheckerApproval = true;
return this.processAndLogCommandService.processAndLogCommand(wrapper, command, makerCheckerApproval);
@@ -54,7 +54,7 @@ public class PortfolioCommandsReadPlatformServiceImpl implements PortfolioComman
final CommandSourceMapper rm = new CommandSourceMapper();
final String sql = "select " + rm.schema()
+ " where mc.checker_id is null order by mc.made_on_date DESC, mc.api_resource ASC, mc.api_operation ASC";
+ " where mc.checker_id is null and mc.processing_result_enum = 2 order by mc.made_on_date DESC, mc.api_resource ASC, mc.api_operation ASC";
return this.jdbcTemplate.query(sql, rm, new Object[] {});
}
@@ -74,7 +74,7 @@ public class PortfolioCommandsReadPlatformServiceImpl implements PortfolioComman
final CommandSourceMapper rm = new CommandSourceMapper();
final String sql = "select "
+ rm.schema()
+ " where mc.api_resource like ? and mc.resource_id = ? and mc.checker_id is null order by mc.made_on_date DESC, mc.api_operation ASC";
+ " where mc.api_resource like ? and mc.resource_id = ? and mc.checker_id is null and mc.processing_result_enum = 2 order by mc.made_on_date DESC, mc.api_operation ASC";
return this.jdbcTemplate.query(sql, rm, new Object[] { apiResource, resourceId });
}
@@ -88,6 +88,7 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
final CommandSource commandSourceResult = CommandSource.fullEntryFrom(wrapper, command, maker);
if (commandSourceResult.hasJson()) {
commandSourceResult.markAsAwaitingApproval();
commandSourceRepository.save(commandSourceResult);
}
@@ -75,7 +75,7 @@ public class CodesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createCode(final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CODE", "CREATE", "codes", null,
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "CODE", "CREATE", "codes", null,
apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -99,8 +99,8 @@ public class CodesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateCode(@PathParam("codeId") final Long codeId, final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CODE", "UPDATE", "codes", codeId,
apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "CODE", "UPDATE", "codes",
codeId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -111,8 +111,8 @@ public class CodesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String deleteCodeApplication(@PathParam("codeId") final Long codeId) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_CODE", "DELETE", "codes", codeId,
"{}");
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "CODE", "DELETE", "codes",
codeId, "{}");
return this.toApiJsonSerializer.serialize(result);
}
@@ -70,7 +70,7 @@ public class CurrenciesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateCurrencies(final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CURRENCY", "UPDATE", "currencies",
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "CURRENCY", "UPDATE", "currencies",
null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -87,7 +87,7 @@ public class OfficeTransactionsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String transferMoneyFrom(final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_OFFICETRANSACTION", "CREATE",
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "OFFICETRANSACTION", "CREATE",
"officetransactions", null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -97,7 +97,7 @@ public class OfficesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createOffice(final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_OFFICE", "CREATE", "offices",
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "OFFICE", "CREATE", "offices",
null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -128,7 +128,7 @@ public class OfficesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateOffice(@PathParam("officeId") final Long officeId, final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_OFFICE", "UPDATE", "offices",
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "OFFICE", "UPDATE", "offices",
officeId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -86,8 +86,8 @@ public class StaffApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createStaff(final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_STAFF", "CREATE", "staff", null,
apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "STAFF", "CREATE", "staff",
null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -117,7 +117,7 @@ public class StaffApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateStaff(@PathParam("staffId") final Long staffId, final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_STAFF", "UPDATE", "staff",
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "STAFF", "UPDATE", "staff",
staffId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -108,8 +108,8 @@ public class ChargesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createCharge(final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CHARGE", "CREATE", "charges", null,
apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "CHARGE", "CREATE", "charges",
null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -120,8 +120,8 @@ public class ChargesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateCharge(@PathParam("chargeId") final Long chargeId, final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CHARGE", "UPDATE", "charges", chargeId,
apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "CHARGE", "UPDATE", "charges",
chargeId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -132,7 +132,8 @@ public class ChargesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String deleteCharge(@PathParam("chargeId") final Long chargeId) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_CHARGE", "DELETE", "charges", chargeId, "{}");
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "CHARGE", "DELETE", "charges",
chargeId, "{}");
return this.toApiJsonSerializer.serialize(result);
}
@@ -98,7 +98,7 @@ public class ClientIdentifiersApiResource {
public String createClientIdentifier(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) {
try {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CLIENTIDENTIFIER", "CREATE",
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "CLIENTIDENTIFIER", "CREATE",
"clients", clientId, "identifiers", null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -143,7 +143,7 @@ public class ClientIdentifiersApiResource {
@PathParam("identifierId") final Long clientIdentifierId, final String apiRequestBodyAsJson) {
try {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CLIENTIDENTIFIER", "UPDATE",
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "CLIENTIDENTIFIER", "UPDATE",
"clients", clientId, "identifiers", clientIdentifierId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -166,7 +166,7 @@ public class ClientIdentifiersApiResource {
public String deleteClientIdentifier(@PathParam("clientId") final Long clientId,
@PathParam("identifierId") final Long clientIdentifierId) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_CLIENTIDENTIFIER", "DELETE",
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "CLIENTIDENTIFIER", "DELETE",
"clients", clientId, "identifiers", clientIdentifierId, "{}");
return this.toApiJsonSerializer.serialize(result);
@@ -71,7 +71,7 @@ public class ClientNotesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String addNewClientNote(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CLIENTNOTE", "CREATE",
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "CLIENTNOTE", "CREATE",
"clients", clientId, "notes", null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -99,7 +99,7 @@ public class ClientNotesApiResource {
public String updateClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId,
final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CLIENTNOTE", "UPDATE",
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "CLIENTNOTE", "UPDATE",
"clients", clientId, "notes", noteId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -213,8 +213,8 @@ public class ClientsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createClient(final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CLIENT", "CREATE", "clients", null,
apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "CLIENT", "CREATE", "clients",
null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -225,8 +225,8 @@ public class ClientsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateClient(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CLIENT", "UPDATE", "clients", clientId,
apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "CLIENT", "UPDATE", "clients",
clientId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -237,7 +237,8 @@ public class ClientsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String deleteClient(@PathParam("clientId") final Long clientId) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_CLIENT", "DELETE", "clients", clientId, "{}");
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "CLIENT", "DELETE", "clients",
clientId, "{}");
return this.toApiJsonSerializer.serialize(result);
}
@@ -76,7 +76,7 @@ public class FundsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createFund(final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_FUND", "CREATE", "funds", null,
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "FUND", "CREATE", "funds", null,
apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -102,8 +102,8 @@ public class FundsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateFund(@PathParam("fundId") final Long fundId, final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_FUND", "UPDATE", "funds", fundId,
apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "FUND", "UPDATE", "funds",
fundId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -25,54 +25,54 @@ import org.mifosplatform.portfolio.charge.exception.LoanChargeWithoutMandatoryFi
import org.mifosplatform.portfolio.loanaccount.command.LoanChargeCommand;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Entity
@Table(name = "m_loan_charge")
public class LoanCharge extends AbstractPersistable<Long> {
@ManyToOne(optional = false)
@JoinColumn(name = "loan_id", referencedColumnName = "id", nullable=false)
@JoinColumn(name = "loan_id", referencedColumnName = "id", nullable = false)
private Loan loan;
@ManyToOne(optional = false)
@JoinColumn(name = "charge_id", referencedColumnName = "id", nullable=false)
@JoinColumn(name = "charge_id", referencedColumnName = "id", nullable = false)
private Charge charge;
@Column(name = "charge_time_enum", nullable = false)
private Integer chargeTime;
@Temporal(TemporalType.DATE)
@Column(name = "due_for_collection_as_of_date")
private Date dueForCollectionAsOfDate;
@Temporal(TemporalType.DATE)
@Column(name = "due_for_collection_as_of_date")
private Date dueForCollectionAsOfDate;
@Column(name = "charge_calculation_enum")
private Integer chargeCalculation;
@Column(name = "calculation_percentage", scale = 6, precision = 19, nullable = true)
private BigDecimal percentage;
@Column(name = "calculation_on_amount", scale = 6, precision = 19, nullable = true)
private BigDecimal amountPercentageAppliedTo;
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
private BigDecimal amount;
@Column(name = "amount_paid_derived", scale = 6, precision = 19, nullable = true)
private BigDecimal amountPaid;
@Column(name = "amount_waived_derived", scale = 6, precision = 19, nullable = true)
@Column(name = "amount_waived_derived", scale = 6, precision = 19, nullable = true)
private BigDecimal amountWaived;
@Column(name = "amount_writtenoff_derived", scale = 6, precision = 19, nullable = true)
private BigDecimal amountWrittenOff;
@Column(name = "amount_outstanding_derived", scale = 6, precision = 19, nullable = false)
@Column(name = "amount_outstanding_derived", scale = 6, precision = 19, nullable = false)
private BigDecimal amountOutstanding;
@Column(name = "is_penalty", nullable=false)
private boolean penaltyCharge = false;
@Column(name = "is_paid_derived", nullable=false)
private boolean paid = false;
@Column(name = "is_penalty", nullable = false)
private boolean penaltyCharge = false;
@Column(name = "is_paid_derived", nullable = false)
private boolean paid = false;
public static LoanCharge createNew(final Loan loan, final Charge chargeDefinition, final LoanChargeCommand command) {
return new LoanCharge(loan, chargeDefinition, command);
@@ -81,396 +81,398 @@ public class LoanCharge extends AbstractPersistable<Long> {
/*
* loanPrincipal is required for charges that are percentage based
*/
public static LoanCharge createNewWithoutLoan(final Charge chargeDefinition, final LoanChargeCommand command, final BigDecimal loanPrincipal) {
return new LoanCharge(chargeDefinition, command, loanPrincipal);
}
public static LoanCharge createNew(final Charge chargeDefinition) {
return new LoanCharge(null, chargeDefinition);
}
public static LoanCharge createNewWithoutLoan(final Charge chargeDefinition, final LoanChargeCommand command,
final BigDecimal loanPrincipal) {
return new LoanCharge(chargeDefinition, command, loanPrincipal);
}
public static LoanCharge createNew(final Charge chargeDefinition) {
return new LoanCharge(null, chargeDefinition);
}
protected LoanCharge() {
//
//
}
public LoanCharge(final Charge chargeDefinition, final LoanChargeCommand command, final BigDecimal loanPrincipal) {
this.loan = null;
this.charge = chargeDefinition;
this.penaltyCharge = chargeDefinition.isPenalty();
if (command.isChargeTimeTypeChanged()) {
this.chargeTime = command.getChargeTimeType();
} else {
this.chargeTime = chargeDefinition.getChargeTime();
}
if (ChargeTimeType.fromInt(this.chargeTime).equals(ChargeTimeType.SPECIFIED_DUE_DATE)) {
if (command.getSpecifiedDueDate() == null) {
final String defaultUserMessage = "Loan charge is missing specified due date";
throw new LoanChargeWithoutMandatoryFieldException("loancharge", "specifiedDueDate", defaultUserMessage, command.getId(), chargeDefinition.getName());
}
this.dueForCollectionAsOfDate = command.getSpecifiedDueDate().toDate();
} else {
this.dueForCollectionAsOfDate = null;
}
if (command.isChargeCalculationTypeChanged()) {
this.chargeCalculation = command.getChargeCalculationType();
} else {
this.chargeCalculation = chargeDefinition.getChargeCalculation();
}
BigDecimal chargeAmount = chargeDefinition.getAmount();
if (command.isAmountChanged()){
chargeAmount = command.getAmount();
}
populateDerivedFields(loanPrincipal, chargeAmount);
this.paid = determineIfFullyPaid();
}
private LoanCharge(final Loan loan, final Charge chargeDefinition, final LoanChargeCommand command) {
this.loan = loan;
public LoanCharge(final Charge chargeDefinition, final LoanChargeCommand command, final BigDecimal loanPrincipal) {
this.loan = null;
this.charge = chargeDefinition;
this.penaltyCharge = chargeDefinition.isPenalty();
if (command.isChargeTimeTypeChanged()){
if (command.isChargeTimeTypeChanged()) {
this.chargeTime = command.getChargeTimeType();
} else {
this.chargeTime = chargeDefinition.getChargeTime();
}
if (ChargeTimeType.fromInt(this.chargeTime).equals(ChargeTimeType.SPECIFIED_DUE_DATE)) {
if (command.getSpecifiedDueDate() == null) {
final String defaultUserMessage = "Loan charge is missing specified due date";
throw new LoanChargeWithoutMandatoryFieldException(
"loancharge", "specifiedDueDate", defaultUserMessage,
command.getId(), chargeDefinition.getName());
}
if (ChargeTimeType.fromInt(this.chargeTime).equals(ChargeTimeType.SPECIFIED_DUE_DATE)) {
this.dueForCollectionAsOfDate = command.getSpecifiedDueDate().toDate();
} else {
this.dueForCollectionAsOfDate = null;
}
if (command.getSpecifiedDueDate() == null) {
final String defaultUserMessage = "Loan charge is missing specified due date";
throw new LoanChargeWithoutMandatoryFieldException("loancharge", "specifiedDueDate", defaultUserMessage, command.getId(),
chargeDefinition.getName());
}
if (command.isChargeCalculationTypeChanged()){
this.dueForCollectionAsOfDate = command.getSpecifiedDueDate().toDate();
} else {
this.dueForCollectionAsOfDate = null;
}
if (command.isChargeCalculationTypeChanged()) {
this.chargeCalculation = command.getChargeCalculationType();
} else {
this.chargeCalculation = chargeDefinition.getChargeCalculation();
}
BigDecimal chargeAmount = chargeDefinition.getAmount();
if (command.isAmountChanged()){
chargeAmount = command.getAmount();
if (command.isAmountChanged()) {
chargeAmount = command.getAmount();
}
populateDerivedFields(loanPrincipal, chargeAmount);
this.paid = determineIfFullyPaid();
}
private LoanCharge(final Loan loan, final Charge chargeDefinition, final LoanChargeCommand command) {
this.loan = loan;
this.charge = chargeDefinition;
this.penaltyCharge = chargeDefinition.isPenalty();
if (command.isChargeTimeTypeChanged()) {
this.chargeTime = command.getChargeTimeType();
} else {
this.chargeTime = chargeDefinition.getChargeTime();
}
if (ChargeTimeType.fromInt(this.chargeTime).equals(ChargeTimeType.SPECIFIED_DUE_DATE)) {
if (command.getSpecifiedDueDate() == null) {
final String defaultUserMessage = "Loan charge is missing specified due date";
throw new LoanChargeWithoutMandatoryFieldException("loancharge", "specifiedDueDate", defaultUserMessage, command.getId(),
chargeDefinition.getName());
}
this.dueForCollectionAsOfDate = command.getSpecifiedDueDate().toDate();
} else {
this.dueForCollectionAsOfDate = null;
}
if (command.isChargeCalculationTypeChanged()) {
this.chargeCalculation = command.getChargeCalculationType();
} else {
this.chargeCalculation = chargeDefinition.getChargeCalculation();
}
BigDecimal chargeAmount = chargeDefinition.getAmount();
if (command.isAmountChanged()) {
chargeAmount = command.getAmount();
}
populateDerivedFields(loan.getPrincpal().getAmount(), chargeAmount);
this.paid = determineIfFullyPaid();
}
private void populateDerivedFields(final BigDecimal loanPrincipal, final BigDecimal chargeAmount) {
switch (ChargeCalculationType.fromInt(this.chargeCalculation)) {
case INVALID:
this.percentage = null;
this.amount = null;
this.amountPercentageAppliedTo = null;
this.amountPaid = null;
this.amountOutstanding = BigDecimal.ZERO;
this.amountWaived = null;
this.amountWrittenOff = null;
break;
case FLAT:
this.percentage = null;
this.amount = chargeAmount;
this.amountPercentageAppliedTo = null;
this.amountPaid = null;
this.amountOutstanding = chargeAmount;
this.amountWaived = null;
this.amountWrittenOff = null;
break;
case PERCENT_OF_AMOUNT:
this.percentage = chargeAmount;
this.amountPercentageAppliedTo = loanPrincipal;
this.amount = percentageOf(this.amountPercentageAppliedTo, this.percentage);
this.amountPaid = null;
this.amountOutstanding = calculateOutstanding();
this.amountWaived = null;
this.amountWrittenOff = null;
break;
case PERCENT_OF_AMOUNT_AND_INTEREST:
this.percentage = null;
this.amount = null;
this.amountPercentageAppliedTo = null;
this.amountPaid = null;
this.amountOutstanding = BigDecimal.ZERO;
this.amountWaived = null;
this.amountWrittenOff = null;
break;
case PERCENT_OF_INTEREST:
this.percentage = null;
this.amount = null;
this.amountPercentageAppliedTo = null;
this.amountPaid = null;
this.amountOutstanding = BigDecimal.ZERO;
this.amountWaived = null;
this.amountWrittenOff = null;
break;
}
}
private void populateDerivedFields(final BigDecimal loanPrincipal, final BigDecimal chargeAmount) {
private LoanCharge(final Loan loan, final Charge chargeDefinition) {
this(loan, chargeDefinition, chargeDefinition.getAmount(), chargeDefinition.getChargeTime(), chargeDefinition.getChargeCalculation());
switch (ChargeCalculationType.fromInt(this.chargeCalculation)) {
case INVALID:
this.percentage = null;
this.amount = null;
this.amountPercentageAppliedTo = null;
this.amountPaid = null;
this.amountOutstanding = BigDecimal.ZERO;
this.amountWaived = null;
this.amountWrittenOff = null;
break;
case FLAT:
this.percentage = null;
this.amount = chargeAmount;
this.amountPercentageAppliedTo = null;
this.amountPaid = null;
this.amountOutstanding = chargeAmount;
this.amountWaived = null;
this.amountWrittenOff = null;
break;
case PERCENT_OF_AMOUNT:
this.percentage = chargeAmount;
this.amountPercentageAppliedTo = loanPrincipal;
this.amount = percentageOf(this.amountPercentageAppliedTo, this.percentage);
this.amountPaid = null;
this.amountOutstanding = calculateOutstanding();
this.amountWaived = null;
this.amountWrittenOff = null;
break;
case PERCENT_OF_AMOUNT_AND_INTEREST:
this.percentage = null;
this.amount = null;
this.amountPercentageAppliedTo = null;
this.amountPaid = null;
this.amountOutstanding = BigDecimal.ZERO;
this.amountWaived = null;
this.amountWrittenOff = null;
break;
case PERCENT_OF_INTEREST:
this.percentage = null;
this.amount = null;
this.amountPercentageAppliedTo = null;
this.amountPaid = null;
this.amountOutstanding = BigDecimal.ZERO;
this.amountWaived = null;
this.amountWrittenOff = null;
break;
}
}
private LoanCharge(final Loan loan, final Charge charge, final BigDecimal amount, final Integer chargeTime, final Integer chargeCalculation) {
private LoanCharge(final Loan loan, final Charge chargeDefinition) {
this(loan, chargeDefinition, chargeDefinition.getAmount(), chargeDefinition.getChargeTime(), chargeDefinition
.getChargeCalculation());
}
private LoanCharge(final Loan loan, final Charge charge, final BigDecimal amount, final Integer chargeTime,
final Integer chargeCalculation) {
this.loan = loan;
this.charge = charge;
this.amount = amount;
this.chargeTime = chargeTime;
this.chargeCalculation = chargeCalculation;
}
public void markAsFullyPaid() {
this.amountPaid = this.amount;
this.amountOutstanding = BigDecimal.ZERO;
this.paid = true;
}
this.amountPaid = this.amount;
this.amountOutstanding = BigDecimal.ZERO;
this.paid = true;
}
public void resetToOriginal(final MonetaryCurrency currency) {
this.amountPaid = BigDecimal.ZERO;
this.amountWaived = BigDecimal.ZERO;
this.amountWrittenOff = BigDecimal.ZERO;
this.amountOutstanding = calculateAmountOutstanding(currency);
this.paid = false;
}
public void resetPaidAmount(final MonetaryCurrency currency) {
this.amountPaid = BigDecimal.ZERO;
this.amountOutstanding = calculateAmountOutstanding(currency);
this.paid = false;
}
public void resetToOriginal(final MonetaryCurrency currency) {
this.amountPaid = BigDecimal.ZERO;
this.amountWaived = BigDecimal.ZERO;
this.amountWrittenOff = BigDecimal.ZERO;
this.amountOutstanding = calculateAmountOutstanding(currency);
this.paid = false;
}
public void resetPaidAmount(final MonetaryCurrency currency) {
this.amountPaid = BigDecimal.ZERO;
this.amountOutstanding = calculateAmountOutstanding(currency);
this.paid = false;
}
public Money waive(final MonetaryCurrency currency) {
this.amountWaived = this.amount;
this.amountOutstanding = calculateAmountOutstanding(currency);
this.paid = determineIfFullyPaid();
return getAmountWaived(currency);
}
this.amountWaived = this.amount;
this.amountOutstanding = calculateAmountOutstanding(currency);
this.paid = determineIfFullyPaid();
return getAmountWaived(currency);
}
private BigDecimal calculateAmountOutstanding(final MonetaryCurrency currency) {
return getAmount(currency).minus(getAmountWaived(currency)).minus(getAmountPaid(currency)).getAmount();
}
private BigDecimal calculateAmountOutstanding(final MonetaryCurrency currency) {
return getAmount(currency).minus(getAmountWaived(currency)).minus(getAmountPaid(currency)).getAmount();
}
public void update(final Loan loan) {
this.loan = loan;
}
public void update(final Loan loan) {
this.loan = loan;
}
public void update(final LoanChargeCommand command, final BigDecimal loanPrincipal){
public void update(final LoanChargeCommand command, final BigDecimal loanPrincipal) {
if (command.isChargeTimeTypeChanged()){
if (command.isChargeTimeTypeChanged()) {
this.chargeTime = ChargeTimeType.fromInt(command.getChargeTimeType()).getValue();
}
if (command.isChargeCalculationTypeChanged()){
if (command.isChargeCalculationTypeChanged()) {
this.chargeCalculation = ChargeCalculationType.fromInt(command.getChargeCalculationType()).getValue();
}
if (command.isSpecifiedDueDateChanged()) {
this.dueForCollectionAsOfDate = command.getSpecifiedDueDate().toDate();
this.dueForCollectionAsOfDate = command.getSpecifiedDueDate().toDate();
}
if (command.isAmountChanged()) {
switch (ChargeCalculationType.fromInt(this.chargeCalculation)) {
case INVALID:
break;
case FLAT:
this.amount = command.getAmount();
break;
case PERCENT_OF_AMOUNT:
this.percentage = command.getAmount();
this.amountPercentageAppliedTo = loanPrincipal;
this.amount = percentageOf(this.amountPercentageAppliedTo, this.percentage);
this.amountOutstanding = calculateOutstanding();
break;
case PERCENT_OF_AMOUNT_AND_INTEREST:
this.percentage = command.getAmount();
this.amount = null;
this.amountPercentageAppliedTo = null;
this.amountOutstanding = null;
break;
case PERCENT_OF_INTEREST:
this.percentage = command.getAmount();
this.amount = null;
this.amountPercentageAppliedTo = null;
this.amountOutstanding = null;
break;
}
case INVALID:
break;
case FLAT:
this.amount = command.getAmount();
break;
case PERCENT_OF_AMOUNT:
this.percentage = command.getAmount();
this.amountPercentageAppliedTo = loanPrincipal;
this.amount = percentageOf(this.amountPercentageAppliedTo, this.percentage);
this.amountOutstanding = calculateOutstanding();
break;
case PERCENT_OF_AMOUNT_AND_INTEREST:
this.percentage = command.getAmount();
this.amount = null;
this.amountPercentageAppliedTo = null;
this.amountOutstanding = null;
break;
case PERCENT_OF_INTEREST:
this.percentage = command.getAmount();
this.amount = null;
this.amountPercentageAppliedTo = null;
this.amountOutstanding = null;
break;
}
}
}
public boolean isDueAtDisbursement() {
return ChargeTimeType.fromInt(this.chargeTime).equals(ChargeTimeType.DISBURSEMENT);
}
public boolean isSpecifiedDueDate() {
return ChargeTimeType.fromInt(this.chargeTime).equals(ChargeTimeType.SPECIFIED_DUE_DATE);
}
public boolean isDueAtDisbursement() {
return ChargeTimeType.fromInt(this.chargeTime).equals(ChargeTimeType.DISBURSEMENT);
}
private boolean isGreaterThanZero(final BigDecimal value) {
return value.compareTo(BigDecimal.ZERO) == 1;
}
public boolean isSpecifiedDueDate() {
return ChargeTimeType.fromInt(this.chargeTime).equals(ChargeTimeType.SPECIFIED_DUE_DATE);
}
public LoanChargeCommand toCommand() {
final LocalDate specifiedDueDate = getDueForCollectionAsOfLocalDate();
final Set<String> modifiedParameters = new HashSet<String>();
return new LoanChargeCommand(modifiedParameters, this.getId(), this.loan.getId(), this.charge.getId(),
this.amount, this.chargeTime, this.chargeCalculation, specifiedDueDate);
}
private boolean isGreaterThanZero(final BigDecimal value) {
return value.compareTo(BigDecimal.ZERO) == 1;
}
public LoanChargeCommand toCommand() {
final LocalDate specifiedDueDate = getDueForCollectionAsOfLocalDate();
final Set<String> modifiedParameters = new HashSet<String>();
return new LoanChargeCommand(modifiedParameters, this.getId(), this.loan.getId(), this.charge.getId(), this.amount,
this.chargeTime, this.chargeCalculation, specifiedDueDate);
}
public LocalDate getDueForCollectionAsOfLocalDate() {
LocalDate specifiedDueDate = null;
if (this.dueForCollectionAsOfDate != null) {
specifiedDueDate = new LocalDate(this.dueForCollectionAsOfDate);
}
return specifiedDueDate;
}
public LocalDate getDueForCollectionAsOfLocalDate() {
LocalDate specifiedDueDate = null;
if (this.dueForCollectionAsOfDate != null) {
specifiedDueDate = new LocalDate(this.dueForCollectionAsOfDate);
}
return specifiedDueDate;
}
private boolean determineIfFullyPaid() {
return BigDecimal.ZERO.compareTo(calculateOutstanding()) == 0;
}
return BigDecimal.ZERO.compareTo(calculateOutstanding()) == 0;
}
private BigDecimal calculateOutstanding() {
BigDecimal amountPaidLocal = BigDecimal.ZERO;
if (this.amountPaid != null) {
amountPaidLocal = this.amountPaid;
}
BigDecimal amountWaivedLocal = BigDecimal.ZERO;
if (this.amountWaived != null) {
amountWaivedLocal = this.amountWaived;
}
BigDecimal amountWrittenOffLocal = BigDecimal.ZERO;
if (this.amountWrittenOff != null) {
amountWrittenOffLocal = this.amountWrittenOff;
}
final BigDecimal totalAccountedFor = amountPaidLocal.add(amountWaivedLocal).add(amountWrittenOffLocal);
return this.amount.subtract(totalAccountedFor);
}
private BigDecimal calculateOutstanding() {
private BigDecimal percentageOf(final BigDecimal value, final BigDecimal percentage) {
BigDecimal percentageOf = BigDecimal.ZERO;
if (isGreaterThanZero(value)) {
final MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
BigDecimal multiplicand = percentage.divide(BigDecimal.valueOf(100l), mc);
percentageOf = value.multiply(multiplicand, mc);
}
return percentageOf;
}
BigDecimal amountPaidLocal = BigDecimal.ZERO;
if (this.amountPaid != null) {
amountPaidLocal = this.amountPaid;
}
public BigDecimal amount() {
return this.amount;
}
public boolean hasNotLoanIdentifiedBy(final Long loanId) {
return !hasLoanIdentifiedBy(loanId);
}
public boolean hasLoanIdentifiedBy(final Long loanId) {
return this.loan.hasIdentifyOf(loanId);
}
BigDecimal amountWaivedLocal = BigDecimal.ZERO;
if (this.amountWaived != null) {
amountWaivedLocal = this.amountWaived;
}
public boolean isDueForCollectionBetween(final LocalDate fromNotInclusive, final LocalDate toInclusive) {
final LocalDate specifiedDueDate = getDueForCollectionAsOfLocalDate();
return specifiedDueDateFallsWithinPeriod(fromNotInclusive, toInclusive, specifiedDueDate);
}
BigDecimal amountWrittenOffLocal = BigDecimal.ZERO;
if (this.amountWrittenOff != null) {
amountWrittenOffLocal = this.amountWrittenOff;
}
private boolean specifiedDueDateFallsWithinPeriod(
final LocalDate fromNotInclusive,
final LocalDate toInclusive,
final LocalDate specifiedDueDate) {
return specifiedDueDate != null && fromNotInclusive.isBefore(specifiedDueDate) && (toInclusive.isAfter(specifiedDueDate) || toInclusive.isEqual(specifiedDueDate));
}
final BigDecimal totalAccountedFor = amountPaidLocal.add(amountWaivedLocal).add(amountWrittenOffLocal);
public boolean isFeeCharge() {
return !this.penaltyCharge;
}
public boolean isPenaltyCharge() {
return this.penaltyCharge;
}
public boolean isNotFullyPaid() {
return !isPaid();
}
return this.amount.subtract(totalAccountedFor);
}
public boolean isPaid() {
return this.paid;
}
public boolean isPaidOrPartiallyPaid(final MonetaryCurrency currency) {
final Money amountWaivedOrWrittenOff = getAmountWaived(currency).plus(getAmountWrittenOff(currency));
return Money.of(currency, this.amountPaid).plus(amountWaivedOrWrittenOff).isGreaterThanZero();
}
public boolean isWaivedOrPartiallyWaived(final MonetaryCurrency currency) {
return getAmountWaived(currency).isGreaterThanZero();
}
private BigDecimal percentageOf(final BigDecimal value, final BigDecimal percentage) {
private Money getAmount(final MonetaryCurrency currency) {
return Money.of(currency, this.amount);
}
private Money getAmountPaid(final MonetaryCurrency currency) {
return Money.of(currency, this.amountPaid);
}
public Money getAmountWaived(final MonetaryCurrency currency) {
return Money.of(currency, this.amountWaived);
}
public Money getAmountWrittenOff(final MonetaryCurrency currency) {
return Money.of(currency, this.amountWrittenOff);
}
BigDecimal percentageOf = BigDecimal.ZERO;
public Money updatePaidAmountBy(final Money incrementBy) {
Money amountPaidToDate = Money.of(incrementBy.getCurrency(), this.amountPaid);
Money amountOutstanding = Money.of(incrementBy.getCurrency(), this.amountOutstanding);
Money amountPaidOnThisCharge = Money.zero(incrementBy.getCurrency());
if (incrementBy.isGreaterThanOrEqualTo(amountOutstanding)) {
amountPaidOnThisCharge = amountOutstanding;
amountPaidToDate = amountPaidToDate.plus(amountOutstanding);
this.amountPaid = amountPaidToDate.getAmount();
this.amountOutstanding = BigDecimal.ZERO;
} else {
amountPaidOnThisCharge = incrementBy;
amountPaidToDate = amountPaidToDate.plus(incrementBy);
this.amountPaid = amountPaidToDate.getAmount();
Money amountExpected = Money.of(incrementBy.getCurrency(), this.amount);
this.amountOutstanding = amountExpected.minus(amountPaidToDate).getAmount();
}
this.paid = determineIfFullyPaid();
return incrementBy.minus(amountPaidOnThisCharge);
}
if (isGreaterThanZero(value)) {
final MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
BigDecimal multiplicand = percentage.divide(BigDecimal.valueOf(100l), mc);
percentageOf = value.multiply(multiplicand, mc);
}
public String name() {
return this.charge.getName();
}
return percentageOf;
}
public BigDecimal amount() {
return this.amount;
}
public boolean hasNotLoanIdentifiedBy(final Long loanId) {
return !hasLoanIdentifiedBy(loanId);
}
public boolean hasLoanIdentifiedBy(final Long loanId) {
return this.loan.hasIdentifyOf(loanId);
}
public boolean isDueForCollectionBetween(final LocalDate fromNotInclusive, final LocalDate toInclusive) {
final LocalDate specifiedDueDate = getDueForCollectionAsOfLocalDate();
return specifiedDueDateFallsWithinPeriod(fromNotInclusive, toInclusive, specifiedDueDate);
}
private boolean specifiedDueDateFallsWithinPeriod(final LocalDate fromNotInclusive, final LocalDate toInclusive,
final LocalDate specifiedDueDate) {
return specifiedDueDate != null && fromNotInclusive.isBefore(specifiedDueDate)
&& (toInclusive.isAfter(specifiedDueDate) || toInclusive.isEqual(specifiedDueDate));
}
public boolean isFeeCharge() {
return !this.penaltyCharge;
}
public boolean isPenaltyCharge() {
return this.penaltyCharge;
}
public boolean isNotFullyPaid() {
return !isPaid();
}
public boolean isPaid() {
return this.paid;
}
public boolean isPaidOrPartiallyPaid(final MonetaryCurrency currency) {
final Money amountWaivedOrWrittenOff = getAmountWaived(currency).plus(getAmountWrittenOff(currency));
return Money.of(currency, this.amountPaid).plus(amountWaivedOrWrittenOff).isGreaterThanZero();
}
public boolean isWaivedOrPartiallyWaived(final MonetaryCurrency currency) {
return getAmountWaived(currency).isGreaterThanZero();
}
private Money getAmount(final MonetaryCurrency currency) {
return Money.of(currency, this.amount);
}
private Money getAmountPaid(final MonetaryCurrency currency) {
return Money.of(currency, this.amountPaid);
}
public Money getAmountWaived(final MonetaryCurrency currency) {
return Money.of(currency, this.amountWaived);
}
public Money getAmountWrittenOff(final MonetaryCurrency currency) {
return Money.of(currency, this.amountWrittenOff);
}
public Money updatePaidAmountBy(final Money incrementBy) {
Money amountPaidToDate = Money.of(incrementBy.getCurrency(), this.amountPaid);
Money amountOutstanding = Money.of(incrementBy.getCurrency(), this.amountOutstanding);
Money amountPaidOnThisCharge = Money.zero(incrementBy.getCurrency());
if (incrementBy.isGreaterThanOrEqualTo(amountOutstanding)) {
amountPaidOnThisCharge = amountOutstanding;
amountPaidToDate = amountPaidToDate.plus(amountOutstanding);
this.amountPaid = amountPaidToDate.getAmount();
this.amountOutstanding = BigDecimal.ZERO;
} else {
amountPaidOnThisCharge = incrementBy;
amountPaidToDate = amountPaidToDate.plus(incrementBy);
this.amountPaid = amountPaidToDate.getAmount();
Money amountExpected = Money.of(incrementBy.getCurrency(), this.amount);
this.amountOutstanding = amountExpected.minus(amountPaidToDate).getAmount();
}
this.paid = determineIfFullyPaid();
return incrementBy.minus(amountPaidOnThisCharge);
}
public String name() {
return this.charge.getName();
}
}
@@ -86,7 +86,7 @@ public class LoanProductsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createLoanProduct(final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_LOANPRODUCT", "CREATE",
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "LOANPRODUCT", "CREATE",
"loanproducts", null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -144,7 +144,7 @@ public class LoanProductsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateLoanProduct(@PathParam("productId") final Long productId, final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_LOANPRODUCT", "UPDATE",
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "LOANPRODUCT", "UPDATE",
"loanproducts", productId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -77,8 +77,8 @@ public class PermissionsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updatePermissionsDetails(final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_PERMISSION", "UPDATE", "permissions", null,
apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "PERMISSION", "UPDATE",
"permissions", null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -103,7 +103,7 @@ public class RolesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createRole(final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_ROLE", "CREATE", "roles", null,
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "ROLE", "CREATE", "roles", null,
apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -145,8 +145,8 @@ public class RolesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateRole(@PathParam("roleId") final Long roleId, final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_ROLE", "UPDATE", "roles", roleId,
apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "ROLE", "UPDATE", "roles",
roleId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -175,8 +175,8 @@ public class RolesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateRolePermissions(@PathParam("roleId") final Long roleId, final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("PERMISSIONS_ROLE", "UPDATEPERMISSIONS",
"roles", roleId, apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("PERMISSIONS", "ROLE",
"UPDATEPERMISSIONS", "roles", roleId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -118,7 +118,7 @@ public class UsersApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createUser(final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_USER", "CREATE", "users", null,
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "USER", "CREATE", "users", null,
apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -130,8 +130,8 @@ public class UsersApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateUser(@PathParam("userId") final Long userId, final String apiRequestBodyAsJson) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_USER", "UPDATE", "users", userId,
apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "USER", "UPDATE", "users",
userId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -142,8 +142,8 @@ public class UsersApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String deleteUser(@PathParam("userId") final Long userId) {
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_USER", "DELETE", "users", userId,
"{}");
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "USER", "DELETE", "users",
userId, "{}");
return this.toApiJsonSerializer.serialize(result);
}