linking loan transactions to branches in preparation for inter-branch account transfers

This commit is contained in:
Vishwas Babu A J
2013-08-21 22:14:17 +05:30
parent 81bde6ddad
commit b1d2b42da1
9 changed files with 128 additions and 67 deletions
@@ -0,0 +1,15 @@
ALTER TABLE `m_loan_transaction`
ADD COLUMN `office_id` BIGINT(20) NULL DEFAULT NULL AFTER `loan_id`;
/**update client loans**/
UPDATE m_loan_transaction lt set lt.office_id = (SELECT c.office_id AS officeId FROM m_loan l JOIN m_client c on l.client_id=c.id where l.id=lt.loan_id) where lt.loan_id in (Select l.id from m_loan l where l.client_id is not null);
/**update group loans**/
UPDATE m_loan_transaction lt set lt.office_id = (SELECT g.office_id AS officeId FROM m_loan l JOIN m_group g on l.group_id=g.id where l.id=lt.loan_id) where lt.loan_id in (Select l.id from m_loan l where l.group_id is not null);
/**Add foreign key constraints**/
ALTER TABLE `m_loan_transaction`
CHANGE COLUMN `office_id` `office_id` BIGINT(20) NOT NULL AFTER `loan_id`;
ALTER TABLE `m_loan_transaction`
ADD CONSTRAINT `FK_m_loan_transaction_m_office` FOREIGN KEY (`office_id`) REFERENCES `m_office` (`id`);
@@ -13,6 +13,8 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData;
public class LoanTransactionDTO {
private final Long officeId;
private final String transactionId;
private final Date transactionDate;
private final Long paymentTypeId;
@@ -33,7 +35,7 @@ public class LoanTransactionDTO {
private final List<ChargePaymentDTO> penaltyPayments;
private final List<ChargePaymentDTO> feePayments;
public LoanTransactionDTO(final Long paymentTypeId, final String transactionId, final Date transactionDate,
public LoanTransactionDTO(final Long officeId, final Long paymentTypeId, final String transactionId, final Date transactionDate,
final LoanTransactionEnumData transactionType, final BigDecimal amount, final BigDecimal principal, final BigDecimal interest,
final BigDecimal fees, final BigDecimal penalties, final boolean reversed, final List<ChargePaymentDTO> feePayments,
final List<ChargePaymentDTO> penaltyPayments) {
@@ -49,6 +51,11 @@ public class LoanTransactionDTO {
this.transactionType = transactionType;
this.feePayments = feePayments;
this.penaltyPayments = penaltyPayments;
this.officeId = officeId;
}
public Long getOfficeId() {
return this.officeId;
}
public String getTransactionId() {
@@ -69,6 +69,7 @@ public class AccountingProcessorHelper {
final List<Map<String, Object>> newTransactionsMap = (List<Map<String, Object>>) accountingBridgeData.get("newLoanTransactions");
for (final Map<String, Object> map : newTransactionsMap) {
final Long transactionOfficeId = (Long) map.get("officeId");
final String transactionId = ((Long) map.get("id")).toString();
final Date transactionDate = ((LocalDate) map.get("date")).toDate();
final LoanTransactionEnumData transactionType = (LoanTransactionEnumData) map.get("type");
@@ -100,8 +101,8 @@ public class AccountingProcessorHelper {
}
}
final LoanTransactionDTO transaction = new LoanTransactionDTO(paymentTypeId, transactionId, transactionDate, transactionType,
amount, principal, interest, fees, penalties, reversed, feePayments, penaltyPayments);
final LoanTransactionDTO transaction = new LoanTransactionDTO(transactionOfficeId, paymentTypeId, transactionId,
transactionDate, transactionType, amount, principal, interest, fees, penalties, reversed, feePayments, penaltyPayments);
newLoanTransactions.add(transaction);
@@ -29,11 +29,13 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
@Override
public void createJournalEntriesForLoan(LoanDTO loanDTO) {
final GLClosure latestGLClosure = this.helper.getLatestClosureByBranch(loanDTO.getOfficeId());
final Office office = this.helper.getOfficeById(loanDTO.getOfficeId());
// final Office office =
// this.helper.getOfficeById(loanDTO.getOfficeId());
final Long loanProductId = loanDTO.getLoanProductId();
for (final LoanTransactionDTO loanTransactionDTO : loanDTO.getNewLoanTransactions()) {
final Date transactionDate = loanTransactionDTO.getTransactionDate();
final String transactionId = loanTransactionDTO.getTransactionId();
final Office office = this.helper.getOfficeById(loanTransactionDTO.getOfficeId());
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
final Long loanId = loanDTO.getLoanId();
@@ -52,6 +52,7 @@ import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.organisation.workingdays.domain.WorkingDays;
import org.mifosplatform.organisation.workingdays.service.WorkingDaysUtil;
@@ -494,8 +495,8 @@ public class Loan extends AbstractPersistable<Long> {
}
}
final LoanTransaction applyLoanChargeTransaction = LoanTransaction.applyLoanCharge(this, chargeAmount, transactionDate, feeCharges,
penaltyCharges);
final LoanTransaction applyLoanChargeTransaction = LoanTransaction.applyLoanCharge(this, this.getOffice(), chargeAmount,
transactionDate, feeCharges, penaltyCharges);
this.loanTransactions.add(applyLoanChargeTransaction);
return applyLoanChargeTransaction;
}
@@ -653,8 +654,8 @@ public class Loan extends AbstractPersistable<Long> {
existingTransactionIds.addAll(findExistingTransactionIds());
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
final LoanTransaction waiveLoanChargeTransaction = LoanTransaction.waiveLoanCharge(this, amountWaived, transactionDate,
feeChargesWaived, penaltyChargesWaived);
final LoanTransaction waiveLoanChargeTransaction = LoanTransaction.waiveLoanCharge(this, this.getOffice(), amountWaived,
transactionDate, feeChargesWaived, penaltyChargesWaived);
this.loanTransactions.add(waiveLoanChargeTransaction);
// Waive of charges whose due date falls after latest 'repayment'
@@ -1096,7 +1097,7 @@ public class Loan extends AbstractPersistable<Long> {
if (this.client != null && this.client.isActivatedAfter(submittedOn)) {
final String errorMessage = "The date on which a loan is submitted cannot be earlier than client's activation date.";
throw new InvalidLoanStateTransitionException("submittal", "cannot.be.before.client.activation.date", errorMessage, submittedOn);
}
}
if (this.group != null && this.group.isActivatedAfter(submittedOn)) {
final String errorMessage = "The date on which a loan is submitted cannot be earlier than groups's activation date.";
throw new InvalidLoanStateTransitionException("submittal", "cannot.be.before.group.activation.date", errorMessage, submittedOn);
@@ -1312,7 +1313,8 @@ public class Loan extends AbstractPersistable<Long> {
updateLoanToPreDisbursalState();
final LoanStatus statusEnum = this.loanLifecycleStateMachine.transition(LoanEvent.LOAN_DISBURSED, LoanStatus.fromInt(this.loanStatus));
final LoanStatus statusEnum = this.loanLifecycleStateMachine.transition(LoanEvent.LOAN_DISBURSED,
LoanStatus.fromInt(this.loanStatus));
if (!statusEnum.hasStateOf(LoanStatus.fromInt(this.loanStatus))) {
existingTransactionIds.addAll(findExistingTransactionIds());
@@ -1348,7 +1350,8 @@ public class Loan extends AbstractPersistable<Long> {
}
final Money interestApplied = Money.of(getCurrency(), this.summary.getTotalInterestCharged());
final LoanTransaction interestAppliedTransaction = LoanTransaction.applyInterest(this, interestApplied, actualDisbursementDate);
final LoanTransaction interestAppliedTransaction = LoanTransaction.applyInterest(this.getOffice(), this, interestApplied,
actualDisbursementDate);
this.loanTransactions.add(interestAppliedTransaction);
}
@@ -1379,10 +1382,11 @@ public class Loan extends AbstractPersistable<Long> {
final Integer loanTermFrequency = this.termFrequency;
final PeriodFrequencyType loanTermPeriodFrequencyType = PeriodFrequencyType.fromInt(this.termPeriodFrequencyType);
final LoanApplicationTerms loanApplicationTerms = LoanApplicationTerms.assembleFrom(applicationCurrency, loanTermFrequency,
loanTermPeriodFrequencyType, getDisbursementDate(), getExpectedFirstRepaymentOnDate(), calculatedRepaymentsStartingFromDate, getInArrearsTolerance(),
this.loanRepaymentScheduleDetail);
loanTermPeriodFrequencyType, getDisbursementDate(), getExpectedFirstRepaymentOnDate(),
calculatedRepaymentsStartingFromDate, getInArrearsTolerance(), this.loanRepaymentScheduleDetail);
final LoanScheduleModel loanSchedule = loanScheduleGenerator.generate(mc, applicationCurrency, loanApplicationTerms, this.charges, isHolidayEnabled, holidays, workingDays);
final LoanScheduleModel loanSchedule = loanScheduleGenerator.generate(mc, applicationCurrency, loanApplicationTerms, this.charges,
isHolidayEnabled, holidays, workingDays);
updateLoanSchedule(loanSchedule);
}
@@ -1390,8 +1394,8 @@ public class Loan extends AbstractPersistable<Long> {
private LoanTransaction handleDisbursementTransaction(final PaymentDetail paymentDetail, final LocalDate disbursedOn,
final String txnExternalId) {
// track disbursement transaction
final LoanTransaction disbursementTransaction = LoanTransaction.disbursement(this.loanRepaymentScheduleDetail.getPrincipal(),
paymentDetail, disbursedOn, txnExternalId);
final LoanTransaction disbursementTransaction = LoanTransaction.disbursement(this.getOffice(),
this.loanRepaymentScheduleDetail.getPrincipal(), paymentDetail, disbursedOn, txnExternalId);
disbursementTransaction.updateLoan(this);
this.loanTransactions.add(disbursementTransaction);
@@ -1405,7 +1409,8 @@ public class Loan extends AbstractPersistable<Long> {
final Money totalFeeChargesDueAtDisbursement = this.summary.getTotalFeeChargesDueAtDisbursement(loanCurrency());
if (totalFeeChargesDueAtDisbursement.isGreaterThanZero()) {
final LoanTransaction chargesPayment = LoanTransaction.repaymentAtDisbursement(totalFeeChargesDueAtDisbursement, null, disbursedOn, txnExternalId);
final LoanTransaction chargesPayment = LoanTransaction.repaymentAtDisbursement(this.getOffice(),
totalFeeChargesDueAtDisbursement, null, disbursedOn, txnExternalId);
final Money zero = Money.zero(getCurrency());
chargesPayment.updateComponents(zero, zero, totalFeeChargesDueAtDisbursement, zero);
chargesPayment.updateLoan(this);
@@ -1728,7 +1733,7 @@ public class Loan extends AbstractPersistable<Long> {
}
}
return LoanTransaction.waiver(this, possibleInterestToWaive, transactionDate);
return LoanTransaction.waiver(this.getOffice(), this, possibleInterestToWaive, transactionDate);
}
public ChangedTransactionDetail adjustExistingTransaction(final LoanTransaction newTransactionDetail,
@@ -1849,7 +1854,7 @@ public class Loan extends AbstractPersistable<Long> {
throw new InvalidLoanStateTransitionException("writeoff", "cannot.be.a.future.date", errorMessage, writtenOffOnLocalDate);
}
loanTransaction = LoanTransaction.writeoff(this, writtenOffOnLocalDate, txnExternalId);
loanTransaction = LoanTransaction.writeoff(this, this.getOffice(), writtenOffOnLocalDate, txnExternalId);
final boolean isLastTransaction = isChronologicallyLatestTransaction(loanTransaction, this.loanTransactions);
if (!isLastTransaction) {
final String errorMessage = "The date of the writeoff transaction must occur on or before previous transactions.";
@@ -1906,7 +1911,7 @@ public class Loan extends AbstractPersistable<Long> {
}
this.closedOnDate = closureDate.toDate();
loanTransaction = LoanTransaction.writeoff(this, closureDate, txnExternalId);
loanTransaction = LoanTransaction.writeoff(this, this.getOffice(), closureDate, txnExternalId);
final boolean isLastTransaction = isChronologicallyLatestTransaction(loanTransaction, this.loanTransactions);
if (!isLastTransaction) {
final String errorMessage = "The closing date of the loan must be on or after latest transaction date.";
@@ -2256,7 +2261,8 @@ public class Loan extends AbstractPersistable<Long> {
final String errorMessage = "The Loan officer Unassign date(" + unassignDate + ") cannot be before its assignment date ("
+ latestHistoryRecord.getStartDate() + ").";
throw new LoanOfficerUnassignmentDateException("cannot.be.before.assignment.date", errorMessage, getId(), getLoanOfficer().getId(), latestHistoryRecord.getStartDate(), unassignDate);
throw new LoanOfficerUnassignmentDateException("cannot.be.before.assignment.date", errorMessage, getId(), getLoanOfficer()
.getId(), latestHistoryRecord.getStartDate(), unassignDate);
} else if (unassignDate.isAfter(today)) {
@@ -2324,6 +2330,16 @@ public class Loan extends AbstractPersistable<Long> {
return officeId;
}
public Office getOffice() {
Office office = null;
if (this.client != null) {
office = this.client.getOffice();
} else {
office = this.group.getOffice();
}
return office;
}
private Boolean isCashBasedAccountingEnabledOnLoanProduct() {
return this.loanProduct.isCashBasedAccountingEnabled();
}
@@ -2389,7 +2405,7 @@ public class Loan extends AbstractPersistable<Long> {
public void updateLoanRepaymentScheduleDates(final LocalDate meetingStartDate, final String recuringRule,
final boolean isHolidayEnabled, final List<Holiday> holidays, final WorkingDays workingDays) {
//first repayment's from date is same as disbursement date.
// first repayment's from date is same as disbursement date.
LocalDate tmpFromDate = this.getDisbursementDate();
final PeriodFrequencyType repaymentPeriodFrequencyType = this.loanRepaymentScheduleDetail.getRepaymentPeriodFrequencyType();
final Integer loanRepaymentInterval = this.loanRepaymentScheduleDetail.getRepayEvery();
@@ -2435,7 +2451,7 @@ public class Loan extends AbstractPersistable<Long> {
private LocalDate getMaxDateLimitForNewRepayment(final PeriodFrequencyType periodFrequencyType, final Integer loanRepaymentInterval,
final LocalDate startDate) {
LocalDate dueRepaymentPeriodDate = startDate;
final Integer repaidEvery = 2*loanRepaymentInterval;
final Integer repaidEvery = 2 * loanRepaymentInterval;
switch (periodFrequencyType) {
case DAYS:
dueRepaymentPeriodDate = startDate.plusDays(repaidEvery);
@@ -2452,7 +2468,8 @@ public class Loan extends AbstractPersistable<Long> {
case INVALID:
break;
}
return dueRepaymentPeriodDate.minusDays(1);//get 2n-1 range date from startDate
return dueRepaymentPeriodDate.minusDays(1);// get 2n-1 range date from
// startDate
}
public void applyHolidayToRepaymentScheduleDates(final Holiday holiday) {
@@ -2468,13 +2485,14 @@ public class Loan extends AbstractPersistable<Long> {
loanRepaymentScheduleInstallment.updateFromDate(tmpFromDate);
}
if (oldDueDate.isAfter(holiday.getToDateLocalDate())) {
break;
}
break;
}
if (oldDueDate.equals(holiday.getFromDateLocalDate()) || oldDueDate.equals(holiday.getToDateLocalDate())
|| oldDueDate.isAfter(holiday.getFromDateLocalDate()) && oldDueDate.isBefore(holiday.getToDateLocalDate())) {
//FIXME: AA do we need to apply non-working days.
//Assuming holiday's repayment reschedule to date cannot be created on a non-working day.
// FIXME: AA do we need to apply non-working days.
// Assuming holiday's repayment reschedule to date cannot be
// created on a non-working day.
final LocalDate newRepaymentDate = holiday.getRepaymentsRescheduledToLocalDate();
loanRepaymentScheduleInstallment.updateDueDate(newRepaymentDate);
}
@@ -2569,5 +2587,4 @@ public class Loan extends AbstractPersistable<Long> {
}
}
@@ -94,8 +94,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
final Money repaymentAmount = Money.of(loan.getCurrency(), transactionAmount);
final LoanTransaction newRepaymentTransaction = LoanTransaction.repayment(repaymentAmount, paymentDetail, transactionDate,
txnExternalId);
final LoanTransaction newRepaymentTransaction = LoanTransaction.repayment(loan.getOffice(), repaymentAmount, paymentDetail,
transactionDate, txnExternalId);
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
final List<Holiday> holidays = this.holidayRepository
.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), transactionDate.toDate());
@@ -31,6 +31,7 @@ import org.joda.time.LocalDate;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData;
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData;
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
@@ -43,13 +44,17 @@ import org.springframework.data.jpa.domain.AbstractPersistable;
* Disbursements, Repayments, Waivers, Write-off etc
*/
@Entity
@Table(name = "m_loan_transaction", uniqueConstraints = {@UniqueConstraint(columnNames = { "external_id" }, name = "external_id_UNIQUE") })
@Table(name = "m_loan_transaction", uniqueConstraints = { @UniqueConstraint(columnNames = { "external_id" }, name = "external_id_UNIQUE") })
public final class LoanTransaction extends AbstractPersistable<Long> {
@ManyToOne(optional = false)
@JoinColumn(name = "loan_id", nullable = false)
private Loan loan;
@ManyToOne
@JoinColumn(name = "office_id", nullable = false)
private Office office;
@ManyToOne(optional = true)
@JoinColumn(name = "payment_detail_id", nullable = true)
private PaymentDetail paymentDetail;
@@ -81,7 +86,7 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
@Column(name = "external_id", length = 100, nullable = true, unique = true)
private String externalId;
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loanTransaction", orphanRemoval = true)
private Set<LoanChargePaidBy> loanChargesPaid = new HashSet<LoanChargePaidBy>();
@@ -92,35 +97,43 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
this.typeOf = null;
}
public static LoanTransaction disbursement(final Money amount, final PaymentDetail paymentDetail, final LocalDate disbursementDate, final String externalId) {
return new LoanTransaction(null, LoanTransactionType.DISBURSEMENT, paymentDetail, amount.getAmount(), disbursementDate, externalId);
public static LoanTransaction disbursement(final Office office, final Money amount, final PaymentDetail paymentDetail,
final LocalDate disbursementDate, final String externalId) {
return new LoanTransaction(null, office, LoanTransactionType.DISBURSEMENT, paymentDetail, amount.getAmount(), disbursementDate,
externalId);
}
public static LoanTransaction repayment(final Money amount, final PaymentDetail paymentDetail, final LocalDate paymentDate, final String externalId) {
return new LoanTransaction(null, LoanTransactionType.REPAYMENT, paymentDetail, amount.getAmount(), paymentDate, externalId);
public static LoanTransaction repayment(final Office office, final Money amount, final PaymentDetail paymentDetail,
final LocalDate paymentDate, final String externalId) {
return new LoanTransaction(null, office, LoanTransactionType.REPAYMENT, paymentDetail, amount.getAmount(), paymentDate, externalId);
}
public static LoanTransaction repaymentAtDisbursement(final Money amount, final PaymentDetail paymentDetail, final LocalDate paymentDate, final String externalId) {
return new LoanTransaction(null, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT, paymentDetail, amount.getAmount(), paymentDate, externalId);
public static LoanTransaction repaymentAtDisbursement(final Office office, final Money amount, final PaymentDetail paymentDetail,
final LocalDate paymentDate, final String externalId) {
return new LoanTransaction(null, office, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT, paymentDetail, amount.getAmount(),
paymentDate, externalId);
}
public static LoanTransaction waiver(final Loan loan, final Money waived, final LocalDate waiveDate) {
return new LoanTransaction(loan, LoanTransactionType.WAIVE_INTEREST, waived.getAmount(), waiveDate, null);
public static LoanTransaction waiver(final Office office, final Loan loan, final Money waived, final LocalDate waiveDate) {
return new LoanTransaction(loan, office, LoanTransactionType.WAIVE_INTEREST, waived.getAmount(), waiveDate, null);
}
public static LoanTransaction applyInterest(final Loan loan, final Money amount, final LocalDate interestAppliedDate) {
return new LoanTransaction(loan, LoanTransactionType.APPLY_INTEREST, amount.getAmount(), interestAppliedDate, null);
public static LoanTransaction applyInterest(final Office office, final Loan loan, final Money amount,
final LocalDate interestAppliedDate) {
return new LoanTransaction(loan, office, LoanTransactionType.APPLY_INTEREST, amount.getAmount(), interestAppliedDate, null);
}
public static LoanTransaction copyTransactionProperties(LoanTransaction loanTransaction) {
return new LoanTransaction(loanTransaction.loan, loanTransaction.typeOf, loanTransaction.dateOf, loanTransaction.amount,
loanTransaction.principalPortion, loanTransaction.interestPortion, loanTransaction.feeChargesPortion,
loanTransaction.penaltyChargesPortion, loanTransaction.reversed, loanTransaction.paymentDetail);
return new LoanTransaction(loanTransaction.loan, loanTransaction.office, loanTransaction.typeOf, loanTransaction.dateOf,
loanTransaction.amount, loanTransaction.principalPortion, loanTransaction.interestPortion,
loanTransaction.feeChargesPortion, loanTransaction.penaltyChargesPortion, loanTransaction.reversed,
loanTransaction.paymentDetail);
}
public static LoanTransaction applyLoanCharge(final Loan loan, final Money amount, final LocalDate applyDate, final Money feeCharges,
final Money penaltyCharges) {
LoanTransaction applyCharge = new LoanTransaction(loan, LoanTransactionType.APPLY_CHARGES, amount.getAmount(), applyDate, null);
public static LoanTransaction applyLoanCharge(final Loan loan, final Office office, final Money amount, final LocalDate applyDate,
final Money feeCharges, final Money penaltyCharges) {
LoanTransaction applyCharge = new LoanTransaction(loan, office, LoanTransactionType.APPLY_CHARGES, amount.getAmount(), applyDate,
null);
applyCharge.updateChargesComponents(feeCharges, penaltyCharges);
return applyCharge;
}
@@ -135,7 +148,7 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
return false;
}
private LoanTransaction(Loan loan, Integer typeOf, Date dateOf, BigDecimal amount, BigDecimal principalPortion,
private LoanTransaction(Loan loan, Office office, Integer typeOf, Date dateOf, BigDecimal amount, BigDecimal principalPortion,
BigDecimal interestPortion, BigDecimal feeChargesPortion, BigDecimal penaltyChargesPortion, boolean reversed,
PaymentDetail paymentDetail) {
super();
@@ -149,36 +162,40 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
this.penaltyChargesPortion = penaltyChargesPortion;
this.reversed = reversed;
this.paymentDetail = paymentDetail;
this.office = office;
}
public static LoanTransaction waiveLoanCharge(final Loan loan, final Money waived, final LocalDate waiveDate,
public static LoanTransaction waiveLoanCharge(final Loan loan, final Office office, final Money waived, final LocalDate waiveDate,
final Money feeChargesWaived, final Money penaltyChargesWaived) {
LoanTransaction waiver = new LoanTransaction(loan, LoanTransactionType.WAIVE_CHARGES, waived.getAmount(), waiveDate, null);
LoanTransaction waiver = new LoanTransaction(loan, office, LoanTransactionType.WAIVE_CHARGES, waived.getAmount(), waiveDate, null);
waiver.updateChargesComponents(feeChargesWaived, penaltyChargesWaived);
return waiver;
}
public static LoanTransaction writeoff(final Loan loan, final LocalDate writeOffDate, final String externalId) {
return new LoanTransaction(loan, LoanTransactionType.WRITEOFF, null, writeOffDate, externalId);
public static LoanTransaction writeoff(final Loan loan, final Office office, final LocalDate writeOffDate, final String externalId) {
return new LoanTransaction(loan, office, LoanTransactionType.WRITEOFF, null, writeOffDate, externalId);
}
private LoanTransaction(final Loan loan, final LoanTransactionType type, final BigDecimal amount, final LocalDate date, final String externalId) {
private LoanTransaction(final Loan loan, final Office office, final LoanTransactionType type, final BigDecimal amount,
final LocalDate date, final String externalId) {
this.loan = loan;
this.typeOf = type.getValue();
this.amount = amount;
this.dateOf = date.toDateMidnight().toDate();
this.externalId = externalId;
this.office = office;
}
private LoanTransaction(final Loan loan, final LoanTransactionType type, final PaymentDetail paymentDetail, final BigDecimal amount,
final LocalDate date, final String externalId) {
private LoanTransaction(final Loan loan, final Office office, final LoanTransactionType type, final PaymentDetail paymentDetail,
final BigDecimal amount, final LocalDate date, final String externalId) {
this.loan = loan;
this.typeOf = type.getValue();
this.paymentDetail = paymentDetail;
this.amount = amount;
this.dateOf = date.toDateMidnight().toDate();
this.externalId = externalId;
this.office = office;
}
public void reverse() {
@@ -368,6 +385,7 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(this.typeOf);
thisTransactionData.put("id", this.getId());
thisTransactionData.put("officeId", this.office.getId());
thisTransactionData.put("type", transactionType);
thisTransactionData.put("reversed", Boolean.valueOf(this.isReversed()));
thisTransactionData.put("date", this.getTransactionDate());
@@ -411,8 +429,8 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
this.loanChargesPaid = loanChargesPaid;
}
public String getExternalId() {
return externalId;
}
public String getExternalId() {
return externalId;
}
}
@@ -243,8 +243,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final Integer repayEvery = repaymentScheduleDetails.getRepayEvery();
final String frequency = CalendarUtils.getMeetingFrequencyFromPeriodFrequencyType(repaymentScheduleDetails
.getRepaymentPeriodFrequencyType());
calculatedRepaymentsStartingFromDate = CalendarUtils.getFirstRepaymentMeetingDate(calendar, actualDisbursementDate, repayEvery,
frequency);
calculatedRepaymentsStartingFromDate = CalendarUtils.getFirstRepaymentMeetingDate(calendar, actualDisbursementDate,
repayEvery, frequency);
}
}
}
@@ -439,10 +439,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final Money transactionAmountAsMoney = Money.of(loan.getCurrency(), transactionAmount);
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createPaymentDetail(command, changes);
LoanTransaction newTransactionDetail = LoanTransaction.repayment(transactionAmountAsMoney, paymentDetail, transactionDate,
txnExternalId);
LoanTransaction newTransactionDetail = LoanTransaction.repayment(loan.getOffice(), transactionAmountAsMoney, paymentDetail,
transactionDate, txnExternalId);
if (transactionToAdjust.isInterestWaiver()) {
newTransactionDetail = LoanTransaction.waiver(loan, transactionAmountAsMoney, transactionDate);
newTransactionDetail = LoanTransaction.waiver(loan.getOffice(), loan, transactionAmountAsMoney, transactionDate);
}
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
@@ -529,7 +529,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
final Money transactionAmountAsMoney = Money.of(loan.getCurrency(), transactionAmount);
final LoanTransaction waiveInterestTransaction = LoanTransaction.waiver(loan, transactionAmountAsMoney, transactionDate);
final LoanTransaction waiveInterestTransaction = LoanTransaction.waiver(loan.getOffice(), loan, transactionAmountAsMoney,
transactionDate);
final ChangedTransactionDetail changedTransactionDetail = loan.waiveInterest(waiveInterestTransaction,
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds);
@@ -231,7 +231,7 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
* For now, do not allow Clients with active loans to be transferred
* between branches
**/
if (loanRepository.doesClientHaveActiveLoans(client.getId())) { throw new TransferNotSupportedException(); }
//if (loanRepository.doesClientHaveActiveLoans(client.getId())) { throw new TransferNotSupportedException(); }
// set the new office for the client
client.updateOffice(destinationOffice);
}