Merge branch 'pull133' into develop

This commit is contained in:
Nazeer Hussain Shaik
2016-06-09 16:30:13 +05:30
8 changed files with 56 additions and 7 deletions
@@ -110,5 +110,7 @@ public interface LoanApiConstants {
public static final String modifiedDueDateParamName = "modifiedDueDate"; public static final String modifiedDueDateParamName = "modifiedDueDate";
public static final String principalParamName = "principal"; public static final String principalParamName = "principal";
public static final String installmentAmountParamName = "installmentAmount"; public static final String installmentAmountParamName = "installmentAmount";
//loan write off
public static final String WRITEOFFREASONS = "WriteOffReasons";
} }
@@ -63,6 +63,8 @@ public class LoanSummaryData {
private final BigDecimal totalOutstanding; private final BigDecimal totalOutstanding;
private final BigDecimal totalOverdue; private final BigDecimal totalOverdue;
private final LocalDate overdueSinceDate; private final LocalDate overdueSinceDate;
private final Long writeoffReasonId;
private final String writeoffReason;
public LoanSummaryData(final CurrencyData currency, final BigDecimal principalDisbursed, final BigDecimal principalPaid, public LoanSummaryData(final CurrencyData currency, final BigDecimal principalDisbursed, final BigDecimal principalPaid,
final BigDecimal principalWrittenOff, final BigDecimal principalOutstanding, final BigDecimal principalOverdue, final BigDecimal principalWrittenOff, final BigDecimal principalOutstanding, final BigDecimal principalOverdue,
@@ -75,7 +77,7 @@ public class LoanSummaryData {
final BigDecimal penaltyChargesOverdue, final BigDecimal totalExpectedRepayment, final BigDecimal totalRepayment, final BigDecimal penaltyChargesOverdue, final BigDecimal totalExpectedRepayment, final BigDecimal totalRepayment,
final BigDecimal totalExpectedCostOfLoan, final BigDecimal totalCostOfLoan, final BigDecimal totalWaived, final BigDecimal totalExpectedCostOfLoan, final BigDecimal totalCostOfLoan, final BigDecimal totalWaived,
final BigDecimal totalWrittenOff, final BigDecimal totalOutstanding, final BigDecimal totalOverdue, final BigDecimal totalWrittenOff, final BigDecimal totalOutstanding, final BigDecimal totalOverdue,
final LocalDate overdueSinceDate) { final LocalDate overdueSinceDate,final Long writeoffReasonId,final String writeoffReason) {
this.currency = currency; this.currency = currency;
this.principalDisbursed = principalDisbursed; this.principalDisbursed = principalDisbursed;
this.principalPaid = principalPaid; this.principalPaid = principalPaid;
@@ -110,6 +112,8 @@ public class LoanSummaryData {
this.totalOutstanding = totalOutstanding; this.totalOutstanding = totalOutstanding;
this.totalOverdue = totalOverdue; this.totalOverdue = totalOverdue;
this.overdueSinceDate = overdueSinceDate; this.overdueSinceDate = overdueSinceDate;
this.writeoffReasonId = writeoffReasonId;
this.writeoffReason = writeoffReason;
} }
public BigDecimal getTotalOutstanding() { public BigDecimal getTotalOutstanding() {
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.loanaccount.data;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Collection; import java.util.Collection;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.portfolio.account.data.AccountTransferData; import org.apache.fineract.portfolio.account.data.AccountTransferData;
import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData; import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData;
@@ -62,6 +63,8 @@ public class LoanTransactionData {
// templates // templates
final Collection<PaymentTypeData> paymentTypeOptions; final Collection<PaymentTypeData> paymentTypeOptions;
private Collection<CodeValueData> writeOffReasonOptions = null;
public static LoanTransactionData templateOnTop(final LoanTransactionData loanTransactionData, public static LoanTransactionData templateOnTop(final LoanTransactionData loanTransactionData,
final Collection<PaymentTypeData> paymentTypeOptions) { final Collection<PaymentTypeData> paymentTypeOptions) {
@@ -224,4 +227,8 @@ public class LoanTransactionData {
public BigDecimal getInterestPortion() { public BigDecimal getInterestPortion() {
return this.interestPortion; return this.interestPortion;
} }
public void setWriteOffReasonOptions(Collection<CodeValueData> writeOffReasonOptions){
this.writeOffReasonOptions =writeOffReasonOptions;
}
} }
@@ -40,6 +40,7 @@ import javax.persistence.CascadeType;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Embedded; import javax.persistence.Embedded;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
@@ -389,6 +390,10 @@ public class Loan extends AbstractPersistable<Long> {
@Column(name = "interest_rate_differential", scale = 6, precision = 19, nullable = true) @Column(name = "interest_rate_differential", scale = 6, precision = 19, nullable = true)
private BigDecimal interestRateDifferential; private BigDecimal interestRateDifferential;
@ManyToOne
@JoinColumn(name = "writeoff_reason_cv_id", nullable = true)
private CodeValue writeOffReason;
public static Loan newIndividualLoanApplication(final String accountNo, final Client client, final Integer loanType, public static Loan newIndividualLoanApplication(final String accountNo, final Client client, final Integer loanType,
final LoanProduct loanProduct, final Fund fund, final Staff officer, final CodeValue loanPurpose, final LoanProduct loanProduct, final Fund fund, final Staff officer, final CodeValue loanPurpose,
@@ -5972,5 +5977,9 @@ public class Loan extends AbstractPersistable<Long> {
} }
return amount; return amount;
} }
public void updateWriteOffReason(CodeValue writeOffReason) {
this.writeOffReason = writeOffReason;
}
} }
@@ -210,7 +210,7 @@ public final class LoanEventApiJsonValidator {
public void validateTransactionWithNoAmount(final String json) { public void validateTransactionWithNoAmount(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Set<String> disbursementParameters = new HashSet<>(Arrays.asList("transactionDate", "note", "locale", "dateFormat")); final Set<String> disbursementParameters = new HashSet<>(Arrays.asList("transactionDate", "note", "locale", "dateFormat","writeoffReasonId"));
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, disbursementParameters); this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, disbursementParameters);
@@ -60,6 +60,7 @@ import org.apache.fineract.portfolio.calendar.service.CalendarReadPlatformServic
import org.apache.fineract.portfolio.charge.data.ChargeData; import org.apache.fineract.portfolio.charge.data.ChargeData;
import org.apache.fineract.portfolio.charge.domain.ChargeTimeType; import org.apache.fineract.portfolio.charge.domain.ChargeTimeType;
import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService; import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService;
import org.apache.fineract.portfolio.client.api.ClientApiConstants;
import org.apache.fineract.portfolio.client.data.ClientData; import org.apache.fineract.portfolio.client.data.ClientData;
import org.apache.fineract.portfolio.client.domain.ClientEnumerations; import org.apache.fineract.portfolio.client.domain.ClientEnumerations;
import org.apache.fineract.portfolio.client.service.ClientReadPlatformService; import org.apache.fineract.portfolio.client.service.ClientReadPlatformService;
@@ -72,6 +73,7 @@ import org.apache.fineract.portfolio.fund.service.FundReadPlatformService;
import org.apache.fineract.portfolio.group.data.GroupGeneralData; import org.apache.fineract.portfolio.group.data.GroupGeneralData;
import org.apache.fineract.portfolio.group.data.GroupRoleData; import org.apache.fineract.portfolio.group.data.GroupRoleData;
import org.apache.fineract.portfolio.group.service.GroupReadPlatformService; import org.apache.fineract.portfolio.group.service.GroupReadPlatformService;
import org.apache.fineract.portfolio.loanaccount.api.LoanApiConstants;
import org.apache.fineract.portfolio.loanaccount.data.DisbursementData; import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData; import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
import org.apache.fineract.portfolio.loanaccount.data.LoanApplicationTimelineData; import org.apache.fineract.portfolio.loanaccount.data.LoanApplicationTimelineData;
@@ -584,6 +586,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
+ " l.total_costofloan_derived as totalCostOfLoan," + " l.total_costofloan_derived as totalCostOfLoan,"
+ " l.total_waived_derived as totalWaived," + " l.total_waived_derived as totalWaived,"
+ " l.total_writtenoff_derived as totalWrittenOff," + " l.total_writtenoff_derived as totalWrittenOff,"
+ " l.writeoff_reason_cv_id as writeoffReasonId,"
+ " codev.code_value as writeoffReason,"
+ " l.total_outstanding_derived as totalOutstanding," + " l.total_outstanding_derived as totalOutstanding,"
+ " l.total_overpaid_derived as totalOverpaid," + " l.total_overpaid_derived as totalOverpaid,"
+ " l.fixed_emi_amount as fixedEmiAmount," + " l.fixed_emi_amount as fixedEmiAmount,"
@@ -629,6 +633,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
+ " left join m_appuser dbu on dbu.id = l.disbursedon_userid" + " left join m_appuser dbu on dbu.id = l.disbursedon_userid"
+ " left join m_appuser cbu on cbu.id = l.closedon_userid" + " left join m_appuser cbu on cbu.id = l.closedon_userid"
+ " left join m_code_value cv on cv.id = l.loanpurpose_cv_id" + " left join m_code_value cv on cv.id = l.loanpurpose_cv_id"
+ " left join m_code_value codev on codev.id = l.writeoff_reason_cv_id"
+ " left join ref_loan_transaction_processing_strategy lps on lps.id = l.loan_transaction_strategy_id" + " left join ref_loan_transaction_processing_strategy lps on lps.id = l.loan_transaction_strategy_id"
+ " left join m_product_loan_variable_installment_config lpvi on lpvi.loan_product_id = l.product_id"; + " left join m_product_loan_variable_installment_config lpvi on lpvi.loan_product_id = l.product_id";
@@ -718,7 +723,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
final String closedByLastname = rs.getString("closedByLastname"); final String closedByLastname = rs.getString("closedByLastname");
final LocalDate writtenOffOnDate = JdbcSupport.getLocalDate(rs, "writtenOffOnDate"); final LocalDate writtenOffOnDate = JdbcSupport.getLocalDate(rs, "writtenOffOnDate");
final Long writeoffReasonId = JdbcSupport.getLong(rs, "writeoffReasonId");
final String writeoffReason = rs.getString("writeoffReason");
final LocalDate expectedMaturityDate = JdbcSupport.getLocalDate(rs, "expectedMaturityDate"); final LocalDate expectedMaturityDate = JdbcSupport.getLocalDate(rs, "expectedMaturityDate");
final Boolean isvariableInstallmentsAllowed = rs.getBoolean("isvariableInstallmentsAllowed"); final Boolean isvariableInstallmentsAllowed = rs.getBoolean("isvariableInstallmentsAllowed");
@@ -837,7 +843,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
feeChargesWaived, feeChargesWrittenOff, feeChargesOutstanding, feeChargesOverdue, penaltyChargesCharged, feeChargesWaived, feeChargesWrittenOff, feeChargesOutstanding, feeChargesOverdue, penaltyChargesCharged,
penaltyChargesPaid, penaltyChargesWaived, penaltyChargesWrittenOff, penaltyChargesOutstanding, penaltyChargesPaid, penaltyChargesWaived, penaltyChargesWrittenOff, penaltyChargesOutstanding,
penaltyChargesOverdue, totalExpectedRepayment, totalRepayment, totalExpectedCostOfLoan, totalCostOfLoan, penaltyChargesOverdue, totalExpectedRepayment, totalRepayment, totalExpectedCostOfLoan, totalCostOfLoan,
totalWaived, totalWrittenOff, totalOutstanding, totalOverdue, overdueSinceDate); totalWaived, totalWrittenOff, totalOutstanding, totalOverdue, overdueSinceDate,writeoffReasonId, writeoffReason);
} }
GroupGeneralData groupData = null; GroupGeneralData groupData = null;
@@ -1788,9 +1794,13 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
final BigDecimal outstandingLoanBalance = null; final BigDecimal outstandingLoanBalance = null;
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.WRITEOFF); final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.WRITEOFF);
final BigDecimal unrecognizedIncomePortion = null; final BigDecimal unrecognizedIncomePortion = null;
return new LoanTransactionData(null, null, null, transactionType, null, loan.currency(), DateUtils.getLocalDateOfTenant(), final List<CodeValueData> writeOffReasonOptions = new ArrayList<>(
this.codeValueReadPlatformService.retrieveCodeValuesByCode(LoanApiConstants.WRITEOFFREASONS));
LoanTransactionData loanTransactionData = new LoanTransactionData(null, null, null, transactionType, null, loan.currency(), DateUtils.getLocalDateOfTenant(),
loan.getTotalOutstandingAmount(), null, null, null, null, null, null, null, null, outstandingLoanBalance, loan.getTotalOutstandingAmount(), null, null, null, null, null, null, null, null, outstandingLoanBalance,
unrecognizedIncomePortion, false); unrecognizedIncomePortion, false);
loanTransactionData.setWriteOffReasonOptions(writeOffReasonOptions);
return loanTransactionData;
} }
@Override @Override
@@ -33,6 +33,9 @@ import java.util.Set;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService; import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
import org.apache.fineract.infrastructure.codes.domain.CodeValueRepositoryWrapper;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError; import org.apache.fineract.infrastructure.core.data.ApiParameterError;
@@ -225,6 +228,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
private final LoanUtilService loanUtilService; private final LoanUtilService loanUtilService;
private final LoanSummaryWrapper loanSummaryWrapper; private final LoanSummaryWrapper loanSummaryWrapper;
private final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessingStrategy; private final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessingStrategy;
private final CodeValueRepositoryWrapper codeValueRepository;
@Autowired @Autowired
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -252,7 +256,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final AccountTransferDetailRepository accountTransferDetailRepository, final AccountTransferDetailRepository accountTransferDetailRepository,
final BusinessEventNotifierService businessEventNotifierService, final GuarantorDomainService guarantorDomainService, final BusinessEventNotifierService businessEventNotifierService, final GuarantorDomainService guarantorDomainService,
final LoanUtilService loanUtilService, final LoanSummaryWrapper loanSummaryWrapper, final LoanUtilService loanUtilService, final LoanSummaryWrapper loanSummaryWrapper,
final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessingStrategy) { final LoanRepaymentScheduleTransactionProcessorFactory transactionProcessingStrategy,
final CodeValueRepositoryWrapper codeValueRepository) {
this.context = context; this.context = context;
this.loanEventApiJsonValidator = loanEventApiJsonValidator; this.loanEventApiJsonValidator = loanEventApiJsonValidator;
this.loanAssembler = loanAssembler; this.loanAssembler = loanAssembler;
@@ -289,6 +294,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.loanUtilService = loanUtilService; this.loanUtilService = loanUtilService;
this.loanSummaryWrapper = loanSummaryWrapper; this.loanSummaryWrapper = loanSummaryWrapper;
this.transactionProcessingStrategy = transactionProcessingStrategy; this.transactionProcessingStrategy = transactionProcessingStrategy;
this.codeValueRepository = codeValueRepository;
} }
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() { private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
@@ -1043,8 +1049,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate")); changes.put("transactionDate", command.stringValueOfParameterNamed("transactionDate"));
changes.put("locale", command.locale()); changes.put("locale", command.locale());
changes.put("dateFormat", command.dateFormat()); changes.put("dateFormat", command.dateFormat());
final Loan loan = this.loanAssembler.assembleFrom(loanId); final Loan loan = this.loanAssembler.assembleFrom(loanId);
if(command.hasParameter("writeoffReasonId")){
Long writeoffReasonId = command.longValueOfParameterNamed("writeoffReasonId");
CodeValue writeoffReason = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection(LoanApiConstants.WRITEOFFREASONS, writeoffReasonId);
changes.put("writeoffReasonId", writeoffReasonId);
loan.updateWriteOffReason(writeoffReason);
}
checkClientOrGroupActive(loan); checkClientOrGroupActive(loan);
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_WRITTEN_OFF, this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_WRITTEN_OFF,
constructEntityMap(BUSINESS_ENTITY.LOAN, loan)); constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
@@ -0,0 +1,5 @@
INSERT INTO `m_code` (`code_name`, `is_system_defined`) VALUES ('WriteOffReasons', 1);
ALTER TABLE `m_loan`
add column `writeoff_reason_cv_id` INT(11) NULL DEFAULT NULL,
add CONSTRAINT `FK_writeoffreason_m_loan_m_code_value` FOREIGN KEY (`writeoff_reason_cv_id`) REFERENCES `m_code_value` (`id`);