MIFOSX-90: disallow ability to remove loan charge if it is waived (or partially waived).

This commit is contained in:
Keith Woodlock
2012-11-08 11:26:51 +00:00
parent 027be9df4f
commit 7af4b12d24
4 changed files with 37 additions and 23 deletions
@@ -507,16 +507,16 @@ public class LoansApiResource {
@Path("{loanId}/charges/{chargeId}") @Path("{loanId}/charges/{chargeId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public Response updateLoanCharge( public String updateLoanCharge(
@PathParam("loanId") final Long loanId, @PathParam("loanId") final Long loanId,
@PathParam("chargeId") final Long loanChargeId, @PathParam("chargeId") final Long loanChargeId,
final String jsonRequestBody){ final String jsonRequestBody){
LoanChargeCommand command = this.apiDataConversionService.convertJsonToLoanChargeCommand(loanChargeId, loanId, jsonRequestBody); final LoanChargeCommand command = this.apiDataConversionService.convertJsonToLoanChargeCommand(loanChargeId, loanId, jsonRequestBody);
EntityIdentifier identifier = this.loanWritePlatformService.updateLoanCharge(command); final EntityIdentifier identifier = this.loanWritePlatformService.updateLoanCharge(command);
return Response.ok().entity(identifier).build(); return this.apiJsonSerializerService.serializeEntityIdentifier(identifier);
} }
@POST @POST
@@ -526,16 +526,13 @@ public class LoansApiResource {
public String waiveLoanCharge( public String waiveLoanCharge(
@PathParam("loanId") final Long loanId, @PathParam("loanId") final Long loanId,
@PathParam("chargeId") final Long loanChargeId, @PathParam("chargeId") final Long loanChargeId,
@QueryParam("command") final String commandParam, @QueryParam("command") final String commandParam){
final String jsonRequestBody){
// LoanChargeCommand command = this.apiDataConversionService.convertJsonToLoanChargeCommand(loanChargeId, loanId, jsonRequestBody); final LoanChargeCommand command = LoanChargeCommand.forWaiver(loanChargeId, loanId);
LoanChargeCommand command = LoanChargeCommand.forWaiver(loanChargeId, loanId);
String json = ""; String json = "";
if (is(commandParam, "waive")) { if (is(commandParam, "waive")) {
EntityIdentifier identifier = this.loanWritePlatformService.waiveLoanCharge(command); final EntityIdentifier identifier = this.loanWritePlatformService.waiveLoanCharge(command);
json = this.apiJsonSerializerService.serializeEntityIdentifier(identifier); json = this.apiJsonSerializerService.serializeEntityIdentifier(identifier);
} else { } else {
throw new UnrecognizedQueryParamException("command", commandParam); throw new UnrecognizedQueryParamException("command", commandParam);
@@ -548,13 +545,11 @@ public class LoansApiResource {
@Path("{loanId}/charges/{chargeId}") @Path("{loanId}/charges/{chargeId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public Response deleteLoanCharge( public String deleteLoanCharge(
@PathParam("loanId") final Long loanId, @PathParam("loanId") final Long loanId,
@PathParam("chargeId") final Long loanChargeId){ @PathParam("chargeId") final Long loanChargeId){
EntityIdentifier identifier = this.loanWritePlatformService.deleteLoanCharge(loanId, loanChargeId); final EntityIdentifier identifier = this.loanWritePlatformService.deleteLoanCharge(loanId, loanChargeId);
return this.apiJsonSerializerService.serializeEntityIdentifier(identifier);
return Response.ok().entity(identifier).build();
} }
} }
@@ -299,6 +299,13 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
throw new LoanChargeCannotBeAddedException("loanCharge", "loan.is.closed", defaultUserMessage, getId(), loanCharge.name()); throw new LoanChargeCannotBeAddedException("loanCharge", "loan.is.closed", defaultUserMessage, getId(), loanCharge.name());
} }
} }
private void validateLoanChargeIsNotWaived(final LoanCharge loanCharge) {
if (loanCharge.isWaivedOrPartiallyWaived(loanCurrency())) {
final String defaultUserMessage = "This loan charge cannot be removed as the charge as already been waived.";
throw new LoanChargeCannotBeAddedException("loanCharge", "loanCharge.is.waived", defaultUserMessage, getId(), loanCharge.name());
}
}
private void validateChargeHasValidSpecifiedDateIfApplicable(final LoanCharge loanCharge, final LocalDate disbursementDate, final LocalDate lastRepaymentPeriodDueDate) { private void validateChargeHasValidSpecifiedDateIfApplicable(final LoanCharge loanCharge, final LocalDate disbursementDate, final LocalDate lastRepaymentPeriodDueDate) {
if (loanCharge.isSpecifiedDueDate() && !loanCharge.isDueForCollectionBetween(disbursementDate, lastRepaymentPeriodDueDate)) { if (loanCharge.isSpecifiedDueDate() && !loanCharge.isDueForCollectionBetween(disbursementDate, lastRepaymentPeriodDueDate)) {
@@ -315,12 +322,26 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
validateLoanIsNotClosed(loanCharge); validateLoanIsNotClosed(loanCharge);
// NOTE: to remove this constraint requires that loan transactions
// that represent the waive of charges also be removed (or reversed)
// if you want ability to remove loan charges that are waived.
validateLoanChargeIsNotWaived(loanCharge);
boolean removed = this.charges.remove(loanCharge); boolean removed = this.charges.remove(loanCharge);
if (removed) { if (removed) {
updateTotalChargesDueAtDisbursement(); updateTotalChargesDueAtDisbursement();
} }
// if removing disbursement charge - accomodate this on the transaction that tracked its payment removeOrModifyTransactionAssociatedWithLoanChargeIfDueAtDisbursement(loanCharge);
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessor.determineProcessor(this.transactionProcessingStrategy);
if (!loanCharge.isDueAtDisbursement() && loanCharge.isPaidOrPartiallyPaid(loanCurrency())) {
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, this.charges);
}
}
private void removeOrModifyTransactionAssociatedWithLoanChargeIfDueAtDisbursement(final LoanCharge loanCharge) {
if (loanCharge.isDueAtDisbursement()) { if (loanCharge.isDueAtDisbursement()) {
LoanTransaction transactionToRemove = null; LoanTransaction transactionToRemove = null;
for (LoanTransaction transaction : this.loanTransactions) { for (LoanTransaction transaction : this.loanTransactions) {
@@ -345,12 +366,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
this.loanTransactions.remove(transactionToRemove); this.loanTransactions.remove(transactionToRemove);
} }
} }
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessor.determineProcessor(this.transactionProcessingStrategy);
if (!loanCharge.isDueAtDisbursement() && loanCharge.isPaidOrPartiallyPaid(loanCurrency())) {
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, this.charges);
}
} }
public void updateLoanCharge(final LoanCharge loanCharge, final LoanChargeCommand command) { public void updateLoanCharge(final LoanCharge loanCharge, final LoanChargeCommand command) {
@@ -411,6 +411,10 @@ public class LoanCharge extends AbstractPersistable<Long> {
final Money amountWaivedOrWrittenOff = getAmountWaived(currency).plus(getAmountWrittenOff(currency)); final Money amountWaivedOrWrittenOff = getAmountWaived(currency).plus(getAmountWrittenOff(currency));
return Money.of(currency, this.amountPaid).plus(amountWaivedOrWrittenOff).isGreaterThanZero(); 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) { private Money getAmount(final MonetaryCurrency currency) {
return Money.of(currency, this.amount); return Money.of(currency, this.amount);
@@ -707,7 +707,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId); final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId);
loan.removeLoanCharge(loanCharge); loan.removeLoanCharge(loanCharge);
this.loanRepository.saveAndFlush(loan); this.loanRepository.save(loan);
return new EntityIdentifier(loanCharge.getId()); return new EntityIdentifier(loanCharge.getId());
} }