MIFOSX-1628 - Added User ID and Datetime to Loan and Savings Transactions
This commit is contained in:
+18
@@ -14,6 +14,7 @@ import java.util.List;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
@@ -41,6 +42,23 @@ public class DateUtils {
|
||||
|
||||
return today;
|
||||
}
|
||||
|
||||
public static LocalDateTime getLocalDateTimeOfTenant() {
|
||||
|
||||
LocalDateTime today = new LocalDateTime();
|
||||
|
||||
final MifosPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
|
||||
|
||||
if (tenant != null) {
|
||||
final DateTimeZone zone = DateTimeZone.forID(tenant.getTimezoneId());
|
||||
if (zone != null) {
|
||||
today = new LocalDateTime(zone);
|
||||
}
|
||||
}
|
||||
|
||||
return today;
|
||||
}
|
||||
|
||||
|
||||
public static LocalDate parseLocalDate(final String stringDate, final String pattern) {
|
||||
|
||||
|
||||
+9
-6
@@ -142,7 +142,7 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
|
||||
final boolean isRecoveryRepayment = false;
|
||||
final LoanTransaction loanRepaymentTransaction = this.loanAccountDomainService.makeRepayment(toLoanAccount,
|
||||
new CommandProcessingResultBuilder(), transactionDate, transactionAmount, paymentDetail, null, null,
|
||||
isRecoveryRepayment, isAccountTransfer);
|
||||
isRecoveryRepayment, isAccountTransfer, null); // FIXME: should not be sending null for currentUser for account transfers
|
||||
|
||||
final AccountTransferDetails accountTransferDetails = this.accountTransferAssembler.assembleSavingsToLoanTransfer(command,
|
||||
fromSavingsAccount, toLoanAccount, withdrawal, loanRepaymentTransaction);
|
||||
@@ -157,7 +157,8 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
|
||||
final Loan fromLoanAccount = this.loanAccountAssembler.assembleFrom(fromLoanAccountId);
|
||||
|
||||
final LoanTransaction loanRefundTransaction = this.loanAccountDomainService.makeRefund(fromLoanAccountId,
|
||||
new CommandProcessingResultBuilder(), transactionDate, transactionAmount, paymentDetail, null, null);
|
||||
new CommandProcessingResultBuilder(), transactionDate, transactionAmount, paymentDetail, null, null,
|
||||
null); // FIXME: should not be sending null for currentUser for account transfers
|
||||
|
||||
final Long toSavingsAccountId = command.longValueOfParameterNamed(toAccountIdParamName);
|
||||
final SavingsAccount toSavingsAccount = this.savingsAccountAssembler.assembleFrom(toSavingsAccountId);
|
||||
@@ -271,13 +272,14 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
|
||||
loanTransaction = this.loanAccountDomainService.makeChargePayment(toLoanAccount, accountTransferDTO.getChargeId(),
|
||||
accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
|
||||
accountTransferDTO.getPaymentDetail(), null, null, accountTransferDTO.getToTransferType(),
|
||||
accountTransferDTO.getLoanInstallmentNumber());
|
||||
accountTransferDTO.getLoanInstallmentNumber(), null); // FIXME: should not be sending null for currentUser for account transfers
|
||||
|
||||
} else {
|
||||
final boolean isRecoveryRepayment = false;
|
||||
loanTransaction = this.loanAccountDomainService.makeRepayment(toLoanAccount, new CommandProcessingResultBuilder(),
|
||||
accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
|
||||
accountTransferDTO.getPaymentDetail(), null, null, isRecoveryRepayment, isAccountTransfer);
|
||||
accountTransferDTO.getPaymentDetail(), null, null, isRecoveryRepayment, isAccountTransfer,
|
||||
null); // FIXME: should not be sending null for currentUser for account transfers
|
||||
}
|
||||
|
||||
accountTransferDetails = this.accountTransferAssembler.assembleSavingsToLoanTransfer(accountTransferDTO, fromSavingsAccount,
|
||||
@@ -344,12 +346,13 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
|
||||
if (LoanTransactionType.DISBURSEMENT.getValue().equals(accountTransferDTO.getFromTransferType())) {
|
||||
loanTransaction = this.loanAccountDomainService.makeDisburseTransaction(accountTransferDTO.getFromAccountId(),
|
||||
accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
|
||||
accountTransferDTO.getPaymentDetail(), accountTransferDTO.getNoteText(), accountTransferDTO.getTxnExternalId());
|
||||
accountTransferDTO.getPaymentDetail(), accountTransferDTO.getNoteText(), accountTransferDTO.getTxnExternalId(),
|
||||
null); // FIXME: should not be sending null for currentUser for account transfers
|
||||
} else {
|
||||
loanTransaction = this.loanAccountDomainService.makeRefund(accountTransferDTO.getFromAccountId(),
|
||||
new CommandProcessingResultBuilder(), accountTransferDTO.getTransactionDate(),
|
||||
accountTransferDTO.getTransactionAmount(), accountTransferDTO.getPaymentDetail(), accountTransferDTO.getNoteText(),
|
||||
accountTransferDTO.getTxnExternalId());
|
||||
accountTransferDTO.getTxnExternalId(), null); // FIXME: should not be sending null for currentUser for account transfers
|
||||
}
|
||||
|
||||
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount,
|
||||
|
||||
+74
-54
@@ -41,6 +41,7 @@ import org.apache.commons.lang.StringUtils;
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
|
||||
@@ -584,7 +585,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
* @param suppliedTransactionDate
|
||||
* @return
|
||||
*/
|
||||
public LoanTransaction handleChargeAppliedTransaction(final LoanCharge loanCharge, final LocalDate suppliedTransactionDate) {
|
||||
public LoanTransaction handleChargeAppliedTransaction(final LoanCharge loanCharge, final LocalDate suppliedTransactionDate,
|
||||
final AppUser currentUser) {
|
||||
final Money chargeAmount = loanCharge.getAmount(getCurrency());
|
||||
Money feeCharges = chargeAmount;
|
||||
Money penaltyCharges = Money.zero(loanCurrency());
|
||||
@@ -609,7 +611,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
final LoanTransaction applyLoanChargeTransaction = LoanTransaction.accrueLoanCharge(this, getOffice(), chargeAmount,
|
||||
transactionDate, feeCharges, penaltyCharges);
|
||||
transactionDate, feeCharges, penaltyCharges, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
Integer installmentNumber = null;
|
||||
final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(applyLoanChargeTransaction, loanCharge, loanCharge.getAmount(
|
||||
getCurrency()).getAmount(), installmentNumber);
|
||||
@@ -864,7 +866,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
public LoanTransaction waiveLoanCharge(final LoanCharge loanCharge, final LoanLifecycleStateMachine loanLifecycleStateMachine,
|
||||
final Map<String, Object> changes, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||
final Integer loanInstallmentNumber, final ScheduleGeneratorDTO scheduleGeneratorDTO, final Money accruedCharge) {
|
||||
final Integer loanInstallmentNumber, final ScheduleGeneratorDTO scheduleGeneratorDTO, final Money accruedCharge,
|
||||
final AppUser currentUser) {
|
||||
|
||||
validateLoanIsNotClosed(loanCharge);
|
||||
|
||||
@@ -902,7 +905,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||
|
||||
final LoanTransaction waiveLoanChargeTransaction = LoanTransaction.waiveLoanCharge(this, getOffice(), amountWaived,
|
||||
transactionDate, feeChargesWaived, penaltyChargesWaived, unrecognizedIncome);
|
||||
transactionDate, feeChargesWaived, penaltyChargesWaived, unrecognizedIncome, DateUtils.getLocalDateTimeOfTenant(), currentUser );
|
||||
final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(waiveLoanChargeTransaction, loanCharge, waiveLoanChargeTransaction
|
||||
.getAmount(getCurrency()).getAmount(), loanInstallmentNumber);
|
||||
waiveLoanChargeTransaction.getLoanChargesPaid().add(loanChargePaidBy);
|
||||
@@ -910,7 +913,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()
|
||||
&& (loanCharge.getDueLocalDate() == null || LocalDate.now().isAfter(loanCharge.getDueLocalDate()))) {
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
||||
}
|
||||
// Waive of charges whose due date falls after latest 'repayment'
|
||||
// transaction dont require entire loan schedule to be reprocessed.
|
||||
@@ -1037,7 +1040,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
this.collateral.addAll(associateWithThisLoan(loanCollateral));
|
||||
}
|
||||
|
||||
public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule) {
|
||||
public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule,
|
||||
AppUser currentUser) {
|
||||
this.repaymentScheduleInstallments.clear();
|
||||
|
||||
for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) {
|
||||
@@ -1054,7 +1058,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
updateLoanScheduleDependentDerivedFields();
|
||||
updateLoanSummaryDerivedFields();
|
||||
applyAccurals();
|
||||
applyAccurals(currentUser);
|
||||
|
||||
}
|
||||
|
||||
@@ -1062,12 +1066,12 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
* method updates accrual derived fields on installments and reverse the
|
||||
* unprocessed transactions
|
||||
*/
|
||||
private void applyAccurals() {
|
||||
private void applyAccurals(AppUser currentUser) {
|
||||
Collection<LoanTransaction> accruals = retreiveListOfAccrualTransactions();
|
||||
if (isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
|
||||
applyPeriodicAccruals(accruals);
|
||||
} else if (isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
|
||||
updateAccrualsForNonPeriodicAccruals(accruals);
|
||||
updateAccrualsForNonPeriodicAccruals(accruals, currentUser);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1097,15 +1101,17 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAccrualsForNonPeriodicAccruals(final Collection<LoanTransaction> accruals) {
|
||||
private void updateAccrualsForNonPeriodicAccruals(final Collection<LoanTransaction> accruals,
|
||||
final AppUser currentUser) {
|
||||
|
||||
final Money interestApplied = Money.of(getCurrency(), this.summary.getTotalInterestCharged());
|
||||
for (LoanTransaction loanTransaction : accruals) {
|
||||
if (loanTransaction.getInterestPortion(getCurrency()).isGreaterThanZero()) {
|
||||
if (loanTransaction.getInterestPortion(getCurrency()).isNotEqualTo(interestApplied)) {
|
||||
loanTransaction.reverse();
|
||||
final LocalDateTime currentDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||
final LoanTransaction interestAppliedTransaction = LoanTransaction.accrueInterest(getOffice(), this, interestApplied,
|
||||
getDisbursementDate());
|
||||
getDisbursementDate(), currentDateTime, currentUser);
|
||||
this.loanTransactions.add(interestAppliedTransaction);
|
||||
}
|
||||
} else {
|
||||
@@ -1115,7 +1121,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
Money chargeAmount = loanCharge.getAmount(getCurrency());
|
||||
if (chargeAmount.isNotEqualTo(loanTransaction.getAmount(getCurrency()))) {
|
||||
loanTransaction.reverse();
|
||||
handleChargeAppliedTransaction(loanCharge, loanTransaction.getTransactionDate());
|
||||
handleChargeAppliedTransaction(loanCharge, loanTransaction.getTransactionDate(), currentUser);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1664,7 +1670,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
final LocalDate submittedOn, final String externalId, final boolean allowTransactionsOnHoliday, final List<Holiday> holidays,
|
||||
final WorkingDays workingDays, final boolean allowTransactionsOnNonWorkingDay, final LocalDate recalculationRestFrequencyDate) {
|
||||
|
||||
updateLoanSchedule(loanSchedule);
|
||||
updateLoanSchedule(loanSchedule, currentUser);
|
||||
|
||||
LoanStatus from = null;
|
||||
if (this.loanStatus != null) {
|
||||
@@ -2027,13 +2033,14 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()
|
||||
&& (fetchRepaymentScheduleInstallment(1).getDueDate().isBefore(LocalDate.now()) || isDisbursementMissed())) {
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
||||
}
|
||||
|
||||
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
||||
updateLoanRepaymentPeriodsDerivedFields(actualDisbursementDate);
|
||||
updateLoanSummaryDerivedFields();
|
||||
handleDisbursementTransaction(actualDisbursementDate);
|
||||
LocalDateTime createdDate = DateUtils.getLocalDateTimeOfTenant();
|
||||
handleDisbursementTransaction(actualDisbursementDate, createdDate, currentUser);
|
||||
|
||||
final Money interestApplied = Money.of(getCurrency(), this.summary.getTotalInterestCharged());
|
||||
|
||||
@@ -2045,7 +2052,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
if (isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
|
||||
final LoanTransaction interestAppliedTransaction = LoanTransaction.accrueInterest(getOffice(), this, interestApplied,
|
||||
actualDisbursementDate);
|
||||
actualDisbursementDate, createdDate, currentUser);
|
||||
this.loanTransactions.add(interestAppliedTransaction);
|
||||
}
|
||||
|
||||
@@ -2054,7 +2061,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public void regenerateScheduleOnDisbursement(final ScheduleGeneratorDTO scheduleGeneratorDTO, final boolean recalculateSchedule,
|
||||
final LocalDate actualDisbursementDate, BigDecimal emiAmount) {
|
||||
final LocalDate actualDisbursementDate, BigDecimal emiAmount, final AppUser currentUser) {
|
||||
boolean isEmiAmountChanged = false;
|
||||
if (this.loanProduct.isMultiDisburseLoan() && emiAmount != null && emiAmount.compareTo(retriveLastEmiAmount()) != 0) {
|
||||
LoanTermVariations loanVariationTerms = new LoanTermVariations(LoanTermVariationType.EMI_AMOUNT.getValue(),
|
||||
@@ -2064,7 +2071,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
if (isRepaymentScheduleRegenerationRequiredForDisbursement(actualDisbursementDate) || recalculateSchedule || isEmiAmountChanged) {
|
||||
regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||
regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2249,11 +2256,12 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
* Ability to regenerate the repayment schedule based on the loans current
|
||||
* details/state.
|
||||
*/
|
||||
public void regenerateRepaymentSchedule(final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
public void regenerateRepaymentSchedule(final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
||||
AppUser currentUser) {
|
||||
|
||||
final LoanScheduleModel loanSchedule = regenerateScheduleModel(scheduleGeneratorDTO);
|
||||
|
||||
updateLoanSchedule(loanSchedule);
|
||||
updateLoanSchedule(loanSchedule, currentUser);
|
||||
Set<LoanCharge> charges = this.charges();
|
||||
for (LoanCharge loanCharge : charges) {
|
||||
recalculateLoanCharge(loanCharge, scheduleGeneratorDTO.getPenaltyWaitPeriod());
|
||||
@@ -2302,7 +2310,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
return loanSchedule;
|
||||
}
|
||||
|
||||
private void handleDisbursementTransaction(final LocalDate disbursedOn) {
|
||||
private void handleDisbursementTransaction(final LocalDate disbursedOn, final LocalDateTime createdDate, final AppUser currentUser) {
|
||||
|
||||
// add repayment transaction to track incoming money from client to mfi
|
||||
// for (charges due at time of disbursement)
|
||||
@@ -2320,7 +2328,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
if (disbursedOn.toDate().equals(this.actualDisbursementDate)) {
|
||||
Money disbursentMoney = Money.zero(getCurrency());
|
||||
final LoanTransaction chargesPayment = LoanTransaction.repaymentAtDisbursement(getOffice(), disbursentMoney, null, disbursedOn,
|
||||
null);
|
||||
null, createdDate, currentUser);
|
||||
final Integer installmentNumber = null;
|
||||
for (final LoanCharge charge : charges()) {
|
||||
if (charge.isDueAtDisbursement()) {
|
||||
@@ -2339,7 +2347,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
* None or Cash based accounting is enabled
|
||||
**/
|
||||
if (isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
|
||||
handleChargeAppliedTransaction(charge, disbursedOn);
|
||||
handleChargeAppliedTransaction(charge, disbursedOn, currentUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2399,7 +2407,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public Map<String, Object> undoDisbursal(final ScheduleGeneratorDTO scheduleGeneratorDTO, final List<Long> existingTransactionIds,
|
||||
final List<Long> existingReversedTransactionIds) {
|
||||
final List<Long> existingReversedTransactionIds, AppUser currentUser) {
|
||||
|
||||
validateAccountStatus(LoanEvent.LOAN_DISBURSAL_UNDO);
|
||||
|
||||
@@ -2430,7 +2438,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
// clear off actual disbusrement date so schedule regeneration
|
||||
// uses expected date.
|
||||
|
||||
regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||
regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
||||
if (isDisbursedAmountChanged) {
|
||||
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
||||
}
|
||||
@@ -2481,7 +2489,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
public ChangedTransactionDetail waiveInterest(final LoanTransaction waiveInterestTransaction,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine, final List<Long> existingTransactionIds,
|
||||
final List<Long> existingReversedTransactionIds, final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
final List<Long> existingReversedTransactionIds, final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
||||
final AppUser currentUser) {
|
||||
|
||||
validateAccountStatus(LoanEvent.LOAN_REPAYMENT_OR_WAIVER);
|
||||
|
||||
@@ -2494,14 +2503,15 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||
|
||||
final ChangedTransactionDetail changedTransactionDetail = handleRepaymentOrRecoveryOrWaiverTransaction(waiveInterestTransaction,
|
||||
loanLifecycleStateMachine, null, scheduleGeneratorDTO);
|
||||
loanLifecycleStateMachine, null, scheduleGeneratorDTO, currentUser);
|
||||
|
||||
return changedTransactionDetail;
|
||||
}
|
||||
|
||||
public ChangedTransactionDetail makeRepayment(final LoanTransaction repaymentTransaction,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine, final List<Long> existingTransactionIds,
|
||||
final List<Long> existingReversedTransactionIds, boolean isRecoveryRepayment, final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
final List<Long> existingReversedTransactionIds, boolean isRecoveryRepayment, final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
||||
final AppUser currentUser) {
|
||||
|
||||
LoanEvent event = null;
|
||||
if (isRecoveryRepayment) {
|
||||
@@ -2523,7 +2533,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||
|
||||
final ChangedTransactionDetail changedTransactionDetail = handleRepaymentOrRecoveryOrWaiverTransaction(repaymentTransaction,
|
||||
loanLifecycleStateMachine, null, scheduleGeneratorDTO);
|
||||
loanLifecycleStateMachine, null, scheduleGeneratorDTO, currentUser);
|
||||
|
||||
return changedTransactionDetail;
|
||||
}
|
||||
@@ -2592,7 +2602,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
private ChangedTransactionDetail handleRepaymentOrRecoveryOrWaiverTransaction(final LoanTransaction loanTransaction,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine, final LoanTransaction adjustedTransaction,
|
||||
final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
final ScheduleGeneratorDTO scheduleGeneratorDTO, final AppUser currentUser) {
|
||||
|
||||
ChangedTransactionDetail changedTransactionDetail = null;
|
||||
|
||||
@@ -2691,7 +2701,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
if (reprocess) {
|
||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
||||
}
|
||||
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
||||
changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(),
|
||||
@@ -2926,7 +2936,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
return loanRepaymentScheduleInstallment;
|
||||
}
|
||||
|
||||
public LoanTransaction deriveDefaultInterestWaiverTransaction() {
|
||||
public LoanTransaction deriveDefaultInterestWaiverTransaction(
|
||||
final LocalDateTime createdDate, final AppUser currentUser) {
|
||||
|
||||
final Money totalInterestOutstanding = getTotalInterestOutstandingOnLoan();
|
||||
Money possibleInterestToWaive = totalInterestOutstanding.copy();
|
||||
@@ -2948,13 +2959,13 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
return LoanTransaction.waiver(getOffice(), this, possibleInterestToWaive, transactionDate, possibleInterestToWaive,
|
||||
possibleInterestToWaive.zero());
|
||||
possibleInterestToWaive.zero(), createdDate, currentUser);
|
||||
}
|
||||
|
||||
public ChangedTransactionDetail adjustExistingTransaction(final LoanTransaction newTransactionDetail,
|
||||
final LoanLifecycleStateMachine loanLifecycleStateMachine, final LoanTransaction transactionForAdjustment,
|
||||
final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||
final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
final ScheduleGeneratorDTO scheduleGeneratorDTO, final AppUser currentUser) {
|
||||
|
||||
HolidayDetailDTO holidayDetailDTO = scheduleGeneratorDTO.getHolidayDetailDTO();
|
||||
validateRepaymentDateIsOnHoliday(newTransactionDetail.getTransactionDate(), holidayDetailDTO.isAllowTransactionsOnHoliday(),
|
||||
@@ -2991,14 +3002,15 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
if (newTransactionDetail.isRepayment() || newTransactionDetail.isInterestWaiver()) {
|
||||
changedTransactionDetail = handleRepaymentOrRecoveryOrWaiverTransaction(newTransactionDetail, loanLifecycleStateMachine,
|
||||
transactionForAdjustment, scheduleGeneratorDTO);
|
||||
transactionForAdjustment, scheduleGeneratorDTO, currentUser);
|
||||
}
|
||||
|
||||
return changedTransactionDetail;
|
||||
}
|
||||
|
||||
public ChangedTransactionDetail undoWrittenOff(final List<Long> existingTransactionIds,
|
||||
final List<Long> existingReversedTransactionIds, final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
final List<Long> existingReversedTransactionIds, final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
||||
final AppUser currentUser) {
|
||||
|
||||
validateAccountStatus(LoanEvent.WRITE_OFF_OUTSTANDING_UNDO);
|
||||
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||
@@ -3010,7 +3022,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
.determineProcessor(this.transactionProcessingStrategy);
|
||||
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
||||
}
|
||||
ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(
|
||||
getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments,
|
||||
@@ -3081,7 +3093,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||
.determineProcessor(this.transactionProcessingStrategy);
|
||||
ChangedTransactionDetail changedTransactionDetail = closeDisbursements(scheduleGeneratorDTO,
|
||||
loanRepaymentScheduleTransactionProcessor);
|
||||
loanRepaymentScheduleTransactionProcessor, currentUser);
|
||||
|
||||
validateAccountStatus(LoanEvent.WRITE_OFF_OUTSTANDING);
|
||||
|
||||
@@ -3119,7 +3131,9 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
throw new InvalidLoanStateTransitionException("writeoff", "cannot.be.a.future.date", errorMessage, writtenOffOnLocalDate);
|
||||
}
|
||||
|
||||
loanTransaction = LoanTransaction.writeoff(this, getOffice(), writtenOffOnLocalDate, txnExternalId);
|
||||
LocalDateTime createdDate = DateUtils.getLocalDateTimeOfTenant();
|
||||
loanTransaction = LoanTransaction.writeoff(this, getOffice(), writtenOffOnLocalDate, txnExternalId,
|
||||
createdDate, currentUser);
|
||||
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.";
|
||||
@@ -3141,14 +3155,15 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
private ChangedTransactionDetail closeDisbursements(final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor) {
|
||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor,
|
||||
final AppUser currentUser) {
|
||||
ChangedTransactionDetail changedTransactionDetail = null;
|
||||
if (isDisbursementAllowed() && atleastOnceDisbursed()) {
|
||||
this.loanRepaymentScheduleDetail.setPrincipal(getDisbursedAmount());
|
||||
removeDisbursementDetail();
|
||||
regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||
regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
||||
}
|
||||
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
||||
changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(),
|
||||
@@ -3178,7 +3193,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
public ChangedTransactionDetail close(final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine,
|
||||
final Map<String, Object> changes, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||
final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
final ScheduleGeneratorDTO scheduleGeneratorDTO, final AppUser currentUser) {
|
||||
|
||||
validateAccountStatus(LoanEvent.LOAN_CLOSED);
|
||||
|
||||
@@ -3206,7 +3221,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||
.determineProcessor(this.transactionProcessingStrategy);
|
||||
ChangedTransactionDetail changedTransactionDetail = closeDisbursements(scheduleGeneratorDTO,
|
||||
loanRepaymentScheduleTransactionProcessor);
|
||||
loanRepaymentScheduleTransactionProcessor, currentUser);
|
||||
|
||||
LoanTransaction loanTransaction = null;
|
||||
if (isOpen()) {
|
||||
@@ -3220,7 +3235,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
changes.put("status", LoanEnumerations.status(this.loanStatus));
|
||||
}
|
||||
this.closedOnDate = closureDate.toDate();
|
||||
loanTransaction = LoanTransaction.writeoff(this, getOffice(), closureDate, txnExternalId);
|
||||
loanTransaction = LoanTransaction.writeoff(this, getOffice(), closureDate, txnExternalId,
|
||||
DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
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.";
|
||||
@@ -4316,7 +4332,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
public ChangedTransactionDetail updateDisbursementDateForTranche(final LoanDisbursementDetails disbursementDetails,
|
||||
final JsonCommand command, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||
final Map<String, Object> actualChanges, final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
final Map<String, Object> actualChanges, final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
||||
final AppUser currentUser) {
|
||||
validateAccountStatus(LoanEvent.LOAN_EDIT_MULTI_DISBURSE_DATE);
|
||||
final LocalDate expectedDisbursementDate = command.localDateValueOfParameterNamed(LoanApiConstants.disbursementDateParameterName);
|
||||
disbursementDetails.updateExpectedDisbursementDate(expectedDisbursementDate.toDate());
|
||||
@@ -4328,9 +4345,9 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||
|
||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
||||
} else {
|
||||
regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||
regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
||||
}
|
||||
|
||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||
@@ -4409,7 +4426,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public ChangedTransactionDetail recalculateScheduleFromLastTransaction(final ScheduleGeneratorDTO generatorDTO,
|
||||
final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds) {
|
||||
final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||
final AppUser currentUser) {
|
||||
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||
/*
|
||||
@@ -4423,14 +4441,15 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
* generatorDTO.setRecalculateFrom(recalculateFrom);
|
||||
*/
|
||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(generatorDTO);
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(generatorDTO, currentUser);
|
||||
}
|
||||
return processTransactions();
|
||||
|
||||
}
|
||||
|
||||
public ChangedTransactionDetail handleRegenerateRepaymentScheduleWithInterestRecalculation(final ScheduleGeneratorDTO generatorDTO) {
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(generatorDTO);
|
||||
public ChangedTransactionDetail handleRegenerateRepaymentScheduleWithInterestRecalculation(final ScheduleGeneratorDTO generatorDTO,
|
||||
final AppUser currentUser) {
|
||||
regenerateRepaymentScheduleWithInterestRecalculation(generatorDTO, currentUser);
|
||||
return processTransactions();
|
||||
|
||||
}
|
||||
@@ -4459,13 +4478,14 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
return changedTransactionDetail;
|
||||
}
|
||||
|
||||
private void regenerateRepaymentScheduleWithInterestRecalculation(final ScheduleGeneratorDTO generatorDTO) {
|
||||
private void regenerateRepaymentScheduleWithInterestRecalculation(final ScheduleGeneratorDTO generatorDTO,
|
||||
final AppUser currentUser) {
|
||||
|
||||
LocalDate lastTransactionDate = getLastUserTransactionDate();
|
||||
generatorDTO.setLastTransactionDate(lastTransactionDate);
|
||||
final LoanScheduleModel loanSchedule = getRecalculatedSchedule(generatorDTO);
|
||||
if (loanSchedule == null) { return; }
|
||||
updateLoanSchedule(loanSchedule);
|
||||
updateLoanSchedule(loanSchedule, currentUser);
|
||||
LocalDate lastRepaymentDate = this.getLastRepaymentPeriodDueDate();
|
||||
|
||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||
|
||||
+7
-4
@@ -12,23 +12,26 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
|
||||
public interface LoanAccountDomainService {
|
||||
|
||||
LoanTransaction makeRepayment(Loan loan, CommandProcessingResultBuilder builderResult, LocalDate transactionDate,
|
||||
BigDecimal transactionAmount, PaymentDetail paymentDetail, String noteText, String txnExternalId,
|
||||
final boolean isRecoveryRepayment, boolean isAccountTransfer);
|
||||
final boolean isRecoveryRepayment, boolean isAccountTransfer, final AppUser currentUser);
|
||||
|
||||
LoanTransaction makeRefund(Long accountId, CommandProcessingResultBuilder builderResult, LocalDate transactionDate,
|
||||
BigDecimal transactionAmount, PaymentDetail paymentDetail, String noteText, String txnExternalId);
|
||||
BigDecimal transactionAmount, PaymentDetail paymentDetail, String noteText, String txnExternalId,
|
||||
final AppUser currentUser);
|
||||
|
||||
void reverseTransfer(LoanTransaction loanTransaction);
|
||||
|
||||
LoanTransaction makeChargePayment(Loan loan, Long chargeId, LocalDate transactionDate, BigDecimal transactionAmount,
|
||||
PaymentDetail paymentDetail, String noteText, String txnExternalId, Integer transactionType, Integer installmentNumber);
|
||||
PaymentDetail paymentDetail, String noteText, String txnExternalId, Integer transactionType, Integer installmentNumber,
|
||||
final AppUser currentUser);
|
||||
|
||||
LoanTransaction makeDisburseTransaction(Long loanId, LocalDate transactionDate, BigDecimal transactionAmount,
|
||||
PaymentDetail paymentDetail, String noteText, String txnExternalId);
|
||||
PaymentDetail paymentDetail, String noteText, String txnExternalId, final AppUser currentUser);
|
||||
|
||||
LocalDate getCalculatedRepaymentsStartingFromDate(LocalDate actualDisbursementDate, Loan loan, CalendarInstance calendarInstance);
|
||||
|
||||
|
||||
+15
-10
@@ -15,6 +15,7 @@ import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.mifosplatform.accounting.journalentry.service.JournalEntryWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
@@ -22,6 +23,7 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.organisation.holiday.domain.Holiday;
|
||||
import org.mifosplatform.organisation.holiday.domain.HolidayRepository;
|
||||
import org.mifosplatform.organisation.holiday.domain.HolidayStatusType;
|
||||
@@ -54,6 +56,7 @@ import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||
import org.mifosplatform.portfolio.note.domain.Note;
|
||||
import org.mifosplatform.portfolio.note.domain.NoteRepository;
|
||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -112,7 +115,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
@Override
|
||||
public LoanTransaction makeRepayment(final Loan loan, final CommandProcessingResultBuilder builderResult,
|
||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final String noteText,
|
||||
final String txnExternalId, final boolean isRecoveryRepayment, boolean isAccountTransfer) {
|
||||
final String txnExternalId, final boolean isRecoveryRepayment, boolean isAccountTransfer,
|
||||
final AppUser currentUser) {
|
||||
|
||||
checkClientOrGroupActive(loan);
|
||||
|
||||
@@ -134,12 +138,13 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
|
||||
final Money repaymentAmount = Money.of(loan.getCurrency(), transactionAmount);
|
||||
LoanTransaction newRepaymentTransaction = null;
|
||||
final LocalDateTime currentDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||
if (isRecoveryRepayment) {
|
||||
newRepaymentTransaction = LoanTransaction.recoveryRepayment(loan.getOffice(), repaymentAmount, paymentDetail, transactionDate,
|
||||
txnExternalId);
|
||||
txnExternalId, currentDateTime, currentUser);
|
||||
} else {
|
||||
newRepaymentTransaction = LoanTransaction.repayment(loan.getOffice(), repaymentAmount, paymentDetail, transactionDate,
|
||||
txnExternalId);
|
||||
txnExternalId, currentDateTime, currentUser);
|
||||
}
|
||||
|
||||
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
||||
@@ -177,7 +182,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
|
||||
final ChangedTransactionDetail changedTransactionDetail = loan.makeRepayment(newRepaymentTransaction,
|
||||
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, isRecoveryRepayment,
|
||||
scheduleGeneratorDTO);
|
||||
scheduleGeneratorDTO, currentUser);
|
||||
|
||||
saveLoanTransactionWithDataIntegrityViolationChecks(newRepaymentTransaction);
|
||||
|
||||
@@ -257,7 +262,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
@Transactional
|
||||
public LoanTransaction makeChargePayment(final Loan loan, final Long chargeId, final LocalDate transactionDate,
|
||||
final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final String noteText, final String txnExternalId,
|
||||
final Integer transactionType, Integer installmentNumber) {
|
||||
final Integer transactionType, Integer installmentNumber, final AppUser currentUser) {
|
||||
|
||||
boolean isAccountTransfer = true;
|
||||
checkClientOrGroupActive(loan);
|
||||
@@ -269,7 +274,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
final LoanTransactionType loanTransactionType = LoanTransactionType.fromInt(transactionType);
|
||||
|
||||
final LoanTransaction newPaymentTransaction = LoanTransaction.loanPayment(null, loan.getOffice(), paymentAmout, paymentDetail,
|
||||
transactionDate, txnExternalId, loanTransactionType);
|
||||
transactionDate, txnExternalId, loanTransactionType, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
|
||||
if (loanTransactionType.isRepaymentAtDisbursement()) {
|
||||
loan.handlePayDisbursementTransaction(chargeId, newPaymentTransaction, existingTransactionIds, existingReversedTransactionIds);
|
||||
@@ -329,7 +334,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
@Override
|
||||
public LoanTransaction makeRefund(final Long accountId, final CommandProcessingResultBuilder builderResult,
|
||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final String noteText,
|
||||
final String txnExternalId) {
|
||||
final String txnExternalId, final AppUser currentUser) {
|
||||
boolean isAccountTransfer = true;
|
||||
final Loan loan = this.loanAccountAssembler.assembleFrom(accountId);
|
||||
checkClientOrGroupActive(loan);
|
||||
@@ -339,7 +344,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
|
||||
final Money refundAmount = Money.of(loan.getCurrency(), transactionAmount);
|
||||
final LoanTransaction newRefundTransaction = LoanTransaction.refund(loan.getOffice(), refundAmount, paymentDetail, transactionDate,
|
||||
txnExternalId);
|
||||
txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
|
||||
transactionDate.toDate(), HolidayStatusType.ACTIVE.getValue());
|
||||
@@ -370,7 +375,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
@Transactional
|
||||
@Override
|
||||
public LoanTransaction makeDisburseTransaction(final Long loanId, final LocalDate transactionDate, final BigDecimal transactionAmount,
|
||||
final PaymentDetail paymentDetail, final String noteText, final String txnExternalId) {
|
||||
final PaymentDetail paymentDetail, final String noteText, final String txnExternalId, final AppUser currentUser) {
|
||||
final Loan loan = this.loanAccountAssembler.assembleFrom(loanId);
|
||||
checkClientOrGroupActive(loan);
|
||||
boolean isAccountTransfer = true;
|
||||
@@ -378,7 +383,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||
final Money amount = Money.of(loan.getCurrency(), transactionAmount);
|
||||
LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), amount, paymentDetail, transactionDate,
|
||||
txnExternalId);
|
||||
txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
disbursementTransaction.updateLoan(loan);
|
||||
loan.getLoanTransactions().add(disbursementTransaction);
|
||||
saveLoanTransactionWithDataIntegrityViolationChecks(disbursementTransaction);
|
||||
|
||||
+61
-32
@@ -28,6 +28,7 @@ import javax.persistence.UniqueConstraint;
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
@@ -39,6 +40,7 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData;
|
||||
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
|
||||
import org.mifosplatform.portfolio.paymentdetail.data.PaymentDetailData;
|
||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
/**
|
||||
@@ -98,6 +100,14 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
|
||||
@Column(name = "external_id", length = 100, nullable = true, unique = true)
|
||||
private String externalId;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "created_date", nullable = false)
|
||||
private final Date createdDate;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name="appuser_id", nullable = true)
|
||||
private final AppUser appUser;
|
||||
|
||||
@LazyCollection(LazyCollectionOption.FALSE)
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loanTransaction", orphanRemoval = true)
|
||||
@@ -114,46 +124,51 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
this.dateOf = null;
|
||||
this.typeOf = null;
|
||||
this.submittedOnDate = DateUtils.getDateOfTenant();
|
||||
this.createdDate = new Date();
|
||||
this.appUser = null;
|
||||
}
|
||||
|
||||
public static LoanTransaction disbursement(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||
final LocalDate disbursementDate, final String externalId) {
|
||||
final LocalDate disbursementDate, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
||||
return new LoanTransaction(null, office, LoanTransactionType.DISBURSEMENT, paymentDetail, amount.getAmount(), disbursementDate,
|
||||
externalId);
|
||||
externalId, createdDate, appUser);
|
||||
}
|
||||
|
||||
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);
|
||||
final LocalDate paymentDate, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
||||
return new LoanTransaction(null, office, LoanTransactionType.REPAYMENT, paymentDetail, amount.getAmount(), paymentDate, externalId,
|
||||
createdDate, appUser);
|
||||
}
|
||||
|
||||
public static LoanTransaction recoveryRepayment(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||
final LocalDate paymentDate, final String externalId) {
|
||||
final LocalDate paymentDate, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
||||
return new LoanTransaction(null, office, LoanTransactionType.RECOVERY_REPAYMENT, paymentDetail, amount.getAmount(), paymentDate,
|
||||
externalId);
|
||||
externalId, createdDate, appUser);
|
||||
}
|
||||
|
||||
public static LoanTransaction loanPayment(final Loan loan, final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||
final LocalDate paymentDate, final String externalId, final LoanTransactionType transactionType) {
|
||||
return new LoanTransaction(loan, office, transactionType, paymentDetail, amount.getAmount(), paymentDate, externalId);
|
||||
final LocalDate paymentDate, final String externalId, final LoanTransactionType transactionType,
|
||||
final LocalDateTime createdDate, final AppUser appUser){
|
||||
return new LoanTransaction(loan, office, transactionType, paymentDetail, amount.getAmount(), paymentDate, externalId,
|
||||
createdDate, appUser);
|
||||
}
|
||||
|
||||
public static LoanTransaction repaymentAtDisbursement(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||
final LocalDate paymentDate, final String externalId) {
|
||||
final LocalDate paymentDate, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
||||
return new LoanTransaction(null, office, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT, paymentDetail, amount.getAmount(),
|
||||
paymentDate, externalId);
|
||||
paymentDate, externalId, createdDate, appUser);
|
||||
}
|
||||
|
||||
public static LoanTransaction waiver(final Office office, final Loan loan, final Money amount, final LocalDate waiveDate,
|
||||
final Money waived, final Money unrecognizedPortion) {
|
||||
final Money waived, final Money unrecognizedPortion, final LocalDateTime createdDate, final AppUser appUser) {
|
||||
LoanTransaction loanTransaction = new LoanTransaction(loan, office, LoanTransactionType.WAIVE_INTEREST, amount.getAmount(),
|
||||
waiveDate, null);
|
||||
waiveDate, null, createdDate, appUser);
|
||||
loanTransaction.updateInterestComponent(waived, unrecognizedPortion);
|
||||
return loanTransaction;
|
||||
}
|
||||
|
||||
public static LoanTransaction accrueInterest(final Office office, final Loan loan, final Money amount,
|
||||
final LocalDate interestAppliedDate) {
|
||||
final LocalDate interestAppliedDate, final LocalDateTime createdDate, final AppUser appUser) {
|
||||
BigDecimal principalPortion = null;
|
||||
BigDecimal feesPortion = null;
|
||||
BigDecimal penaltiesPortion = null;
|
||||
@@ -163,47 +178,53 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
PaymentDetail paymentDetail = null;
|
||||
String externalId = null;
|
||||
return new LoanTransaction(loan, office, LoanTransactionType.ACCRUAL.getValue(), interestAppliedDate.toDate(), interestPortion,
|
||||
principalPortion, interestPortion, feesPortion, penaltiesPortion, overPaymentPortion, reversed, paymentDetail, externalId);
|
||||
principalPortion, interestPortion, feesPortion, penaltiesPortion, overPaymentPortion, reversed, paymentDetail, externalId,
|
||||
createdDate, appUser);
|
||||
}
|
||||
|
||||
public static LoanTransaction initiateTransfer(final Office office, final Loan loan, final LocalDate transferDate) {
|
||||
public static LoanTransaction initiateTransfer(final Office office, final Loan loan, final LocalDate transferDate,
|
||||
final LocalDateTime createdDate, final AppUser appUser) {
|
||||
return new LoanTransaction(loan, office, LoanTransactionType.INITIATE_TRANSFER.getValue(), transferDate.toDateTimeAtStartOfDay()
|
||||
.toDate(), loan.getSummary().getTotalOutstanding(), loan.getSummary().getTotalPrincipalOutstanding(), loan.getSummary()
|
||||
.getTotalInterestOutstanding(), loan.getSummary().getTotalFeeChargesOutstanding(), loan.getSummary()
|
||||
.getTotalPenaltyChargesOutstanding(), null, false, null, null);
|
||||
.getTotalPenaltyChargesOutstanding(), null, false, null, null, createdDate, appUser);
|
||||
}
|
||||
|
||||
public static LoanTransaction approveTransfer(final Office office, final Loan loan, final LocalDate transferDate) {
|
||||
public static LoanTransaction approveTransfer(final Office office, final Loan loan, final LocalDate transferDate,
|
||||
final LocalDateTime createdDate, final AppUser appUser) {
|
||||
return new LoanTransaction(loan, office, LoanTransactionType.APPROVE_TRANSFER.getValue(), transferDate.toDateTimeAtStartOfDay()
|
||||
.toDate(), loan.getSummary().getTotalOutstanding(), loan.getSummary().getTotalPrincipalOutstanding(), loan.getSummary()
|
||||
.getTotalInterestOutstanding(), loan.getSummary().getTotalFeeChargesOutstanding(), loan.getSummary()
|
||||
.getTotalPenaltyChargesOutstanding(), null, false, null, null);
|
||||
.getTotalPenaltyChargesOutstanding(), null, false, null, null, createdDate, appUser);
|
||||
}
|
||||
|
||||
public static LoanTransaction withdrawTransfer(final Office office, final Loan loan, final LocalDate transferDate) {
|
||||
public static LoanTransaction withdrawTransfer(final Office office, final Loan loan, final LocalDate transferDate,
|
||||
final LocalDateTime createdDate, final AppUser appUser) {
|
||||
return new LoanTransaction(loan, office, LoanTransactionType.WITHDRAW_TRANSFER.getValue(), transferDate.toDateTimeAtStartOfDay()
|
||||
.toDate(), loan.getSummary().getTotalOutstanding(), loan.getSummary().getTotalPrincipalOutstanding(), loan.getSummary()
|
||||
.getTotalInterestOutstanding(), loan.getSummary().getTotalFeeChargesOutstanding(), loan.getSummary()
|
||||
.getTotalPenaltyChargesOutstanding(), null, false, null, null);
|
||||
.getTotalPenaltyChargesOutstanding(), null, false, null, null, createdDate, appUser);
|
||||
}
|
||||
|
||||
public static LoanTransaction refund(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||
final LocalDate paymentDate, final String externalId) {
|
||||
return new LoanTransaction(null, office, LoanTransactionType.REFUND, paymentDetail, amount.getAmount(), paymentDate, externalId);
|
||||
final LocalDate paymentDate, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
||||
return new LoanTransaction(null, office, LoanTransactionType.REFUND, paymentDetail, amount.getAmount(), paymentDate, externalId,
|
||||
createdDate, appUser);
|
||||
}
|
||||
|
||||
public static LoanTransaction copyTransactionProperties(final LoanTransaction loanTransaction) {
|
||||
return new LoanTransaction(loanTransaction.loan, loanTransaction.office, loanTransaction.typeOf, loanTransaction.dateOf,
|
||||
loanTransaction.amount, loanTransaction.principalPortion, loanTransaction.interestPortion,
|
||||
loanTransaction.feeChargesPortion, loanTransaction.penaltyChargesPortion, loanTransaction.overPaymentPortion,
|
||||
loanTransaction.reversed, loanTransaction.paymentDetail, loanTransaction.externalId);
|
||||
loanTransaction.reversed, loanTransaction.paymentDetail, loanTransaction.externalId,
|
||||
new LocalDateTime(loanTransaction.createdDate), loanTransaction.appUser);
|
||||
}
|
||||
|
||||
public static LoanTransaction accrueLoanCharge(final Loan loan, final Office office, final Money amount, final LocalDate applyDate,
|
||||
final Money feeCharges, final Money penaltyCharges) {
|
||||
final Money feeCharges, final Money penaltyCharges, final LocalDateTime createdDate, final AppUser appUser) {
|
||||
String externalId = null;
|
||||
final LoanTransaction applyCharge = new LoanTransaction(loan, office, LoanTransactionType.ACCRUAL, amount.getAmount(), applyDate,
|
||||
externalId);
|
||||
externalId, createdDate, appUser);
|
||||
applyCharge.updateChargesComponents(feeCharges, penaltyCharges);
|
||||
return applyCharge;
|
||||
}
|
||||
@@ -222,7 +243,7 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
private LoanTransaction(final Loan loan, final Office office, final Integer typeOf, final Date dateOf, final BigDecimal amount,
|
||||
final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion,
|
||||
final BigDecimal penaltyChargesPortion, final BigDecimal overPaymentPortion, final boolean reversed,
|
||||
final PaymentDetail paymentDetail, final String externalId) {
|
||||
final PaymentDetail paymentDetail, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
||||
super();
|
||||
this.loan = loan;
|
||||
this.typeOf = typeOf;
|
||||
@@ -238,23 +259,27 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
this.office = office;
|
||||
this.externalId = externalId;
|
||||
this.submittedOnDate = DateUtils.getDateOfTenant();
|
||||
this.createdDate = createdDate.toDate();
|
||||
this.appUser = appUser;
|
||||
}
|
||||
|
||||
public static LoanTransaction waiveLoanCharge(final Loan loan, final Office office, final Money waived, final LocalDate waiveDate,
|
||||
final Money feeChargesWaived, final Money penaltyChargesWaived, final Money unrecognizedCharge) {
|
||||
final Money feeChargesWaived, final Money penaltyChargesWaived, final Money unrecognizedCharge,
|
||||
final LocalDateTime createdDate, final AppUser appUser) {
|
||||
final LoanTransaction waiver = new LoanTransaction(loan, office, LoanTransactionType.WAIVE_CHARGES, waived.getAmount(), waiveDate,
|
||||
null);
|
||||
null, createdDate, appUser);
|
||||
waiver.updateChargesComponents(feeChargesWaived, penaltyChargesWaived, unrecognizedCharge);
|
||||
|
||||
return waiver;
|
||||
}
|
||||
|
||||
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);
|
||||
public static LoanTransaction writeoff(final Loan loan, final Office office, final LocalDate writeOffDate, final String externalId,
|
||||
final LocalDateTime createdDate, final AppUser appUser) {
|
||||
return new LoanTransaction(loan, office, LoanTransactionType.WRITEOFF, null, writeOffDate, externalId, createdDate, appUser);
|
||||
}
|
||||
|
||||
private LoanTransaction(final Loan loan, final Office office, final LoanTransactionType type, final BigDecimal amount,
|
||||
final LocalDate date, final String externalId) {
|
||||
final LocalDate date, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
||||
this.loan = loan;
|
||||
this.typeOf = type.getValue();
|
||||
this.amount = amount;
|
||||
@@ -262,10 +287,12 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
this.externalId = externalId;
|
||||
this.office = office;
|
||||
this.submittedOnDate = DateUtils.getDateOfTenant();
|
||||
this.createdDate = createdDate.toDate();
|
||||
this.appUser = appUser;
|
||||
}
|
||||
|
||||
private LoanTransaction(final Loan loan, final Office office, final LoanTransactionType type, final PaymentDetail paymentDetail,
|
||||
final BigDecimal amount, final LocalDate date, final String externalId) {
|
||||
final BigDecimal amount, final LocalDate date, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
||||
this.loan = loan;
|
||||
this.typeOf = type.getValue();
|
||||
this.paymentDetail = paymentDetail;
|
||||
@@ -274,6 +301,8 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
this.externalId = externalId;
|
||||
this.office = office;
|
||||
this.submittedOnDate = DateUtils.getDateOfTenant();
|
||||
this.createdDate = createdDate.toDate();
|
||||
this.appUser = appUser;
|
||||
}
|
||||
|
||||
public void reverse() {
|
||||
|
||||
+3
-1
@@ -16,6 +16,7 @@ import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
@@ -169,7 +170,8 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
|
||||
modifiedTransactions.add(LoanTransaction.copyTransactionProperties(loanTransaction));
|
||||
}
|
||||
if (isNewPaymentRequired) {
|
||||
LoanTransaction ondayPaymentTransaction = LoanTransaction.repayment(null, totalAmount, null, LocalDate.now(), null);
|
||||
LoanTransaction ondayPaymentTransaction = LoanTransaction.repayment(null, totalAmount, null, LocalDate.now(), null,
|
||||
DateUtils.getLocalDateTimeOfTenant(), null);
|
||||
modifiedTransactions.add(ondayPaymentTransaction);
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -360,7 +360,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
public CommandProcessingResult modifyApplication(final Long loanId, final JsonCommand command) {
|
||||
|
||||
try {
|
||||
this.context.authenticatedUser();
|
||||
AppUser currentUser = this.context.authenticatedUser();
|
||||
|
||||
this.fromApiJsonDeserializer.validateForModify(command.json());
|
||||
|
||||
@@ -519,7 +519,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
final JsonQuery query = JsonQuery.from(command.json(), parsedQuery, this.fromJsonHelper);
|
||||
|
||||
final LoanScheduleModel loanSchedule = this.calculationPlatformService.calculateLoanSchedule(query, false);
|
||||
existingLoanApplication.updateLoanSchedule(loanSchedule);
|
||||
existingLoanApplication.updateLoanSchedule(loanSchedule, currentUser);
|
||||
existingLoanApplication.recalculateAllCharges();
|
||||
}
|
||||
|
||||
@@ -733,7 +733,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
// to recompute the schedule
|
||||
if (changes.containsKey(LoanApiConstants.approvedLoanAmountParameterName)) {
|
||||
ScheduleGeneratorDTO scheduleGeneratorDTO = loanAccountDomainService.buildScheduleGeneratorDTO(loan);
|
||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
||||
}
|
||||
|
||||
this.loanRepository.save(loan);
|
||||
@@ -761,7 +761,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
@Override
|
||||
public CommandProcessingResult undoApplicationApproval(final Long loanId, final JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
AppUser currentUser = this.context.authenticatedUser();
|
||||
|
||||
this.fromApiJsonDeserializer.validateForUndo(command.json());
|
||||
|
||||
@@ -777,7 +777,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
if (changes.containsKey(LoanApiConstants.approvedLoanAmountParameterName)
|
||||
|| changes.containsKey(LoanApiConstants.disbursementPrincipalParameterName )) {
|
||||
ScheduleGeneratorDTO scheduleGeneratorDTO = loanAccountDomainService.buildScheduleGeneratorDTO(loan);
|
||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
||||
}
|
||||
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
+3
-2
@@ -405,7 +405,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
@Override
|
||||
public LoanTransactionData retrieveWaiveInterestDetails(final Long loanId) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
AppUser currentUser = this.context.authenticatedUser();
|
||||
|
||||
// TODO - KW -OPTIMIZE - write simple sql query to fetch back overdue
|
||||
// interest that can be waived along with the date of repayment period
|
||||
@@ -417,7 +417,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
||||
final CurrencyData currencyData = applicationCurrency.toData();
|
||||
|
||||
final LoanTransaction waiveOfInterest = loan.deriveDefaultInterestWaiverTransaction();
|
||||
final LoanTransaction waiveOfInterest = loan.deriveDefaultInterestWaiverTransaction(
|
||||
DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
|
||||
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.WAIVE_INTEREST);
|
||||
|
||||
|
||||
+75
-27
@@ -32,6 +32,7 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRul
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformServiceUnavailableException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.infrastructure.jobs.annotation.CronTarget;
|
||||
import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException;
|
||||
import org.mifosplatform.infrastructure.jobs.service.JobName;
|
||||
@@ -316,7 +317,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
existingTransactionIds.addAll(loan.findExistingTransactionIds());
|
||||
existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());
|
||||
LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), disburseAmount, paymentDetail,
|
||||
actualDisbursementDate, txnExternalId);
|
||||
actualDisbursementDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
disbursementTransaction.updateLoan(loan);
|
||||
loan.getLoanTransactions().add(disbursementTransaction);
|
||||
}
|
||||
@@ -565,7 +566,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
existingTransactionIds.addAll(loan.findExistingTransactionIds());
|
||||
existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());
|
||||
LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), disburseAmount, paymentDetail,
|
||||
actualDisbursementDate, txnExternalId);
|
||||
actualDisbursementDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
disbursementTransaction.updateLoan(loan);
|
||||
loan.getLoanTransactions().add(disbursementTransaction);
|
||||
}
|
||||
@@ -641,6 +642,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
@Override
|
||||
public CommandProcessingResult undoLoanDisbursal(final Long loanId, final JsonCommand command) {
|
||||
|
||||
final AppUser currentUser = this.context.authenticatedUser();
|
||||
|
||||
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||
checkClientOrGroupActive(loan);
|
||||
removeLoanCycle(loan);
|
||||
@@ -668,7 +671,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO);
|
||||
|
||||
final Map<String, Object> changes = loan
|
||||
.undoDisbursal(scheduleGeneratorDTO, existingTransactionIds, existingReversedTransactionIds);
|
||||
.undoDisbursal(scheduleGeneratorDTO, existingTransactionIds, existingReversedTransactionIds, currentUser);
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
@@ -702,7 +705,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
@Override
|
||||
public CommandProcessingResult makeLoanRepayment(final Long loanId, final JsonCommand command, final boolean isRecoveryRepayment) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
AppUser currentUser = null;
|
||||
if (this.context != null) {
|
||||
currentUser = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
this.loanEventApiJsonValidator.validateNewRepaymentTransaction(command.json());
|
||||
|
||||
@@ -727,7 +733,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
boolean isAccountTransfer = false;
|
||||
final CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder();
|
||||
this.loanAccountDomainService.makeRepayment(loan, commandProcessingResultBuilder, transactionDate, transactionAmount,
|
||||
paymentDetail, noteText, txnExternalId, isRecoveryRepayment, isAccountTransfer);
|
||||
paymentDetail, noteText, txnExternalId, isRecoveryRepayment, isAccountTransfer, currentUser);
|
||||
|
||||
return commandProcessingResultBuilder.withCommandId(command.commandId()) //
|
||||
.withLoanId(loanId) //
|
||||
@@ -739,7 +745,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
@Override
|
||||
public Map<String, Object> makeLoanBulkRepayment(final CollectionSheetBulkRepaymentCommand bulkRepaymentCommand) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
AppUser currentUser = this.context.authenticatedUser();
|
||||
final SingleRepaymentCommand[] repaymentCommand = bulkRepaymentCommand.getLoanTransactions();
|
||||
final Map<String, Object> changes = new LinkedHashMap<>();
|
||||
final boolean isRecoveryRepayment = false;
|
||||
@@ -756,7 +762,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder();
|
||||
this.loanAccountDomainService.makeRepayment(loan, commandProcessingResultBuilder, bulkRepaymentCommand.getTransactionDate(),
|
||||
singleLoanRepaymentCommand.getTransactionAmount(), paymentDetail, bulkRepaymentCommand.getNote(), null,
|
||||
isRecoveryRepayment, isAccountTransfer);
|
||||
isRecoveryRepayment, isAccountTransfer, currentUser);
|
||||
|
||||
changes.put("bulkTransactions", singleLoanRepaymentCommand);
|
||||
}
|
||||
@@ -767,7 +773,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
@Override
|
||||
public CommandProcessingResult adjustLoanTransaction(final Long loanId, final Long transactionId, final JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
AppUser currentUser = null;
|
||||
if (this.context != null) {
|
||||
currentUser = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
this.loanEventApiJsonValidator.validateTransaction(command.json());
|
||||
|
||||
@@ -800,7 +809,7 @@ 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(loan.getOffice(), transactionAmountAsMoney, paymentDetail,
|
||||
transactionDate, txnExternalId);
|
||||
transactionDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
if (transactionToAdjust.isInterestWaiver()) {
|
||||
Money unrecognizedIncome = transactionAmountAsMoney.zero();
|
||||
Money interestComponent = transactionAmountAsMoney;
|
||||
@@ -812,7 +821,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
}
|
||||
}
|
||||
newTransactionDetail = LoanTransaction.waiver(loan.getOffice(), loan, transactionAmountAsMoney, transactionDate,
|
||||
interestComponent, unrecognizedIncome);
|
||||
interestComponent, unrecognizedIncome, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
}
|
||||
|
||||
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
||||
@@ -852,7 +861,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
final ChangedTransactionDetail changedTransactionDetail = loan.adjustExistingTransaction(newTransactionDetail,
|
||||
defaultLoanLifecycleStateMachine(), transactionToAdjust, existingTransactionIds, existingReversedTransactionIds,
|
||||
scheduleGeneratorDTO);
|
||||
scheduleGeneratorDTO, currentUser);
|
||||
|
||||
if (newTransactionDetail.isGreaterThanZero(loan.getPrincpal().getCurrency())) {
|
||||
if (paymentDetail != null) {
|
||||
@@ -914,7 +923,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
@Override
|
||||
public CommandProcessingResult waiveInterestOnLoan(final Long loanId, final JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
AppUser currentUser = this.context.authenticatedUser();
|
||||
|
||||
this.loanEventApiJsonValidator.validateTransaction(command.json());
|
||||
|
||||
@@ -943,7 +952,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
}
|
||||
}
|
||||
final LoanTransaction waiveInterestTransaction = LoanTransaction.waiver(loan.getOffice(), loan, transactionAmountAsMoney,
|
||||
transactionDate, interestComponent, unrecognizedIncome);
|
||||
transactionDate, interestComponent, unrecognizedIncome, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
|
||||
CalendarInstance restCalendarInstance = null;
|
||||
ApplicationCurrency applicationCurrency = null;
|
||||
@@ -976,7 +985,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, recalculateFrom, overdurPenaltyWaitPeriod,
|
||||
lastTransactionDate);
|
||||
final ChangedTransactionDetail changedTransactionDetail = loan.waiveInterest(waiveInterestTransaction,
|
||||
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO);
|
||||
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO,
|
||||
currentUser);
|
||||
|
||||
this.loanTransactionRepository.save(waiveInterestTransaction);
|
||||
|
||||
@@ -1096,7 +1106,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
@Override
|
||||
public CommandProcessingResult closeLoan(final Long loanId, final JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
AppUser currentUser = this.context.authenticatedUser();
|
||||
|
||||
this.loanEventApiJsonValidator.validateTransactionWithNoAmount(command.json());
|
||||
|
||||
@@ -1140,7 +1150,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, recalculateFrom, overdurPenaltyWaitPeriod,
|
||||
lastTransactionDate);
|
||||
ChangedTransactionDetail changedTransactionDetail = loan.close(command, defaultLoanLifecycleStateMachine(), changes,
|
||||
existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO);
|
||||
existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO, currentUser);
|
||||
final LoanTransaction possibleClosingTransaction = changedTransactionDetail.getNewTransactionMappings().remove(0L);
|
||||
if (possibleClosingTransaction != null) {
|
||||
this.loanTransactionRepository.save(possibleClosingTransaction);
|
||||
@@ -1300,6 +1310,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
}
|
||||
|
||||
public void runScheduleRecalculation(Loan loan) {
|
||||
AppUser currentUser = null;
|
||||
if (this.context != null) {
|
||||
currentUser = this.context.authenticatedUser();
|
||||
}
|
||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||
CalendarInstance restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_DETAIL.getValue());
|
||||
@@ -1325,7 +1339,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, recalculateFrom,
|
||||
overdurPenaltyWaitPeriod, lastTransactionDate);
|
||||
ChangedTransactionDetail changedTransactionDetail = loan
|
||||
.handleRegenerateRepaymentScheduleWithInterestRecalculation(generatorDTO);
|
||||
.handleRegenerateRepaymentScheduleWithInterestRecalculation(generatorDTO, currentUser);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
if (changedTransactionDetail != null) {
|
||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
@@ -1365,6 +1379,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
private boolean addCharge(final Loan loan, final Charge chargeDefinition, final LoanCharge loanCharge) {
|
||||
|
||||
AppUser currentUser = null;
|
||||
if (this.context != null) {
|
||||
currentUser = this.context.authenticatedUser();
|
||||
}
|
||||
if (!loan.hasCurrencyCodeOf(chargeDefinition.getCurrencyCode())) {
|
||||
final String errorMessage = "Charge and Loan must have the same currency.";
|
||||
throw new InvalidCurrencyException("loanCharge", "attach.to.loan", errorMessage);
|
||||
@@ -1390,7 +1408,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
**/
|
||||
if (loan.status().isActive()) {
|
||||
if (loan.isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
|
||||
final LoanTransaction applyLoanChargeTransaction = loan.handleChargeAppliedTransaction(loanCharge, null);
|
||||
final LoanTransaction applyLoanChargeTransaction = loan.handleChargeAppliedTransaction(loanCharge, null, currentUser);
|
||||
this.loanTransactionRepository.save(applyLoanChargeTransaction);
|
||||
}
|
||||
/***
|
||||
@@ -1455,7 +1473,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
@Override
|
||||
public CommandProcessingResult waiveLoanCharge(final Long loanId, final Long loanChargeId, final JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
AppUser currentUser = this.context.authenticatedUser();
|
||||
|
||||
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||
checkClientOrGroupActive(loan);
|
||||
@@ -1539,7 +1557,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
}
|
||||
|
||||
final LoanTransaction waiveTransaction = loan.waiveLoanCharge(loanCharge, defaultLoanLifecycleStateMachine(), changes,
|
||||
existingTransactionIds, existingReversedTransactionIds, loanInstallmentNumber, scheduleGeneratorDTO, accruedCharge);
|
||||
existingTransactionIds, existingReversedTransactionIds, loanInstallmentNumber, scheduleGeneratorDTO, accruedCharge,
|
||||
currentUser);
|
||||
|
||||
this.loanTransactionRepository.save(waiveTransaction);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
@@ -1758,6 +1777,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
@Transactional
|
||||
@Override
|
||||
public LoanTransaction initiateLoanTransfer(final Long accountId, final LocalDate transferDate) {
|
||||
|
||||
AppUser currentUser = null;
|
||||
if (this.context != null) {
|
||||
currentUser = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final Loan loan = this.loanAssembler.assembleFrom(accountId);
|
||||
checkClientOrGroupActive(loan);
|
||||
@@ -1765,7 +1789,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final List<Long> existingTransactionIds = new ArrayList<>(loan.findExistingTransactionIds());
|
||||
final List<Long> existingReversedTransactionIds = new ArrayList<>(loan.findExistingReversedTransactionIds());
|
||||
|
||||
final LoanTransaction newTransferTransaction = LoanTransaction.initiateTransfer(loan.getOffice(), loan, transferDate);
|
||||
final LoanTransaction newTransferTransaction = LoanTransaction.initiateTransfer(loan.getOffice(), loan, transferDate,
|
||||
DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
loan.getLoanTransactions().add(newTransferTransaction);
|
||||
loan.setLoanStatus(LoanStatus.TRANSFER_IN_PROGRESS.getValue());
|
||||
|
||||
@@ -1781,13 +1806,19 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
@Override
|
||||
public LoanTransaction acceptLoanTransfer(final Long accountId, final LocalDate transferDate, final Office acceptedInOffice,
|
||||
final Staff loanOfficer) {
|
||||
|
||||
AppUser currentUser = null;
|
||||
if (this.context != null) {
|
||||
currentUser = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final Loan loan = this.loanAssembler.assembleFrom(accountId);
|
||||
|
||||
final List<Long> existingTransactionIds = new ArrayList<>(loan.findExistingTransactionIds());
|
||||
final List<Long> existingReversedTransactionIds = new ArrayList<>(loan.findExistingReversedTransactionIds());
|
||||
|
||||
final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.approveTransfer(acceptedInOffice, loan, transferDate);
|
||||
final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.approveTransfer(acceptedInOffice, loan, transferDate,
|
||||
DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
loan.getLoanTransactions().add(newTransferAcceptanceTransaction);
|
||||
if (loan.getTotalOverpaid() != null) {
|
||||
loan.setLoanStatus(LoanStatus.OVERPAID.getValue());
|
||||
@@ -1809,12 +1840,19 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
@Transactional
|
||||
@Override
|
||||
public LoanTransaction withdrawLoanTransfer(final Long accountId, final LocalDate transferDate) {
|
||||
|
||||
AppUser currentUser = null;
|
||||
if (this.context != null) {
|
||||
currentUser = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final Loan loan = this.loanAssembler.assembleFrom(accountId);
|
||||
|
||||
final List<Long> existingTransactionIds = new ArrayList<>(loan.findExistingTransactionIds());
|
||||
final List<Long> existingReversedTransactionIds = new ArrayList<>(loan.findExistingReversedTransactionIds());
|
||||
|
||||
final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.withdrawTransfer(loan.getOffice(), loan, transferDate);
|
||||
final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.withdrawTransfer(loan.getOffice(), loan, transferDate,
|
||||
DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||
loan.getLoanTransactions().add(newTransferAcceptanceTransaction);
|
||||
loan.setLoanStatus(LoanStatus.ACTIVE.getValue());
|
||||
|
||||
@@ -2355,6 +2393,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult undoWriteOff(Long loanId) {
|
||||
final AppUser currentUser = this.context.authenticatedUser();
|
||||
|
||||
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||
checkClientOrGroupActive(loan);
|
||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||
@@ -2395,7 +2435,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
lastTransactionDate);
|
||||
|
||||
ChangedTransactionDetail changedTransactionDetail = loan.undoWrittenOff(existingTransactionIds, existingReversedTransactionIds,
|
||||
scheduleGeneratorDTO);
|
||||
scheduleGeneratorDTO, currentUser);
|
||||
if (changedTransactionDetail != null) {
|
||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
this.loanTransactionRepository.save(mapEntry.getValue());
|
||||
@@ -2417,6 +2457,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
@Override
|
||||
@Transactional
|
||||
public CommandProcessingResult updateDisbursementDateForTranche(final Long loanId, final Long disbursementId, final JsonCommand command) {
|
||||
|
||||
AppUser currentUser = this.context.authenticatedUser();
|
||||
|
||||
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||
checkClientOrGroupActive(loan);
|
||||
@@ -2452,7 +2494,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
lastTransactionDate);
|
||||
|
||||
final ChangedTransactionDetail changedTransactionDetail = loan.updateDisbursementDateForTranche(loanDisbursementDetails, command,
|
||||
existingTransactionIds, existingReversedTransactionIds, changes, scheduleGeneratorDTO);
|
||||
existingTransactionIds, existingReversedTransactionIds, changes, scheduleGeneratorDTO, currentUser);
|
||||
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
@@ -2555,6 +2597,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
@Transactional
|
||||
public void recalculateInterest(final long loanId) {
|
||||
AppUser currentUser = null;
|
||||
if (this.context != null) {
|
||||
currentUser = this.context.authenticatedUser();
|
||||
}
|
||||
Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||
CalendarInstance restCalendarInstance = null;
|
||||
ApplicationCurrency applicationCurrency = null;
|
||||
@@ -2589,7 +2635,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
lastTransactionDate);
|
||||
|
||||
ChangedTransactionDetail changedTransactionDetail = loan.recalculateScheduleFromLastTransaction(generatorDTO,
|
||||
existingTransactionIds, existingReversedTransactionIds);
|
||||
existingTransactionIds, existingReversedTransactionIds, currentUser);
|
||||
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
@@ -2620,9 +2666,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
private void regenerateScheduleOnDisbursement(final JsonCommand command, final Loan loan, final boolean recalculateSchedule,
|
||||
final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
AppUser currentUser = this.context.authenticatedUser();
|
||||
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
|
||||
BigDecimal emiAmount = command.bigDecimalValueOfParameterNamed(LoanApiConstants.emiAmountParameterName);
|
||||
loan.regenerateScheduleOnDisbursement(scheduleGeneratorDTO, recalculateSchedule, actualDisbursementDate, emiAmount);
|
||||
loan.regenerateScheduleOnDisbursement(scheduleGeneratorDTO, recalculateSchedule, actualDisbursementDate, emiAmount,
|
||||
currentUser);
|
||||
}
|
||||
|
||||
private List<LoanRepaymentScheduleInstallment> retrieveRepaymentScheduleFromModel(LoanScheduleModel model) {
|
||||
|
||||
+11
-2
@@ -11,6 +11,7 @@ import java.util.Date;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
|
||||
public class SavingsAccountTransactionDTO {
|
||||
|
||||
@@ -20,15 +21,18 @@ public class SavingsAccountTransactionDTO {
|
||||
private final PaymentDetail paymentDetail;
|
||||
private final Date createdDate;
|
||||
private final Long savingsAccountId;
|
||||
private final AppUser appUser;
|
||||
|
||||
public SavingsAccountTransactionDTO(final DateTimeFormatter formatter, final LocalDate transactionDate,
|
||||
final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final Date createdDate) {
|
||||
final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final Date createdDate,
|
||||
final AppUser appUser) {
|
||||
this.formatter = formatter;
|
||||
this.transactionDate = transactionDate;
|
||||
this.transactionAmount = transactionAmount;
|
||||
this.paymentDetail = paymentDetail;
|
||||
this.createdDate = createdDate;
|
||||
this.savingsAccountId = null;
|
||||
this.appUser = appUser;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,13 +46,14 @@ public class SavingsAccountTransactionDTO {
|
||||
* @param savingsAccountId
|
||||
*/
|
||||
public SavingsAccountTransactionDTO(DateTimeFormatter formatter, LocalDate transactionDate, BigDecimal transactionAmount,
|
||||
PaymentDetail paymentDetail, Date createdDate, Long savingsAccountId) {
|
||||
PaymentDetail paymentDetail, Date createdDate, Long savingsAccountId, AppUser appUser) {
|
||||
this.formatter = formatter;
|
||||
this.transactionDate = transactionDate;
|
||||
this.transactionAmount = transactionAmount;
|
||||
this.paymentDetail = paymentDetail;
|
||||
this.createdDate = createdDate;
|
||||
this.savingsAccountId = savingsAccountId;
|
||||
this.appUser = appUser;
|
||||
}
|
||||
|
||||
public DateTimeFormatter getFormatter() {
|
||||
@@ -74,5 +79,9 @@ public class SavingsAccountTransactionDTO {
|
||||
public Long getSavingsAccountId() {
|
||||
return this.savingsAccountId;
|
||||
}
|
||||
|
||||
public AppUser getAppUser() {
|
||||
return this.appUser;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+10
-2
@@ -52,6 +52,7 @@ import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||
import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.account.service.AccountTransfersReadPlatformService;
|
||||
@@ -88,6 +89,7 @@ import com.google.gson.JsonObject;
|
||||
@Service
|
||||
public class DepositAccountAssembler {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
|
||||
private final SavingsHelper savingsHelper;
|
||||
private final ClientRepositoryWrapper clientRepository;
|
||||
@@ -108,7 +110,8 @@ public class DepositAccountAssembler {
|
||||
final SavingsAccountChargeAssembler savingsAccountChargeAssembler, final FromJsonHelper fromApiJsonHelper,
|
||||
final DepositProductAssembler depositProductAssembler,
|
||||
final RecurringDepositProductRepository recurringDepositProductRepository,
|
||||
final AccountTransfersReadPlatformService accountTransfersReadPlatformService) {
|
||||
final AccountTransfersReadPlatformService accountTransfersReadPlatformService,
|
||||
final PlatformSecurityContext context) {
|
||||
|
||||
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
|
||||
this.clientRepository = clientRepository;
|
||||
@@ -121,6 +124,7 @@ public class DepositAccountAssembler {
|
||||
this.depositProductAssembler = depositProductAssembler;
|
||||
this.recurringDepositProductRepository = recurringDepositProductRepository;
|
||||
this.savingsHelper = new SavingsHelper(accountTransfersReadPlatformService);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -390,6 +394,10 @@ public class DepositAccountAssembler {
|
||||
}
|
||||
|
||||
public Collection<SavingsAccountTransactionDTO> assembleBulkMandatorySavingsAccountTransactionDTOs(final JsonCommand command) {
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
final String json = command.json();
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
@@ -412,7 +420,7 @@ public class DepositAccountAssembler {
|
||||
final BigDecimal dueAmount = this.fromApiJsonHelper.extractBigDecimalNamed(transactionAmountParamName,
|
||||
savingsTransactionElement, locale);
|
||||
final SavingsAccountTransactionDTO savingsAccountTransactionDTO = new SavingsAccountTransactionDTO(formatter,
|
||||
transactionDate, dueAmount, paymentDetail, new Date(), savingsId);
|
||||
transactionDate, dueAmount, paymentDetail, new Date(), savingsId, user);
|
||||
savingsAccountTransactions.add(savingsAccountTransactionDTO);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -232,7 +232,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
||||
depositAccountAssembler.assignSavingAccountHelpers(reinvestedDeposit);
|
||||
reinvestedDeposit.updateMaturityDateAndAmount(mc, isPreMatureClosure,
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
reinvestedDeposit.processAccountUponActivation(fmt);
|
||||
reinvestedDeposit.processAccountUponActivation(fmt, user);
|
||||
reinvestedDeposit.updateMaturityDateAndAmount(mc, isPreMatureClosure,
|
||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
this.savingsAccountRepository.save(reinvestedDeposit);
|
||||
|
||||
+1
-1
@@ -180,7 +180,7 @@ public class FixedDepositAccount extends SavingsAccount {
|
||||
List<SavingsAccountTransaction> allTransactions = new ArrayList<>();
|
||||
final Money transactionAmountMoney = Money.of(getCurrency(), this.accountTermAndPreClosure.depositAmount());
|
||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(null, office(), null,
|
||||
this.accountSubmittedOrActivationDate(), transactionAmountMoney, new Date());
|
||||
this.accountSubmittedOrActivationDate(), transactionAmountMoney, new Date(), null); // TODO: verify if it is ok to pass null for AppUser
|
||||
transaction.updateRunningBalance(transactionAmountMoney);
|
||||
transaction.updateCumulativeBalanceAndDates(this.getCurrency(), interestCalculatedUpto());
|
||||
allTransactions.add(transaction);
|
||||
|
||||
+1437
-1069
File diff suppressed because it is too large
Load Diff
+26
-21
@@ -738,7 +738,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
final Money amount = Money.of(this.currency, transactionDTO.getTransactionAmount());
|
||||
|
||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(this, office(), transactionDTO.getPaymentDetail(),
|
||||
transactionDTO.getTransactionDate(), amount, transactionDTO.getCreatedDate());
|
||||
transactionDTO.getTransactionDate(), amount, transactionDTO.getCreatedDate(), transactionDTO.getAppUser());
|
||||
this.transactions.add(transaction);
|
||||
|
||||
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
||||
@@ -821,21 +821,23 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
final Money transactionAmountMoney = Money.of(this.currency, transactionDTO.getTransactionAmount());
|
||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.withdrawal(this, office(),
|
||||
transactionDTO.getPaymentDetail(), transactionDTO.getTransactionDate(), transactionAmountMoney,
|
||||
transactionDTO.getCreatedDate());
|
||||
transactionDTO.getCreatedDate(), transactionDTO.getAppUser());
|
||||
this.transactions.add(transaction);
|
||||
|
||||
if (applyWithdrawFee) {
|
||||
// auto pay withdrawal fee
|
||||
payWithdrawalFee(transactionDTO.getTransactionAmount(), transactionDTO.getTransactionDate());
|
||||
payWithdrawalFee(transactionDTO.getTransactionAmount(), transactionDTO.getTransactionDate(),
|
||||
transactionDTO.getAppUser());
|
||||
}
|
||||
return transaction;
|
||||
}
|
||||
|
||||
private void payWithdrawalFee(final BigDecimal transactionAmoount, final LocalDate transactionDate) {
|
||||
private void payWithdrawalFee(final BigDecimal transactionAmoount, final LocalDate transactionDate,
|
||||
final AppUser user) {
|
||||
for (SavingsAccountCharge charge : this.charges()) {
|
||||
if (charge.isWithdrawalFee() && charge.isActive()) {
|
||||
charge.updateWithdralFeeAmount(transactionAmoount);
|
||||
this.payCharge(charge, charge.getAmountOutstanding(this.getCurrency()), transactionDate);
|
||||
this.payCharge(charge, charge.getAmountOutstanding(this.getCurrency()), transactionDate, user);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1817,7 +1819,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public void processAccountUponActivation(final boolean isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||
final Integer financialYearBeginningMonth) {
|
||||
final Integer financialYearBeginningMonth, final AppUser user) {
|
||||
|
||||
// update annual fee due date
|
||||
for (SavingsAccountCharge charge : this.charges()) {
|
||||
@@ -1825,7 +1827,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
// auto pay the activation time charges
|
||||
this.payActivationCharges(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
this.payActivationCharges(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, user);
|
||||
// TODO : AA add activation charges to actual changes list
|
||||
}
|
||||
|
||||
@@ -1848,12 +1850,13 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
this.lockedInUntilDate = calculateDateAccountIsLockedUntil(getActivationLocalDate());
|
||||
}
|
||||
|
||||
private void payActivationCharges(final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth) {
|
||||
private void payActivationCharges(final boolean isSavingsInterestPostingAtCurrentPeriodEnd, final Integer financialYearBeginningMonth,
|
||||
final AppUser user) {
|
||||
boolean isSavingsChargeApplied = false;
|
||||
for (SavingsAccountCharge savingsAccountCharge : this.charges()) {
|
||||
if (savingsAccountCharge.isSavingsActivation()) {
|
||||
isSavingsChargeApplied = true;
|
||||
payCharge(savingsAccountCharge, savingsAccountCharge.getAmountOutstanding(getCurrency()), getActivationLocalDate());
|
||||
payCharge(savingsAccountCharge, savingsAccountCharge.getAmountOutstanding(getCurrency()), getActivationLocalDate(), user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2037,7 +2040,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
this.charges.remove(charge);
|
||||
}
|
||||
|
||||
public void waiveCharge(final Long savingsAccountChargeId) {
|
||||
public void waiveCharge(final Long savingsAccountChargeId, final AppUser user) {
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
@@ -2076,7 +2079,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
|
||||
// waive charge
|
||||
final Money amountWaived = savingsAccountCharge.waive(getCurrency());
|
||||
handleWaiverChargeTransactions(savingsAccountCharge, amountWaived);
|
||||
handleWaiverChargeTransactions(savingsAccountCharge, amountWaived, user);
|
||||
|
||||
}
|
||||
|
||||
@@ -2167,7 +2170,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public void payCharge(final SavingsAccountCharge savingsAccountCharge, final BigDecimal amountPaid, final LocalDate transactionDate,
|
||||
final DateTimeFormatter formatter) {
|
||||
final DateTimeFormatter formatter, final AppUser user) {
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
@@ -2242,32 +2245,34 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
this.payCharge(savingsAccountCharge, chargePaid, transactionDate);
|
||||
this.payCharge(savingsAccountCharge, chargePaid, transactionDate, user);
|
||||
}
|
||||
|
||||
public void payCharge(final SavingsAccountCharge savingsAccountCharge, final Money amountPaid, final LocalDate transactionDate) {
|
||||
public void payCharge(final SavingsAccountCharge savingsAccountCharge, final Money amountPaid, final LocalDate transactionDate,
|
||||
final AppUser user) {
|
||||
savingsAccountCharge.pay(getCurrency(), amountPaid);
|
||||
handlePayChargeTransactions(savingsAccountCharge, amountPaid, transactionDate);
|
||||
handlePayChargeTransactions(savingsAccountCharge, amountPaid, transactionDate, user);
|
||||
}
|
||||
|
||||
private void handlePayChargeTransactions(SavingsAccountCharge savingsAccountCharge, Money transactionAmount,
|
||||
final LocalDate transactionDate) {
|
||||
final LocalDate transactionDate, final AppUser user) {
|
||||
SavingsAccountTransaction chargeTransaction = null;
|
||||
|
||||
if (savingsAccountCharge.isWithdrawalFee()) {
|
||||
chargeTransaction = SavingsAccountTransaction.withdrawalFee(this, office(), transactionDate, transactionAmount);
|
||||
chargeTransaction = SavingsAccountTransaction.withdrawalFee(this, office(), transactionDate, transactionAmount, user);
|
||||
} else if (savingsAccountCharge.isAnnualFee()) {
|
||||
chargeTransaction = SavingsAccountTransaction.annualFee(this, office(), transactionDate, transactionAmount);
|
||||
chargeTransaction = SavingsAccountTransaction.annualFee(this, office(), transactionDate, transactionAmount, user);
|
||||
} else {
|
||||
chargeTransaction = SavingsAccountTransaction.charge(this, office(), transactionDate, transactionAmount);
|
||||
chargeTransaction = SavingsAccountTransaction.charge(this, office(), transactionDate, transactionAmount, user);
|
||||
}
|
||||
|
||||
handleChargeTransactions(savingsAccountCharge, chargeTransaction);
|
||||
}
|
||||
|
||||
private void handleWaiverChargeTransactions(SavingsAccountCharge savingsAccountCharge, Money transactionAmount) {
|
||||
private void handleWaiverChargeTransactions(SavingsAccountCharge savingsAccountCharge, Money transactionAmount,
|
||||
AppUser user) {
|
||||
final SavingsAccountTransaction chargeTransaction = SavingsAccountTransaction.waiver(this, office(),
|
||||
DateUtils.getLocalDateOfTenant(), transactionAmount);
|
||||
DateUtils.getLocalDateOfTenant(), transactionAmount, user);
|
||||
handleChargeTransactions(savingsAccountCharge, chargeTransaction);
|
||||
}
|
||||
|
||||
|
||||
+16
-3
@@ -17,6 +17,7 @@ import org.joda.time.format.DateTimeFormatter;
|
||||
import org.mifosplatform.accounting.journalentry.service.JournalEntryWritePlatformService;
|
||||
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
@@ -24,6 +25,7 @@ import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||
import org.mifosplatform.portfolio.savings.SavingsTransactionBooleanValues;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDTO;
|
||||
import org.mifosplatform.portfolio.savings.exception.DepositAccountTransactionNotAllowedException;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -31,6 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
@Service
|
||||
public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainService {
|
||||
|
||||
private final PlatformSecurityContext context;
|
||||
private final SavingsAccountRepositoryWrapper savingsAccountRepository;
|
||||
private final SavingsAccountTransactionRepository savingsAccountTransactionRepository;
|
||||
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper;
|
||||
@@ -42,12 +45,14 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
final SavingsAccountTransactionRepository savingsAccountTransactionRepository,
|
||||
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
|
||||
final JournalEntryWritePlatformService journalEntryWritePlatformService,
|
||||
final ConfigurationDomainService configurationDomainService) {
|
||||
final ConfigurationDomainService configurationDomainService,
|
||||
final PlatformSecurityContext context) {
|
||||
this.savingsAccountRepository = savingsAccountRepository;
|
||||
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
||||
this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper;
|
||||
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
||||
this.configurationDomainService = configurationDomainService;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -56,6 +61,10 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
|
||||
final SavingsTransactionBooleanValues transactionBooleanValues) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService
|
||||
@@ -67,7 +76,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||
paymentDetail, new Date());
|
||||
paymentDetail, new Date(), user);
|
||||
final SavingsAccountTransaction withdrawal = account.withdraw(transactionDTO, transactionBooleanValues.isApplyWithdrawFee());
|
||||
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -97,6 +106,10 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
|
||||
final boolean isAccountTransfer, final boolean isRegularTransaction) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService
|
||||
@@ -110,7 +123,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||
paymentDetail, new Date());
|
||||
paymentDetail, new Date(), user);
|
||||
final SavingsAccountTransaction deposit = account.deposit(transactionDTO);
|
||||
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
|
||||
+35
-25
@@ -37,6 +37,7 @@ import org.mifosplatform.portfolio.savings.SavingsAccountTransactionType;
|
||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionEnumData;
|
||||
import org.mifosplatform.portfolio.savings.domain.interest.EndOfDayBalance;
|
||||
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@@ -96,6 +97,10 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "created_date", nullable = false)
|
||||
private final Date createdDate;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "appuser_id", nullable = false)
|
||||
private AppUser appUser;
|
||||
|
||||
protected SavingsAccountTransaction() {
|
||||
this.dateOf = null;
|
||||
@@ -104,97 +109,101 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final Office office,
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, Date createdDate) {
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, Date createdDate, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.DEPOSIT.getValue(), date,
|
||||
createdDate, amount, isReversed);
|
||||
createdDate, amount, isReversed, appUser);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction withdrawal(final SavingsAccount savingsAccount, final Office office,
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, Date createdDate) {
|
||||
final PaymentDetail paymentDetail, final LocalDate date, final Money amount, Date createdDate, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.WITHDRAWAL.getValue(),
|
||||
date, createdDate, amount, isReversed);
|
||||
date, createdDate, amount, isReversed, appUser);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction interestPosting(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.INTEREST_POSTING.getValue(), date,
|
||||
amount, isReversed);
|
||||
amount, isReversed, null);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction withdrawalFee(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount) {
|
||||
final Money amount, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue(), date, amount,
|
||||
isReversed);
|
||||
isReversed, appUser);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction annualFee(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount) {
|
||||
final Money amount, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.ANNUAL_FEE.getValue(), date, amount,
|
||||
isReversed);
|
||||
isReversed, appUser);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction charge(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount) {
|
||||
final Money amount, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.PAY_CHARGE.getValue(), date, amount,
|
||||
isReversed);
|
||||
isReversed, appUser);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction waiver(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount) {
|
||||
final Money amount, final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.WAIVE_CHARGES.getValue(), date, amount,
|
||||
isReversed);
|
||||
isReversed, appUser);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction initiateTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date) {
|
||||
public static SavingsAccountTransaction initiateTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final PaymentDetail paymentDetail = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail,
|
||||
SavingsAccountTransactionType.INITIATE_TRANSFER.getValue(), date, new Date(), savingsAccount.getSummary()
|
||||
.getAccountBalance(), isReversed);
|
||||
.getAccountBalance(), isReversed, appUser);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction approveTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date) {
|
||||
public static SavingsAccountTransaction approveTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final PaymentDetail paymentDetail = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail,
|
||||
SavingsAccountTransactionType.APPROVE_TRANSFER.getValue(), date, new Date(), savingsAccount.getSummary()
|
||||
.getAccountBalance(), isReversed);
|
||||
.getAccountBalance(), isReversed, appUser);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction withdrawTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date) {
|
||||
public static SavingsAccountTransaction withdrawTransfer(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final AppUser appUser) {
|
||||
final boolean isReversed = false;
|
||||
final PaymentDetail paymentDetail = null;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail,
|
||||
SavingsAccountTransactionType.WITHDRAW_TRANSFER.getValue(), date, new Date(), savingsAccount.getSummary()
|
||||
.getAccountBalance(), isReversed);
|
||||
.getAccountBalance(), isReversed, appUser);
|
||||
}
|
||||
|
||||
public static SavingsAccountTransaction copyTransaction(SavingsAccountTransaction accountTransaction) {
|
||||
return new SavingsAccountTransaction(accountTransaction.savingsAccount, accountTransaction.office,
|
||||
accountTransaction.paymentDetail, accountTransaction.typeOf, accountTransaction.transactionLocalDate(),
|
||||
accountTransaction.createdDate, accountTransaction.amount, accountTransaction.reversed);
|
||||
accountTransaction.createdDate, accountTransaction.amount, accountTransaction.reversed, accountTransaction.appUser);
|
||||
}
|
||||
|
||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final Integer typeOf,
|
||||
final LocalDate transactionLocalDate, final Money amount, final boolean isReversed) {
|
||||
this(savingsAccount, office, null, typeOf, transactionLocalDate, new Date(), amount, isReversed);
|
||||
final LocalDate transactionLocalDate, final Money amount, final boolean isReversed, final AppUser appUser) {
|
||||
this(savingsAccount, office, null, typeOf, transactionLocalDate, new Date(), amount, isReversed, appUser);
|
||||
}
|
||||
|
||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
|
||||
final Integer typeOf, final LocalDate transactionLocalDate, final Date createdDate, final Money amount, final boolean isReversed) {
|
||||
this(savingsAccount, office, paymentDetail, typeOf, transactionLocalDate, createdDate, amount.getAmount(), isReversed);
|
||||
final Integer typeOf, final LocalDate transactionLocalDate, final Date createdDate, final Money amount, final boolean isReversed,
|
||||
final AppUser appUser) {
|
||||
this(savingsAccount, office, paymentDetail, typeOf, transactionLocalDate, createdDate, amount.getAmount(), isReversed, appUser);
|
||||
}
|
||||
|
||||
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
|
||||
final Integer typeOf, final LocalDate transactionLocalDate, final Date createdDate, final BigDecimal amount,
|
||||
final boolean isReversed) {
|
||||
final boolean isReversed, final AppUser appUser) {
|
||||
this.savingsAccount = savingsAccount;
|
||||
this.office = office;
|
||||
this.typeOf = typeOf;
|
||||
@@ -203,6 +212,7 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
||||
this.reversed = isReversed;
|
||||
this.paymentDetail = paymentDetail;
|
||||
this.createdDate = createdDate;
|
||||
this.appUser = appUser;
|
||||
}
|
||||
|
||||
public LocalDate transactionLocalDate() {
|
||||
|
||||
+37
-9
@@ -583,6 +583,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
|
||||
@Override
|
||||
public CommandProcessingResult adjustRDTransaction(final Long savingsId, final Long transactionId, final JsonCommand command) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -625,11 +630,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
SavingsAccountTransaction transaction = null;
|
||||
if (savingsAccountTransaction.isDeposit()) {
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||
paymentDetail, savingsAccountTransaction.createdDate());
|
||||
paymentDetail, savingsAccountTransaction.createdDate(), user);
|
||||
transaction = account.deposit(transactionDTO);
|
||||
} else {
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||
paymentDetail, savingsAccountTransaction.createdDate());
|
||||
paymentDetail, savingsAccountTransaction.createdDate(), user);
|
||||
transaction = account.withdraw(transactionDTO, true);
|
||||
}
|
||||
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
|
||||
@@ -825,6 +830,10 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
public SavingsAccountTransaction initiateSavingsTransfer(final Long accountId, final LocalDate transferDate,
|
||||
final DepositAccountType depositAccountType) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
@@ -836,7 +845,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final SavingsAccountTransaction newTransferTransaction = SavingsAccountTransaction.initiateTransfer(savingsAccount,
|
||||
savingsAccount.office(), transferDate);
|
||||
savingsAccount.office(), transferDate, user);
|
||||
savingsAccount.getTransactions().add(newTransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -855,6 +864,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@Override
|
||||
public SavingsAccountTransaction withdrawSavingsTransfer(final Long accountId, final LocalDate transferDate,
|
||||
final DepositAccountType depositAccountType) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -867,7 +881,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final SavingsAccountTransaction withdrawtransferTransaction = SavingsAccountTransaction.withdrawTransfer(savingsAccount,
|
||||
savingsAccount.office(), transferDate);
|
||||
savingsAccount.office(), transferDate, user);
|
||||
savingsAccount.getTransactions().add(withdrawtransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -894,6 +908,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
public SavingsAccountTransaction acceptSavingsTransfer(final Long accountId, final LocalDate transferDate,
|
||||
final Office acceptedInOffice, final Staff fieldOfficer, final DepositAccountType depositAccountType) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
@@ -905,7 +924,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final SavingsAccountTransaction acceptTransferTransaction = SavingsAccountTransaction.approveTransfer(savingsAccount,
|
||||
acceptedInOffice, transferDate);
|
||||
acceptedInOffice, transferDate, user);
|
||||
savingsAccount.getTransactions().add(acceptTransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
if (fieldOfficer != null) {
|
||||
@@ -1038,7 +1057,10 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
public CommandProcessingResult waiveCharge(final Long savingsAccountId, final Long savingsAccountChargeId,
|
||||
@SuppressWarnings("unused") final DepositAccountType depositAccountType) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -1055,7 +1077,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
account.waiveCharge(savingsAccountChargeId);
|
||||
account.waiveCharge(savingsAccountChargeId, user);
|
||||
boolean isInterestTransfer = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
|
||||
@@ -1109,7 +1131,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
public CommandProcessingResult payCharge(final Long savingsAccountId, final Long savingsAccountChargeId, final JsonCommand command,
|
||||
@SuppressWarnings("unused") final DepositAccountType depositAccountType) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
this.context.authenticatedUser();
|
||||
|
||||
this.savingsAccountChargeDataValidator.validatePayCharge(command.json());
|
||||
final Locale locale = command.extractLocale();
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
@@ -1168,6 +1191,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
@Transactional
|
||||
private void payCharge(final SavingsAccountCharge savingsAccountCharge, final LocalDate transactionDate, final BigDecimal amountPaid,
|
||||
final DateTimeFormatter formatter) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -1179,7 +1207,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
final Set<Long> existingTransactionIds = new HashSet<>();
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter);
|
||||
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user);
|
||||
boolean isInterestTransfer = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||
|
||||
+55
-13
@@ -195,6 +195,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
public void processPostActiveActions(final SavingsAccount account, final DateTimeFormatter fmt, final Set<Long> existingTransactionIds,
|
||||
final Set<Long> existingReversedTransactionIds) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
@@ -207,7 +212,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
null, isAccountTransfer, isRegularTransaction);
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
}
|
||||
account.processAccountUponActivation(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||
account.processAccountUponActivation(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, user);
|
||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name());
|
||||
}
|
||||
|
||||
@@ -292,12 +297,17 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Override
|
||||
public CommandProcessingResult applyAnnualFee(final Long savingsAccountChargeId, final Long accountId) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, accountId);
|
||||
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy");
|
||||
|
||||
this.payCharge(savingsAccountCharge, savingsAccountCharge.getDueLocalDate(), savingsAccountCharge.amount(), fmt);
|
||||
this.payCharge(savingsAccountCharge, savingsAccountCharge.getDueLocalDate(), savingsAccountCharge.amount(), fmt, user);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(savingsAccountCharge.getId()) //
|
||||
@@ -461,6 +471,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Override
|
||||
public CommandProcessingResult adjustSavingsTransaction(final Long savingsId, final Long transactionId, final JsonCommand command) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
@@ -511,7 +526,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
SavingsAccountTransaction transaction = null;
|
||||
boolean isInterestTransfer = false;
|
||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||
paymentDetail, savingsAccountTransaction.createdDate());
|
||||
paymentDetail, savingsAccountTransaction.createdDate(), user);
|
||||
if (savingsAccountTransaction.isDeposit()) {
|
||||
transaction = account.deposit(transactionDTO);
|
||||
} else {
|
||||
@@ -625,6 +640,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Override
|
||||
public SavingsAccountTransaction initiateSavingsTransfer(final Long accountId, final LocalDate transferDate) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
@@ -636,7 +656,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final SavingsAccountTransaction newTransferTransaction = SavingsAccountTransaction.initiateTransfer(savingsAccount,
|
||||
savingsAccount.office(), transferDate);
|
||||
savingsAccount.office(), transferDate, user);
|
||||
savingsAccount.getTransactions().add(newTransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -655,6 +675,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Override
|
||||
public SavingsAccountTransaction withdrawSavingsTransfer(final Long accountId, final LocalDate transferDate) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
@@ -666,7 +691,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final SavingsAccountTransaction withdrawtransferTransaction = SavingsAccountTransaction.withdrawTransfer(savingsAccount,
|
||||
savingsAccount.office(), transferDate);
|
||||
savingsAccount.office(), transferDate, user);
|
||||
savingsAccount.getTransactions().add(withdrawtransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
@@ -693,6 +718,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
public SavingsAccountTransaction acceptSavingsTransfer(final Long accountId, final LocalDate transferDate,
|
||||
final Office acceptedInOffice, final Staff fieldOfficer) {
|
||||
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
final Integer financialYearBeginningMonth = this.configurationDomainService.retrieveFinancialYearBeginningMonth();
|
||||
@@ -704,7 +734,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
updateExistingTransactionsDetails(savingsAccount, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
final SavingsAccountTransaction acceptTransferTransaction = SavingsAccountTransaction.approveTransfer(savingsAccount,
|
||||
acceptedInOffice, transferDate);
|
||||
acceptedInOffice, transferDate, user);
|
||||
savingsAccount.getTransactions().add(acceptTransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
if (fieldOfficer != null) {
|
||||
@@ -836,7 +866,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Override
|
||||
public CommandProcessingResult waiveCharge(final Long savingsAccountId, final Long savingsAccountChargeId) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -853,7 +886,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
account.waiveCharge(savingsAccountChargeId);
|
||||
account.waiveCharge(savingsAccountChargeId, user);
|
||||
boolean isInterestTransfer = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
if (account.isBeforeLastPostingPeriod(savingsAccountCharge.getDueLocalDate())) {
|
||||
@@ -906,7 +939,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Override
|
||||
public CommandProcessingResult payCharge(final Long savingsAccountId, final Long savingsAccountChargeId, final JsonCommand command) {
|
||||
|
||||
this.context.authenticatedUser();
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
this.savingsAccountChargeDataValidator.validatePayCharge(command.json());
|
||||
final Locale locale = command.extractLocale();
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||
@@ -935,7 +972,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||
}
|
||||
|
||||
this.payCharge(savingsAccountCharge, transactionDate, amountPaid, fmt);
|
||||
this.payCharge(savingsAccountCharge, transactionDate, amountPaid, fmt, user);
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withEntityId(savingsAccountCharge.getId()) //
|
||||
.withOfficeId(savingsAccountCharge.savingsAccount().officeId()) //
|
||||
@@ -950,6 +987,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
@Override
|
||||
public void applyChargeDue(final Long savingsAccountChargeId, final Long accountId) {
|
||||
// always use current date as transaction date for batch job
|
||||
AppUser user = null;
|
||||
if (this.context != null) {
|
||||
user = this.context.authenticatedUser();
|
||||
}
|
||||
|
||||
final LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
||||
final SavingsAccountCharge savingsAccountCharge = this.savingsAccountChargeRepository.findOneWithNotFoundDetection(
|
||||
savingsAccountChargeId, accountId);
|
||||
@@ -957,13 +999,13 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final DateTimeFormatter fmt = DateTimeFormat.forPattern("dd MM yyyy");
|
||||
|
||||
while (transactionDate.isAfter(savingsAccountCharge.getDueLocalDate()) && savingsAccountCharge.isNotFullyPaid()) {
|
||||
payCharge(savingsAccountCharge, transactionDate, savingsAccountCharge.amoutOutstanding(), fmt);
|
||||
payCharge(savingsAccountCharge, transactionDate, savingsAccountCharge.amoutOutstanding(), fmt, user);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
private void payCharge(final SavingsAccountCharge savingsAccountCharge, final LocalDate transactionDate, final BigDecimal amountPaid,
|
||||
final DateTimeFormatter formatter) {
|
||||
final DateTimeFormatter formatter, final AppUser user) {
|
||||
|
||||
final boolean isSavingsInterestPostingAtCurrentPeriodEnd = this.configurationDomainService
|
||||
.isSavingsInterestPostingAtCurrentPeriodEnd();
|
||||
@@ -975,7 +1017,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
final Set<Long> existingTransactionIds = new HashSet<>();
|
||||
final Set<Long> existingReversedTransactionIds = new HashSet<>();
|
||||
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
|
||||
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter);
|
||||
account.payCharge(savingsAccountCharge, amountPaid, transactionDate, formatter, user);
|
||||
boolean isInterestTransfer = false;
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||
|
||||
Reference in New Issue
Block a user