From b1d2b42da10a29e3fecaf57aee6ae6f234dd243e Mon Sep 17 00:00:00 2001 From: Vishwas Babu A J Date: Wed, 21 Aug 2013 21:52:43 +0530 Subject: [PATCH] linking loan transactions to branches in preparation for inter-branch account transfers --- ..._track_loan_transaction_against_office.sql | 15 ++++ .../journalentry/data/LoanTransactionDTO.java | 9 ++- .../service/AccountingProcessorHelper.java | 5 +- .../CashBasedAccountingProcessorForLoan.java | 4 +- .../portfolio/loanaccount/domain/Loan.java | 67 ++++++++++------ .../domain/LoanAccountDomainServiceJpa.java | 4 +- .../loanaccount/domain/LoanTransaction.java | 76 ++++++++++++------- ...WritePlatformServiceJpaRepositoryImpl.java | 13 ++-- ...WritePlatformServiceJpaRepositoryImpl.java | 2 +- 9 files changed, 128 insertions(+), 67 deletions(-) create mode 100644 mifosng-db/migrations/core_db/V105__track_loan_transaction_against_office.sql diff --git a/mifosng-db/migrations/core_db/V105__track_loan_transaction_against_office.sql b/mifosng-db/migrations/core_db/V105__track_loan_transaction_against_office.sql new file mode 100644 index 000000000..dd5d8e844 --- /dev/null +++ b/mifosng-db/migrations/core_db/V105__track_loan_transaction_against_office.sql @@ -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`); \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/data/LoanTransactionDTO.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/data/LoanTransactionDTO.java index cd17861a0..61679d171 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/data/LoanTransactionDTO.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/data/LoanTransactionDTO.java @@ -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 penaltyPayments; private final List 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 feePayments, final List 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() { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccountingProcessorHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccountingProcessorHelper.java index 7245e7949..a96118bb9 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccountingProcessorHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccountingProcessorHelper.java @@ -69,6 +69,7 @@ public class AccountingProcessorHelper { final List> newTransactionsMap = (List>) accountingBridgeData.get("newLoanTransactions"); for (final Map 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); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java index ed207651b..0eca865cd 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java @@ -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(); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index b88a003ce..f1b3b9b04 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -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 { } } - 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 { 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 { 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 { 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 { } 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 { 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 { 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 { 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 { } } - 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 { 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 { } 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 { 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 { 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 { public void updateLoanRepaymentScheduleDates(final LocalDate meetingStartDate, final String recuringRule, final boolean isHolidayEnabled, final List 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 { 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 { 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 { 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 { } - } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java index 6bbb5ee16..13d6a244a 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java @@ -94,8 +94,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { final List existingReversedTransactionIds = new ArrayList(); 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 holidays = this.holidayRepository .findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), transactionDate.toDate()); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransaction.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransaction.java index c39b04fa1..32302df4f 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransaction.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransaction.java @@ -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 { @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 { @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 loanChargesPaid = new HashSet(); @@ -92,35 +97,43 @@ public final class LoanTransaction extends AbstractPersistable { 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 { 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 { 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 { 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 { this.loanChargesPaid = loanChargesPaid; } - public String getExternalId() { - return externalId; - } + public String getExternalId() { + return externalId; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index f84d63c7f..79791fc3e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -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 existingReversedTransactionIds = new ArrayList(); 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); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/transfer/service/TransferWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/transfer/service/TransferWritePlatformServiceJpaRepositoryImpl.java index 4da7825a5..c0892bbc0 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/transfer/service/TransferWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/transfer/service/TransferWritePlatformServiceJpaRepositoryImpl.java @@ -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); }