mifosx-746 fixes

This commit is contained in:
andrew-dzak
2013-11-15 11:43:28 +00:00
committed by Keith Woodlock
parent 25bc2f4553
commit b43a9472e3
10 changed files with 252 additions and 69 deletions
@@ -6,7 +6,7 @@ public enum JobName {
"Update Loan Paid In Advance"), APPLY_ANNUAL_FEE_FOR_SAVINGS("Apply Annual Fee For Savings"), APPLY_HOLIDAYS_TO_LOANS(
"Apply Holidays To Loans"), POST_INTEREST_FOR_SAVINGS("Post Interest For Savings"), TRANSFER_FEE_CHARGE_FOR_LOANS(
"Transfer Fee For Loans From Savings"), ACCOUNTING_RUNNING_BALANCE_UPDATE("Update Accounting Running Balances"), PAY_DUE_SAVINGS_CHARGES(
"Pay Due Savings Charges");
"Pay Due Savings Charges"),APPLY_CHARGE_TO_OVERDUE_LOAN_INSTALLMENT("Apply penalty to overdue loans");
private final String name;
@@ -17,7 +17,8 @@ public enum ChargeTimeType {
WITHDRAWAL_FEE(5, "chargeTimeType.withdrawalFee"), // only for savings
ANNUAL_FEE(6, "chargeTimeType.annualFee"), // only for savings
MONTHLY_FEE(7, "chargeTimeType.monthlyFee"), // only for savings
INSTALMENT_FEE(8, "chargeTimeType.instalmentFee");// only for loan charges
INSTALMENT_FEE(8, "chargeTimeType.instalmentFee"),// only for loan charges
OVERDUE_INSTALLMENT(9, "chargeTimeType.overdueInstallment"); // only for loan charges
private final Integer value;
private final String code;
@@ -37,7 +38,7 @@ public enum ChargeTimeType {
public static Object[] validLoanValues() {
return new Integer[] { ChargeTimeType.DISBURSEMENT.getValue(), ChargeTimeType.SPECIFIED_DUE_DATE.getValue(),
ChargeTimeType.INSTALMENT_FEE.getValue() };
ChargeTimeType.INSTALMENT_FEE.getValue(),ChargeTimeType.OVERDUE_INSTALLMENT.getValue() };
}
public static Object[] validSavingsValues() {
@@ -74,6 +75,9 @@ public enum ChargeTimeType {
case 8:
chargeTimeType = INSTALMENT_FEE;
break;
case 9:
chargeTimeType = OVERDUE_INSTALLMENT;
break;
default:
chargeTimeType = INVALID;
break;
@@ -114,8 +118,12 @@ public enum ChargeTimeType {
return this.value.equals(ChargeTimeType.INSTALMENT_FEE.getValue());
}
public boolean isOverdueInstallment(){
return this.value.equals(ChargeTimeType.OVERDUE_INSTALLMENT.getValue());
}
public boolean isAllowedLoanChargeTime() {
return isTimeOfDisbursement() || isOnSpecifiedDueDate() || isInstalmentFee();
return isTimeOfDisbursement() || isOnSpecifiedDueDate() || isInstalmentFee() || isOverdueInstallment();
}
public boolean isAllowedSavingsChargeTime() {
@@ -5,14 +5,6 @@
*/
package org.mifosplatform.portfolio.charge.service;
import static org.mifosplatform.portfolio.charge.service.ChargeEnumerations.chargeCalculationType;
import static org.mifosplatform.portfolio.charge.service.ChargeEnumerations.chargePaymentMode;
import static org.mifosplatform.portfolio.charge.service.ChargeEnumerations.chargeTimeType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.portfolio.charge.domain.ChargeAppliesTo;
import org.mifosplatform.portfolio.charge.domain.ChargeCalculationType;
@@ -20,6 +12,12 @@ import org.mifosplatform.portfolio.charge.domain.ChargePaymentMode;
import org.mifosplatform.portfolio.charge.domain.ChargeTimeType;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.mifosplatform.portfolio.charge.service.ChargeEnumerations.*;
@Service
public class ChargeDropdownReadPlatformServiceImpl implements ChargeDropdownReadPlatformService {
@@ -69,7 +67,7 @@ public class ChargeDropdownReadPlatformServiceImpl implements ChargeDropdownRead
@Override
public List<EnumOptionData> retrieveLoanCollectionTimeTypes() {
return Arrays.asList(chargeTimeType(ChargeTimeType.DISBURSEMENT), chargeTimeType(ChargeTimeType.SPECIFIED_DUE_DATE),chargeTimeType(ChargeTimeType.INSTALMENT_FEE));
return Arrays.asList(chargeTimeType(ChargeTimeType.DISBURSEMENT), chargeTimeType(ChargeTimeType.SPECIFIED_DUE_DATE),chargeTimeType(ChargeTimeType.INSTALMENT_FEE),chargeTimeType(ChargeTimeType.OVERDUE_INSTALLMENT));
}
@Override
@@ -46,6 +46,9 @@ public class ChargeEnumerations {
case INSTALMENT_FEE:
optionData = new EnumOptionData(ChargeTimeType.INSTALMENT_FEE.getValue().longValue(), ChargeTimeType.INSTALMENT_FEE.getCode(), "Instalment Fee");
break;
case OVERDUE_INSTALLMENT:
optionData = new EnumOptionData(ChargeTimeType.OVERDUE_INSTALLMENT.getValue().longValue(),ChargeTimeType.OVERDUE_INSTALLMENT.getCode(),"overdue fees") ;
break;
default:
optionData = new EnumOptionData(ChargeTimeType.INVALID.getValue().longValue(), ChargeTimeType.INVALID.getCode(), "Invalid");
break;
@@ -172,7 +172,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
this.chargeTime = chargeTime.getValue();
}
if (ChargeTimeType.fromInt(this.chargeTime).equals(ChargeTimeType.SPECIFIED_DUE_DATE)) {
if (ChargeTimeType.fromInt(this.chargeTime).equals(ChargeTimeType.SPECIFIED_DUE_DATE) || ChargeTimeType.fromInt(this.chargeTime).equals(ChargeTimeType.OVERDUE_INSTALLMENT) ) {
if (dueDate == null) {
final String defaultUserMessage = "Loan charge is missing due date.";
@@ -0,0 +1,65 @@
package org.mifosplatform.portfolio.loanaccount.loanschedule.data;
import java.math.BigDecimal;
/**
* Created with IntelliJ IDEA.
* User: andrew
* Date: 13-11-13
* Time: 11:53
* To change this template use File | Settings | File Templates.
*/
public class OverdueLoanScheduleData {
private final Long loanId;
private final Long chargeId;
private final String locale;
private final BigDecimal amount;
private final String dateFormat;
private final String dueDate;
public OverdueLoanScheduleData(Long loanId, Long chargeId, String dueDate, BigDecimal amount, String dateFormat, String locale) {
this.loanId = loanId;
this.chargeId = chargeId;
this.dueDate = dueDate;
this.amount = amount;
this.dateFormat = dateFormat;
this.locale = locale;
}
public Long getLoanId() {
return this.loanId;
}
public Long getChargeId() {
return this.chargeId;
}
public String getDueDate() {
return this.dueDate;
}
public BigDecimal getAmount() {
return this.amount;
}
public String getDateFormat() {
return this.dateFormat;
}
public String getLocale() {
return this.locale;
}
@Override
public String toString() {
return "{" +
"chargeId:" + chargeId +
", locale:'" + locale + '\'' +
", amount:" + amount +
", dateFormat:'" + dateFormat + '\'' +
", dueDate:'" + dueDate + '\'' +
'}';
}
}
@@ -5,8 +5,6 @@
*/
package org.mifosplatform.portfolio.loanaccount.service;
import java.util.Collection;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.portfolio.calendar.data.CalendarData;
@@ -15,6 +13,9 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanAccountData;
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData;
import org.mifosplatform.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.OverdueLoanScheduleData;
import java.util.Collection;
public interface LoanReadPlatformService {
@@ -53,4 +54,6 @@ public interface LoanReadPlatformService {
Page<LoanAccountData> retrieveAll(SearchParameters searchParameters);
Collection<StaffData> retrieveAllowedLoanOfficers(Long selectedOfficeId, boolean staffInSelectedOfficeOnly);
Collection<OverdueLoanScheduleData> retrieveAllOverdueLoans();
}
@@ -5,13 +5,6 @@
*/
package org.mifosplatform.portfolio.loanaccount.service;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import org.apache.commons.lang.StringUtils;
import org.joda.time.Days;
import org.joda.time.LocalDate;
@@ -47,23 +40,13 @@ import org.mifosplatform.portfolio.group.data.GroupGeneralData;
import org.mifosplatform.portfolio.group.data.GroupRoleData;
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
import org.mifosplatform.portfolio.group.service.SearchParameters;
import org.mifosplatform.portfolio.loanaccount.data.DisbursementData;
import org.mifosplatform.portfolio.loanaccount.data.LoanAccountData;
import org.mifosplatform.portfolio.loanaccount.data.LoanApplicationTimelineData;
import org.mifosplatform.portfolio.loanaccount.data.LoanStatusEnumData;
import org.mifosplatform.portfolio.loanaccount.data.LoanSummaryData;
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData;
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData;
import org.mifosplatform.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType;
import org.mifosplatform.portfolio.loanaccount.data.*;
import org.mifosplatform.portfolio.loanaccount.domain.*;
import org.mifosplatform.portfolio.loanaccount.exception.LoanNotFoundException;
import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFoundException;
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.OverdueLoanScheduleData;
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData;
import org.mifosplatform.portfolio.loanproduct.service.LoanDropdownReadPlatformService;
@@ -81,6 +64,13 @@ import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@Service
public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
@@ -688,6 +678,39 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
feeChargesDueAtDisbursementCharged, syncDisbursementWithMeeting, loanCounter, loanProductCounter);
}
}
private static final class OverdueLoanSchedule implements RowMapper<OverdueLoanScheduleData>{
public String schema(){
return " ls.loan_id as loanId, ls.installment as period, ls.fromdate as fromDate, ls.duedate as dueDate, ls.obligations_met_on_date as obligationsMetOnDate, ls.completed_derived as complete,"
+ " ls.principal_amount as principalDue, ls.principal_completed_derived as principalPaid, ls.principal_writtenoff_derived as principalWrittenOff, "
+ " ls.interest_amount as interestDue, ls.interest_completed_derived as interestPaid, ls.interest_waived_derived as interestWaived, ls.interest_writtenoff_derived as interestWrittenOff, "
+ " ls.fee_charges_amount as feeChargesDue, ls.fee_charges_completed_derived as feeChargesPaid, ls.fee_charges_waived_derived as feeChargesWaived, ls.fee_charges_writtenoff_derived as feeChargesWrittenOff, "
+ " ls.penalty_charges_amount as penaltyChargesDue, ls.penalty_charges_completed_derived as penaltyChargesPaid, ls.penalty_charges_waived_derived as penaltyChargesWaived, ls.penalty_charges_writtenoff_derived as penaltyChargesWrittenOff, "
+ " ls.total_paid_in_advance_derived as totalPaidInAdvanceForPeriod, ls.total_paid_late_derived as totalPaidLateForPeriod, "
+ " mc.amount,mc.id as chargeId "
+ " from m_loan_repayment_schedule ls "
+ " inner join m_loan ml on ml.id = ls.loan_id "
+ " join m_product_loan_charge plc on plc.product_loan_id = ml.product_id "
+ " join m_charge mc on mc.id = plc.charge_id ";
}
@Override
public OverdueLoanScheduleData mapRow(ResultSet rs, int rowNum) throws SQLException {
final Long chargeId = rs.getLong("chargeId");
final Long loanId = rs.getLong("loanId");
final BigDecimal amount = rs.getBigDecimal("amount");
final String dateFormat = "yyyy-MM-dd";
final String dueDate = rs.getString("dueDate");
final String locale = "en_GB";
OverdueLoanScheduleData overdueLoanScheduleData = new OverdueLoanScheduleData(loanId,chargeId,dueDate,
amount,dateFormat,locale) ;
return overdueLoanScheduleData;
}
}
private static final class LoanScheduleResultSetExtractor implements ResultSetExtractor<LoanScheduleData> {
@@ -1105,4 +1128,14 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
return allowedLoanOfficers;
}
@Override
public Collection<OverdueLoanScheduleData> retrieveAllOverdueLoans() {
final OverdueLoanSchedule rm = new OverdueLoanSchedule();
final String sql = "select " + rm.schema() +
" where CURDATE() > ls.duedate "+
" and ls.completed_derived <> 1 and mc.charge_applies_to_enum =1 "+
" and mc.charge_time_enum = 9 and ml.loan_status_id = 300 "+
" and plc.charge_id not in (SELECT charge_id from m_loan_charge as mlc where mlc.loan_id = ml.id and mlc.charge_id = plc.charge_id and mlc.due_for_collection_as_of_date > fromdate AND mlc.due_for_collection_as_of_date <= duedate) ";
return this.jdbcTemplate.query(sql,rm,new Object[] {});
}
}
@@ -5,9 +5,6 @@
*/
package org.mifosplatform.portfolio.loanaccount.service;
import java.util.Collection;
import java.util.Map;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
@@ -20,6 +17,9 @@ import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkDi
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkRepaymentCommand;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
import java.util.Collection;
import java.util.Map;
public interface LoanWritePlatformService {
CommandProcessingResult disburseLoan(Long loanId, JsonCommand command);
@@ -72,4 +72,8 @@ public interface LoanWritePlatformService {
void transferFeeCharges() throws JobExecutionException;
void applyChargeForOverdueLoans() throws JobExecutionException;
}
@@ -5,17 +5,7 @@
*/
package org.mifosplatform.portfolio.loanaccount.service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import com.google.gson.JsonElement;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
@@ -29,6 +19,7 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
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.jobs.annotation.CronTarget;
import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException;
import org.mifosplatform.infrastructure.jobs.service.JobName;
@@ -58,15 +49,11 @@ import org.mifosplatform.portfolio.calendar.service.CalendarUtils;
import org.mifosplatform.portfolio.charge.domain.Charge;
import org.mifosplatform.portfolio.charge.domain.ChargePaymentMode;
import org.mifosplatform.portfolio.charge.domain.ChargeRepositoryWrapper;
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeDeletedException;
import org.mifosplatform.portfolio.charge.exception.*;
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeDeletedException.LOAN_CHARGE_CANNOT_BE_DELETED_REASON;
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBePayedException;
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBePayedException.LOAN_CHARGE_CANNOT_BE_PAYED_REASON;
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeUpdatedException;
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeUpdatedException.LOAN_CHARGE_CANNOT_BE_UPDATED_REASON;
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException;
import org.mifosplatform.portfolio.charge.exception.LoanChargeCannotBeWaivedException.LOAN_CHARGE_CANNOT_BE_WAIVED_REASON;
import org.mifosplatform.portfolio.charge.exception.LoanChargeNotFoundException;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
import org.mifosplatform.portfolio.collectionsheet.command.CollectionSheetBulkDisbursalCommand;
@@ -78,23 +65,12 @@ import org.mifosplatform.portfolio.group.exception.GroupNotActiveException;
import org.mifosplatform.portfolio.loanaccount.command.LoanUpdateCommand;
import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
import org.mifosplatform.portfolio.loanaccount.data.LoanInstallmentChargeData;
import org.mifosplatform.portfolio.loanaccount.domain.ChangedTransactionDetail;
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
import org.mifosplatform.portfolio.loanaccount.domain.LoanAccountDomainService;
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
import org.mifosplatform.portfolio.loanaccount.domain.LoanInstallmentCharge;
import org.mifosplatform.portfolio.loanaccount.domain.LoanChargeRepository;
import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType;
import org.mifosplatform.portfolio.loanaccount.domain.*;
import org.mifosplatform.portfolio.loanaccount.exception.LoanDisbursalException;
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerAssignmentException;
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerUnassignmentException;
import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFoundException;
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.OverdueLoanScheduleData;
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
import org.mifosplatform.portfolio.loanaccount.serialization.LoanEventApiJsonValidator;
import org.mifosplatform.portfolio.loanaccount.serialization.LoanUpdateCommandFromApiJsonDeserializer;
@@ -109,14 +85,23 @@ import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
import org.mifosplatform.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
import org.mifosplatform.portfolio.savings.exception.InsufficientAccountBalanceException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.*;
@Service
public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatformService {
private final static Logger logger = LoggerFactory.getLogger(LoanWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context;
private final LoanEventApiJsonValidator loanEventApiJsonValidator;
@@ -141,6 +126,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
private final AccountTransfersReadPlatformService accountTransfersReadPlatformService;
private final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService;
private final LoanChargeReadPlatformService LoanChargeReadPlatformService;
private final LoanReadPlatformService loanReadPlatformService;
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -158,7 +146,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final AccountTransfersWritePlatformService accountTransfersWritePlatformService,
final AccountTransfersReadPlatformService accountTransfersReadPlatformService,
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
final LoanChargeReadPlatformService loanChargeReadPlatformService) {
final LoanChargeReadPlatformService loanChargeReadPlatformService,final LoanReadPlatformService loanReadPlatformService,
final FromJsonHelper fromApiJsonHelper ) {
this.context = context;
this.loanEventApiJsonValidator = loanEventApiJsonValidator;
this.loanAssembler = loanAssembler;
@@ -182,6 +171,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.accountTransfersReadPlatformService = accountTransfersReadPlatformService;
this.accountAssociationsReadPlatformService = accountAssociationsReadPlatformService;
this.LoanChargeReadPlatformService = loanChargeReadPlatformService;
this.loanReadPlatformService = loanReadPlatformService;
this.fromApiJsonHelper = fromApiJsonHelper;
}
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
@@ -1607,4 +1598,82 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
}
}
@Override
@CronTarget(jobName = JobName.APPLY_CHARGE_TO_OVERDUE_LOAN_INSTALLMENT)
public void applyChargeForOverdueLoans() throws JobExecutionException {
final Collection<OverdueLoanScheduleData> overdueLoanScheduleData = this.loanReadPlatformService.retrieveAllOverdueLoans();
if(!overdueLoanScheduleData.isEmpty()) {
for(OverdueLoanScheduleData overdueLoanScheduleData1 : overdueLoanScheduleData){
try{
final JsonElement parsedCommand = fromApiJsonHelper.parse(overdueLoanScheduleData1.toString());
final JsonCommand command = JsonCommand.from(overdueLoanScheduleData1.toString(),parsedCommand,this.fromApiJsonHelper,null,null,
null,null,null,overdueLoanScheduleData1.getLoanId(),null,null,null,null,null,null,null);
this.applyChargeToOverdueLoanInstallment(overdueLoanScheduleData1.getLoanId(),overdueLoanScheduleData1.getChargeId(),command);
}catch(final PlatformApiDataValidationException e){
final List<ApiParameterError> errors = e.getErrors();
for (final ApiParameterError error : errors) {
logger.error("Apply Charges due for overdue loans failed for account:" + overdueLoanScheduleData1.getLoanId() + " with message "
+ error.getDeveloperMessage());
}
}
}
}
}
@Transactional
public void applyChargeToOverdueLoanInstallment(Long loanId, Long loanChargeId,JsonCommand command) {
final Loan loan = this.loanAssembler.assembleFrom(loanId);
checkClientOrGroupActive(loan);
final Charge chargeDefinition = this.chargeRepository.findOneWithNotFoundDetection(loanChargeId);
final LoanCharge loanCharge = LoanCharge.createNewFromJson(loan, chargeDefinition, command);
if (!loan.hasCurrencyCodeOf(chargeDefinition.getCurrencyCode())) {
final String errorMessage = "Charge and Loan must have the same currency.";
throw new InvalidCurrencyException("loanCharge", "attach.to.loan", errorMessage);
}
if (loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
final PortfolioAccountData portfolioAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(loanId);
if (portfolioAccountData == null) {
final String errorMessage = loanCharge.name() + "Charge requires linked savings account for payment";
throw new LinkedAccountRequiredException("loanCharge.add", errorMessage, loanCharge.name());
}
}
final List<Long> existingTransactionIds = new ArrayList<Long>();
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
this.loanChargeRepository.save(loanCharge);
final ChangedTransactionDetail changedTransactionDetail = loan.addLoanCharge(loanCharge, existingTransactionIds,
existingReversedTransactionIds);
// we want to apply charge transactions only for those loans charges
// that are applied when a loan is active
if (loan.status().isActive()) {
final LoanTransaction applyLoanChargeTransaction = loan.handleChargeAppliedTransaction(loanCharge, null);
this.loanTransactionRepository.save(applyLoanChargeTransaction);
/***
* TODO Vishwas Batch save is giving me a
* HibernateOptimisticLockingFailureException, looping and saving
* for the time being, not a major issue for now as this loop is
* entered only in edge cases (when a payment is made before the
* latest payment recorded against the loan)
***/
this.loanRepository.saveAndFlush(loan);
if (changedTransactionDetail != null) {
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
this.loanTransactionRepository.save(mapEntry.getValue());
this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue());
}
}
// we post Journal entries only for loans in active status
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
}
}
}