Repository: incubator-fineract
Updated Branches:
  refs/heads/develop 882132739 -> 7fe50160c


http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b9b345a5/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
index f6df4e4..51038d4 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java
@@ -126,5 +126,8 @@ public interface LoanReadPlatformService {
     LoanTransactionData retrieveRefundByCashTemplate(Long loanId);
     
     Collection<InterestRatePeriodData> retrieveLoanInterestRatePeriodData(Long 
loanId);
+
     Collection<Long> retrieveLoanIdsWithPendingIncomePostingTransactions();
+
+    LoanTransactionData retrieveLoanForeclosureTemplate(final Long loanId, 
final LocalDate transactionDate);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b9b345a5/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
index f994d91..7283ca0 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
@@ -93,6 +93,7 @@ import 
org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleIns
 import 
org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanSubStatus;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariationType;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
 import 
org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
@@ -592,6 +593,7 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService {
                     + " l.total_overpaid_derived as totalOverpaid,"
                     + " l.fixed_emi_amount as fixedEmiAmount,"
                     + " l.max_outstanding_loan_balance as 
outstandingLoanBalance,"
+                    + " l.loan_sub_status_id as loanSubStatusId,"
                     + " la.principal_overdue_derived as principalOverdue,"
                     + " la.interest_overdue_derived as interestOverdue,"
                     + " la.fee_charges_overdue_derived as feeChargesOverdue,"
@@ -783,6 +785,12 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService {
             final Integer lifeCycleStatusId = JdbcSupport.getInteger(rs, 
"lifeCycleStatusId");
             final LoanStatusEnumData status = 
LoanEnumerations.status(lifeCycleStatusId);
 
+            final Integer loanSubStatusId = JdbcSupport.getInteger(rs, 
"loanSubStatusId");
+            EnumOptionData loanSubStatus = null;
+            if (loanSubStatusId != null) {
+                loanSubStatus = LoanSubStatus.loanSubStatus(loanSubStatusId);
+            }
+
             // settings
             final LocalDate expectedFirstRepaymentOnDate = 
JdbcSupport.getLocalDate(rs, "expectedFirstRepaymentOnDate");
             final LocalDate interestChargedFromDate = 
JdbcSupport.getLocalDate(rs, "interestChargedFromDate");
@@ -936,7 +944,7 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService {
                     loanProductCounter, multiDisburseLoan, 
canDefineInstallmentAmount, fixedEmiAmount, outstandingLoanBalance, inArrears,
                     graceOnArrearsAgeing, isNPA, daysInMonthType, 
daysInYearType, isInterestRecalculationEnabled,
                     interestRecalculationData, 
createStandingInstructionAtDisbursement, isvariableInstallmentsAllowed, 
minimumGap,
-                    maximumGap);
+                    maximumGap, loanSubStatus);
         }
     }
 
@@ -2028,7 +2036,6 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService {
 
         final LoanTransactionEnumData transactionType = 
LoanEnumerations.transactionType(LoanTransactionType.REFUND_FOR_ACTIVE_LOAN);
         final Collection<PaymentTypeData> paymentOptions = 
this.paymentTypeReadPlatformService.retrieveAllPaymentTypes();
-
         return new LoanTransactionData(null, null, null, transactionType, 
null, currencyData, earliestUnpaidInstallmentDate,
                 retrieveTotalPaidInAdvance(loan.getId()).getPaidInAdvance(), 
null, null, null, null, null, null, paymentOptions, null,
                 null, null, null, false);
@@ -2100,4 +2107,35 @@ public class LoanReadPlatformServiceImpl implements 
LoanReadPlatformService {
             return null;
         }
     }
