wip:minor changes to charges

This commit is contained in:
Vishwas Babu AJ
2013-03-15 13:19:00 +05:30
parent fe426352ff
commit 50b9839024
6 changed files with 123 additions and 20 deletions
+2
View File
@@ -0,0 +1,2 @@
ALTER TABLE `m_loan_charge`
ADD COLUMN `waived` TINYINT(1) NOT NULL DEFAULT '0' AFTER `is_paid_derived`;
@@ -0,0 +1,38 @@
/**
* 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.portfolio.charge.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class LoanChargeCannotBeDeletedException extends AbstractPlatformDomainRuleException {
/*** enum of reasons of why Loan Charge cannot be waived **/
public static enum LOAN_CHARGE_CANNOT_BE_DELETED_REASON {
ALREADY_PAID, ALREADY_WAIVED, LOAN_APPROVED;
public String errorMessage() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "This loan charge has been partially/completely paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "This loan charge has already been waived";
} else if (name().toString().equalsIgnoreCase("LOAN_APPROVED")) { return "This charge cannot be deleted as the loan it is associated with has already been approved"; }
return name().toString();
}
public String errorCode() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "error.msg.loan.charge.already.paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "error.msg.loan.charge.already.waived";
} else if (name().toString().equalsIgnoreCase("LOAN_APPROVED")) { return "error.msg.loan.charge.associated.loan.already.approved"; }
return name().toString();
}
}
public LoanChargeCannotBeDeletedException(final LOAN_CHARGE_CANNOT_BE_DELETED_REASON reason, final Long loanChargeId) {
super(reason.errorCode(), reason.errorMessage(), loanChargeId);
}
}
@@ -0,0 +1,38 @@
/**
* 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.portfolio.charge.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class LoanChargeCannotBeWaivedException extends AbstractPlatformDomainRuleException {
/*** enum of reasons of why Loan Charge cannot be waived **/
public static enum LOAN_CHARGE_CANNOT_BE_WAIVED_REASON {
ALREADY_PAID, ALREADY_WAIVED, LOAN_INACTIVE;
public String errorMessage() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "This loan charge has been completely paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "This loan charge has already been waived";
} else if (name().toString().equalsIgnoreCase("LOAN_INACTIVE")) { return "This loan charge can be waived as the loan associated with it is currently inactive"; }
return name().toString();
}
public String errorCode() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "error.msg.loan.charge.already.paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "error.msg.loan.charge.already.waived";
} else if (name().toString().equalsIgnoreCase("LOAN_INACTIVE")) { return "error.msg.loan.charge.associated.loan.inactive"; }
return name().toString();
}
}
public LoanChargeCannotBeWaivedException(final LOAN_CHARGE_CANNOT_BE_WAIVED_REASON reason, final Long loanChargeId) {
super(reason.errorCode(), reason.errorMessage(), loanChargeId);
}
}
@@ -430,7 +430,7 @@ public class Loan extends AbstractPersistable<Long> {
}
private void validateLoanChargeIsNotWaived(final LoanCharge loanCharge) {
if (loanCharge.isWaivedOrPartiallyWaived(loanCurrency())) {
if (loanCharge.isWaived()) {
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());
}
@@ -1793,7 +1793,7 @@ public class Loan extends AbstractPersistable<Long> {
return !isSubmittedAndPendingApproval();
}
private LoanStatus status() {
public LoanStatus status() {
return LoanStatus.fromInt(this.loanStatus);
}
@@ -82,6 +82,9 @@ public class LoanCharge extends AbstractPersistable<Long> {
@Column(name = "is_paid_derived", nullable = false)
private boolean paid = false;
@Column(name = "waived", nullable = false)
private boolean waived = false;
public static LoanCharge createNewFromJson(final Loan loan, final Charge chargeDefinition, final JsonCommand command) {
final BigDecimal amount = command.bigDecimalValueOfParameterNamed("amount");
@@ -101,8 +104,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
// ChargeCalculationType.fromInt(chargeCalculationType);
// }
return new LoanCharge(loan, chargeDefinition, loan.getPrincpal().getAmount(), amount, chargeTime, chargeCalculation,
dueDate);
return new LoanCharge(loan, chargeDefinition, loan.getPrincpal().getAmount(), amount, chargeTime, chargeCalculation, dueDate);
}
/*
@@ -132,8 +134,8 @@ public class LoanCharge extends AbstractPersistable<Long> {
if (dueDate == null) {
final String defaultUserMessage = "Loan charge is missing due date.";
throw new LoanChargeWithoutMandatoryFieldException("loanCharge", "dueDate", defaultUserMessage,
chargeDefinition.getId(), chargeDefinition.getName());
throw new LoanChargeWithoutMandatoryFieldException("loanCharge", "dueDate", defaultUserMessage, chargeDefinition.getId(),
chargeDefinition.getName());
}
this.dueDate = dueDate.toDate();
@@ -218,6 +220,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
this.amountWrittenOff = BigDecimal.ZERO;
this.amountOutstanding = calculateAmountOutstanding(currency);
this.paid = false;
this.waived = false;
}
public void resetPaidAmount(final MonetaryCurrency currency) {
@@ -227,9 +230,10 @@ public class LoanCharge extends AbstractPersistable<Long> {
}
public Money waive(final MonetaryCurrency currency) {
this.amountWaived = this.amount;
this.amountOutstanding = calculateAmountOutstanding(currency);
this.paid = determineIfFullyPaid();
this.amountWaived = this.amountOutstanding;
this.amountOutstanding = BigDecimal.ZERO;
this.paid = false;
this.waived = true;
return getAmountWaived(currency);
}
@@ -452,16 +456,16 @@ public class LoanCharge extends AbstractPersistable<Long> {
return this.paid;
}
public boolean isWaived() {
return this.waived;
}
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);
}
@@ -24,6 +24,10 @@ import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyReposit
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.portfolio.charge.domain.Charge;
import org.mifosplatform.portfolio.charge.domain.ChargeRepositoryWrapper;
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeDeletedException;
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeDeletedException.LOAN_CHARGE_CANNOT_BE_DELETED_REASON;
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException;
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException.LOAN_CHARGE_CANNOT_BE_WAIVED_REASON;
import org.mifosplatform.portfolio.charge.exception.LoanChargeNotFoundException;
import org.mifosplatform.portfolio.loanaccount.command.LoanUpdateCommand;
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
@@ -143,7 +147,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
context.authenticatedUser();
final Loan loan = retrieveLoanBy(loanId);
final BigDecimal totalInterestCharged = loan.getSummary().getTotalInterestCharged();
final BigDecimal totalInterestCharged = loan.getSummary().getTotalInterestCharged();
final List<Long> existingTransactionIds = new ArrayList<Long>();
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
@@ -164,7 +168,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
// accountingBridgedate, this would not work if interest
// recalculation in introduced
accountingBridgeData.put("calculatedInterest", totalInterestCharged);
journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
}
@@ -310,7 +314,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final Note note = Note.loanTransactionNote(loan, waiveTransaction, noteText);
this.noteRepository.save(note);
}
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
return new CommandProcessingResultBuilder() //
@@ -535,16 +539,28 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final Loan loan = retrieveLoanBy(loanId);
final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId);
// Charges may be waived only when the loan associated with them are
// active
if (!loan.status().isActive()) { throw new LoanChargeCannotBeWaivedException(LOAN_CHARGE_CANNOT_BE_WAIVED_REASON.LOAN_INACTIVE,
loanCharge.getId()); }
// validate loan charge is not already paid or waived
if (loanCharge.isWaived()) {
throw new LoanChargeCannotBeWaivedException(LOAN_CHARGE_CANNOT_BE_WAIVED_REASON.ALREADY_WAIVED, loanCharge.getId());
} else if (loanCharge.isPaid()) { throw new LoanChargeCannotBeWaivedException(LOAN_CHARGE_CANNOT_BE_WAIVED_REASON.ALREADY_PAID,
loanCharge.getId()); }
final Map<String, Object> changes = new LinkedHashMap<String, Object>(3);
final List<Long> existingTransactionIds = new ArrayList<Long>();
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
final LoanTransaction waiveTransaction = loan.waiveLoanCharge(loanCharge, defaultLoanLifecycleStateMachine(), changes,
existingTransactionIds, existingReversedTransactionIds);
this.loanTransactionRepository.save(waiveTransaction);
this.loanRepository.save(loan);
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
return new CommandProcessingResultBuilder() //
@@ -558,7 +574,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
.build();
}
@Transactional
@Override
public CommandProcessingResult deleteLoanCharge(final Long loanId, final Long loanChargeId, final JsonCommand command) {
@@ -568,6 +583,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final Loan loan = retrieveLoanBy(loanId);
final LoanCharge loanCharge = retrieveLoanChargeBy(loanId, loanChargeId);
// validate loan charge is not partly paid or waived
if (loanCharge.isWaived()) {
throw new LoanChargeCannotBeDeletedException(LOAN_CHARGE_CANNOT_BE_DELETED_REASON.ALREADY_WAIVED, loanCharge.getId());
} else if (loanCharge.isPaidOrPartiallyPaid(loan.getCurrency())) { throw new LoanChargeCannotBeDeletedException(
LOAN_CHARGE_CANNOT_BE_DELETED_REASON.ALREADY_PAID, loanCharge.getId()); }
loan.removeLoanCharge(loanCharge);
this.loanRepository.save(loan);
@@ -688,7 +709,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
.withLoanId(loanId) //
.build();
}
/**
* @param loan
* @param existingTransactionIds