+
+    @Override
+    public LoanTransactionData retrieveLoanForeclosureTemplate(final Long 
loanId, final LocalDate transactionDate) {
+        this.context.authenticatedUser();
+
+        final Loan loan = this.loanRepository.findOne(loanId);
+        if (loan == null) { throw new LoanNotFoundException(loanId); }
+        loan.validateForForeclosure(transactionDate);
+        final MonetaryCurrency currency = loan.getCurrency();
+        final ApplicationCurrency applicationCurrency = 
this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
+
+        final CurrencyData currencyData = applicationCurrency.toData();
+
+        final LocalDate earliestUnpaidInstallmentDate = 
DateUtils.getLocalDateOfTenant();
+
+        final LoanRepaymentScheduleInstallment 
loanRepaymentScheduleInstallment = 
loan.fetchLoanForeclosureDetail(transactionDate);
+        BigDecimal unrecognizedIncomePortion = null;
+        final LoanTransactionEnumData transactionType = 
LoanEnumerations.transactionType(LoanTransactionType.REPAYMENT);
+        final Collection<PaymentTypeData> paymentTypeOptions = 
this.paymentTypeReadPlatformService.retrieveAllPaymentTypes();
+        final BigDecimal outstandingLoanBalance = 
loanRepaymentScheduleInstallment.getPrincipalOutstanding(currency).getAmount();
+        final Boolean isReversed = false;
+
+        final Money outStandingAmount = 
loanRepaymentScheduleInstallment.getTotalOutstanding(currency);
+
+        return new LoanTransactionData(null, null, null, transactionType, 
null, currencyData, earliestUnpaidInstallmentDate,
+                outStandingAmount.getAmount(), 
loanRepaymentScheduleInstallment.getPrincipalOutstanding(currency).getAmount(),
+                
loanRepaymentScheduleInstallment.getInterestOutstanding(currency).getAmount(), 
loanRepaymentScheduleInstallment
+                        .getFeeChargesOutstanding(currency).getAmount(), 
loanRepaymentScheduleInstallment.getPenaltyChargesOutstanding(
+                        currency).getAmount(), null, 
unrecognizedIncomePortion, paymentTypeOptions, null, null, null,
+                outstandingLoanBalance, isReversed);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b9b345a5/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java
index 9189718..49a52fb 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java
@@ -104,6 +104,8 @@ public interface LoanWritePlatformService {
 
     void recalculateInterest(long loanId);
 
-       CommandProcessingResult undoLastLoanDisbursal(Long loanId, JsonCommand 
command);
+    CommandProcessingResult undoLastLoanDisbursal(Long loanId, JsonCommand 
command);
+
+    CommandProcessingResult forecloseLoan(final Long loanId, JsonCommand 
command);
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b9b345a5/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
index f897c3d..6e35e51 100755
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
@@ -137,6 +137,7 @@ import 
org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleIns
 import 
org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanSubStatus;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanSummaryWrapper;
 import 
org.apache.fineract.portfolio.loanaccount.domain.LoanTrancheDisbursementCharge;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
@@ -145,6 +146,7 @@ import 
org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
 import 
org.apache.fineract.portfolio.loanaccount.exception.ExceedingTrancheCountException;
 import 
org.apache.fineract.portfolio.loanaccount.exception.InvalidPaidInAdvanceAmountException;
 import 
org.apache.fineract.portfolio.loanaccount.exception.LoanDisbursalException;
+import 
org.apache.fineract.portfolio.loanaccount.exception.LoanForeclosureException;
 import 
org.apache.fineract.portfolio.loanaccount.exception.LoanMultiDisbursementException;
 import 
org.apache.fineract.portfolio.loanaccount.exception.LoanOfficerAssignmentException;
 import 
org.apache.fineract.portfolio.loanaccount.exception.LoanOfficerUnassignmentException;
@@ -822,6 +824,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
         this.loanEventApiJsonValidator.validateTransaction(command.json());
 
         final Loan loan = this.loanAssembler.assembleFrom(loanId);
+        if(loan.status().isClosed() && 
loan.getLoanSubStatus().equals(LoanSubStatus.FORECLOSED.getValue())) {
+            final String defaultUserMessage = "The loan cannot reopend as it 
is foreclosed.";
+            throw new 
LoanForeclosureException("loan.cannot.be.reopened.as.it.is.foreclosured", 
defaultUserMessage,
+                    loanId);
+        }
         checkClientOrGroupActive(loan);
         final LoanTransaction transactionToAdjust = 
this.loanTransactionRepository.findOne(transactionId);
         if (transactionToAdjust == null) { throw new 
LoanTransactionNotFoundException(transactionId); }
@@ -2883,6 +2890,33 @@ public class LoanWritePlatformServiceJpaRepositoryImpl 
implements LoanWritePlatf
                 .build();
     }
 
+    @Override
+    @Transactional
+    public CommandProcessingResult forecloseLoan(final Long loanId, final 
JsonCommand command) {
+        final String json = command.json();
+        final JsonElement element = fromApiJsonHelper.parse(json);
+        final Loan loan = this.loanAssembler.assembleFrom(loanId);
+        final LocalDate transactionDate = 
this.fromApiJsonHelper.extractLocalDateNamed(LoanApiConstants.transactionDateParamName,
 element);
+        this.loanEventApiJsonValidator.validateLoanForeclosure(command.json());
+        loan.validateForForeclosure(transactionDate);
+        final Map<String, Object> changes = new LinkedHashMap<>();
+        changes.put("transactionDate", transactionDate);
+
+        String noteText = 
this.fromApiJsonHelper.extractStringNamed(LoanApiConstants.noteParamName, 
element);
+        LoanRescheduleRequest loanRescheduleRequest = null;
+        
this.loanScheduleHistoryWritePlatformService.createAndSaveLoanScheduleArchive(loan.getRepaymentScheduleInstallments(),
+                loan, loanRescheduleRequest);
+        loan.updateInstallmentsPostDate(transactionDate);
+
+        final Map<String, Object> modifications = 
this.loanAccountDomainService.foreCloseLoan(loan, transactionDate, noteText);
+        changes.putAll(modifications);
+
+        final CommandProcessingResultBuilder commandProcessingResultBuilder = 
new CommandProcessingResultBuilder();
+        return commandProcessingResultBuilder.withLoanId(loanId) //
+                .with(changes) //
+                .build();
+    }
+
     private void 
validateIsMultiDisbursalLoanAndDisbursedMoreThanOneTranche(Loan loan) {
         if (!loan.isMultiDisburmentLoan()) {
             final String errorMessage = 
"loan.product.does.not.support.multiple.disbursals.cannot.undo.last.disbursal";

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b9b345a5/fineract-provider/src/main/resources/sql/migrations/core_db/V311__foreclosure_details.sql
----------------------------------------------------------------------
diff --git 
a/fineract-provider/src/main/resources/sql/migrations/core_db/V311__foreclosure_details.sql
 
b/fineract-provider/src/main/resources/sql/migrations/core_db/V311__foreclosure_details.sql
new file mode 100644
index 0000000..63bfc29
--- /dev/null
+++ 
b/fineract-provider/src/main/resources/sql/migrations/core_db/V311__foreclosure_details.sql
@@ -0,0 +1,7 @@
+INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, 
`can_maker_checker`) VALUES 
+('portfolio', 'FORECLOSURE_LOAN', 'LOAN', 'FORECLOSURE', 0), 
+('portfolio', 'FORECLOSURE_LOAN_CHECKER', 'LOAN', 'FORECLOSURE_CHECKER', 0);
+
+
+ALTER TABLE `m_loan`
+       ADD COLUMN `loan_sub_status_id` SMALLINT(5) NULL DEFAULT NULL;
\ No newline at end of file

Reply via email to