diff --git a/mifosng-db/migrations/core_db/V161__added_accrual_batch_job.sql b/mifosng-db/migrations/core_db/V161__added_accrual_batch_job.sql new file mode 100755 index 000000000..70c288067 --- /dev/null +++ b/mifosng-db/migrations/core_db/V161__added_accrual_batch_job.sql @@ -0,0 +1,6 @@ +ALTER TABLE `m_loan_repayment_schedule` + ADD COLUMN `accrual_interest_derived` DECIMAL(19,6) NULL DEFAULT NULL AFTER `interest_waived_derived`, + ADD COLUMN `accrual_fee_charges_derived` DECIMAL(19,6) NULL DEFAULT NULL AFTER `fee_charges_waived_derived`, + ADD COLUMN `accrual_penalty_charges_derived` DECIMAL(19,6) NULL DEFAULT NULL AFTER `penalty_charges_waived_derived`; + +INSERT INTO `job` (`name`, `display_name`, `cron_expression`, `create_time`, `task_priority`, `group_name`, `previous_run_start_time`, `next_run_time`, `job_key`, `initializing_errorlog`, `is_active`, `currently_running`, `updates_allowed`, `scheduler_group`, `is_misfired`) VALUES ('Add Accrual Transactions', 'Add Accrual Transactions', '0 1 0 1/1 * ? *', now(), 5, NULL, NULL, NULL, NULL, NULL, 1, 0, 1, 0, 0); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/jobs/service/JobName.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/jobs/service/JobName.java index acd7eb40c..66e677e2d 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/jobs/service/JobName.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/jobs/service/JobName.java @@ -12,7 +12,8 @@ public enum JobName { ACCOUNTING_RUNNING_BALANCE_UPDATE("Update Accounting Running Balances"), // PAY_DUE_SAVINGS_CHARGES("Pay Due Savings Charges"), // APPLY_CHARGE_TO_OVERDUE_LOAN_INSTALLMENT("Apply penalty to overdue loans"), - EXECUTE_STANDING_INSTRUCTIONS("Execute Standing Instruction"); + EXECUTE_STANDING_INSTRUCTIONS("Execute Standing Instruction"), + ADD_ACCRUAL_ENTRIES("Add Accrual Transactions"); private final String name; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanScheduleAccrualData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanScheduleAccrualData.java new file mode 100755 index 000000000..57e06fdc0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanScheduleAccrualData.java @@ -0,0 +1,94 @@ +package org.mifosplatform.portfolio.loanaccount.data; + +import java.math.BigDecimal; +import java.util.Date; + +import org.joda.time.LocalDate; +import org.mifosplatform.organisation.monetary.data.CurrencyData; + +public class LoanScheduleAccrualData { + + private final Long loanId; + private final Long officeId; + private final LocalDate dueDate; + private final Long repaymentScheduleId; + private final Long loanProductId; + private final BigDecimal interestIncome; + private final BigDecimal feeIncome; + private final BigDecimal penaltyIncome; + private final BigDecimal accruedInterestIncome; + private final BigDecimal accruedFeeIncome; + private final BigDecimal accruedPenaltyIncome; + private final CurrencyData currencyData; + + public LoanScheduleAccrualData(final Long loanId, final Long officeId, final LocalDate dueDate, final Long repaymentScheduleId, + final Long loanProductId, final BigDecimal interestIncome, final BigDecimal feeIncome, final BigDecimal penaltyIncome, + final BigDecimal accruedInterestIncome, final BigDecimal accruedFeeIncome, final BigDecimal accruedPenaltyIncome, + final CurrencyData currencyData) { + this.loanId = loanId; + this.officeId = officeId; + this.dueDate = dueDate; + this.repaymentScheduleId = repaymentScheduleId; + this.loanProductId = loanProductId; + this.interestIncome = interestIncome; + this.feeIncome = feeIncome; + this.penaltyIncome = penaltyIncome; + this.accruedFeeIncome = accruedFeeIncome; + this.accruedInterestIncome = accruedInterestIncome; + this.accruedPenaltyIncome = accruedPenaltyIncome; + this.currencyData = currencyData; + } + + public Long getLoanId() { + return this.loanId; + } + + public Long getOfficeId() { + return this.officeId; + } + + public Date getDueDate() { + return this.dueDate.toDate(); + } + + public LocalDate getDueDateAsLocaldate() { + return this.dueDate; + } + + public Long getRepaymentScheduleId() { + return this.repaymentScheduleId; + } + + public Long getLoanProductId() { + return this.loanProductId; + } + + public BigDecimal getInterestIncome() { + return this.interestIncome; + } + + public BigDecimal getFeeIncome() { + return this.feeIncome; + } + + public BigDecimal getPenaltyIncome() { + return this.penaltyIncome; + } + + public BigDecimal getAccruedInterestIncome() { + return this.accruedInterestIncome; + } + + public BigDecimal getAccruedFeeIncome() { + return this.accruedFeeIncome; + } + + public BigDecimal getAccruedPenaltyIncome() { + return this.accruedPenaltyIncome; + } + + public CurrencyData getCurrencyData() { + return this.currencyData; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransactionType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransactionType.java index f85a56e9c..4213d9150 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransactionType.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransactionType.java @@ -34,7 +34,8 @@ public enum LoanTransactionType { WITHDRAW_TRANSFER(14, "loanTransactionType.withdrawTransfer"), // REJECT_TRANSFER(15, "loanTransactionType.rejectTransfer"), - REFUND(16, "loanTransactionType.refund"), CHARGE_PAYMENT(17, "loanTransactionType.chargePayment"); + REFUND(16, "loanTransactionType.refund"), CHARGE_PAYMENT(17, "loanTransactionType.chargePayment"), + ACCRUAL_ACCOUNTING(17,"loanTransactionType.accrualAccounting"); private final Integer value; private final String code; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAccrualWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAccrualWritePlatformService.java new file mode 100755 index 000000000..a6eb34db2 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAccrualWritePlatformService.java @@ -0,0 +1,10 @@ +package org.mifosplatform.portfolio.loanaccount.service; + +import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException; + + +public interface LoanAccrualWritePlatformService { + + void addAccrualAccounting() throws JobExecutionException; + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java new file mode 100755 index 000000000..98d802cd3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java @@ -0,0 +1,179 @@ +package org.mifosplatform.portfolio.loanaccount.service; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.sql.DataSource; + +import org.mifosplatform.accounting.journalentry.service.JournalEntryWritePlatformService; +import org.mifosplatform.infrastructure.core.service.RoutingDataSource; +import org.mifosplatform.infrastructure.jobs.annotation.CronTarget; +import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException; +import org.mifosplatform.infrastructure.jobs.service.JobName; +import org.mifosplatform.portfolio.loanaccount.data.LoanScheduleAccrualData; +import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData; +import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType; +import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.stereotype.Service; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.support.DefaultTransactionDefinition; + +@Service +public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlatformService { + + private final LoanReadPlatformService loanReadPlatformService; + private final JdbcTemplate jdbcTemplate; + private final DataSource dataSource; + private final JournalEntryWritePlatformService journalEntryWritePlatformService; + private final JpaTransactionManager transactionManager; + + @Autowired + public LoanAccrualWritePlatformServiceImpl(final RoutingDataSource dataSource, final LoanReadPlatformService loanReadPlatformService, + final JournalEntryWritePlatformService journalEntryWritePlatformService, final JpaTransactionManager transactionManager) { + this.loanReadPlatformService = loanReadPlatformService; + this.dataSource = dataSource; + this.jdbcTemplate = new JdbcTemplate(this.dataSource); + this.journalEntryWritePlatformService = journalEntryWritePlatformService; + this.transactionManager = transactionManager; + } + + @Override + @CronTarget(jobName = JobName.ADD_ACCRUAL_ENTRIES) + public void addAccrualAccounting() throws JobExecutionException { + Collection loanScheduleAccrualDatas = this.loanReadPlatformService.retriveScheduleAccrualData(); + StringBuilder sb = new StringBuilder(); + for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) { + try { + addAccrualAccounting(accrualData); + } catch (Exception e) { + Throwable realCause = e; + if (e.getCause() != null) { + realCause = e.getCause(); + } + sb.append("failed to add accural transaction for repayment with id " + accrualData.getRepaymentScheduleId() + + " with message " + realCause.getMessage()); + } + } + + if (sb.length() > 0) { throw new JobExecutionException(sb.toString()); } + } + + @Transactional + public void addAccrualAccounting(LoanScheduleAccrualData scheduleAccrualData) throws Exception { + + String transactionSql = "INSERT INTO m_loan_transaction (loan_id,office_id,is_reversed,transaction_type_enum,transaction_date,amount,interest_portion_derived," + + "fee_charges_portion_derived,penalty_charges_portion_derived) VALUES (?, ?, 0, ?, ?, ?, ?, ?, ?)"; + BigDecimal amount = BigDecimal.ZERO; + BigDecimal interestportion = null; + BigDecimal totalAccInterest = null; + if (scheduleAccrualData.getInterestIncome() != null) { + interestportion = scheduleAccrualData.getInterestIncome(); + totalAccInterest = interestportion; + if (scheduleAccrualData.getAccruedInterestIncome() != null) { + interestportion = interestportion.subtract(scheduleAccrualData.getAccruedInterestIncome()); + } + amount = amount.add(interestportion); + if (interestportion.compareTo(BigDecimal.ZERO) == 0) { + interestportion = null; + } + } + + BigDecimal feeportion = null; + BigDecimal totalAccFee = null; + if (scheduleAccrualData.getFeeIncome() != null) { + feeportion = scheduleAccrualData.getFeeIncome(); + totalAccFee = feeportion; + if (scheduleAccrualData.getAccruedFeeIncome() != null) { + feeportion.subtract(scheduleAccrualData.getAccruedFeeIncome()); + } + amount = amount.add(feeportion); + if (feeportion.compareTo(BigDecimal.ZERO) == 0) { + feeportion = null; + } + } + + BigDecimal penaltyportion = null; + BigDecimal totalAccPenalty = null; + if (scheduleAccrualData.getPenaltyIncome() != null) { + penaltyportion = scheduleAccrualData.getPenaltyIncome(); + totalAccPenalty = penaltyportion; + if (scheduleAccrualData.getAccruedPenaltyIncome() != null) { + penaltyportion.subtract(scheduleAccrualData.getAccruedPenaltyIncome()); + } + amount = amount.add(penaltyportion); + if (penaltyportion.compareTo(BigDecimal.ZERO) == 0) { + penaltyportion = null; + } + } + TransactionStatus transactionStatus = this.transactionManager.getTransaction(new DefaultTransactionDefinition()); + try { + this.jdbcTemplate.update(transactionSql, scheduleAccrualData.getLoanId(), scheduleAccrualData.getOfficeId(), + LoanTransactionType.ACCRUAL_ACCOUNTING.getValue(), scheduleAccrualData.getDueDate(), amount, interestportion, + feeportion, penaltyportion); + final Long transactonId = this.jdbcTemplate.queryForLong("SELECT LAST_INSERT_ID()"); + + Map transactionMap = toMapData(transactonId, amount, interestportion, feeportion, penaltyportion, + scheduleAccrualData); + + String repaymetUpdatesql = "UPDATE m_loan_repayment_schedule SET accrual_interest_derived=?, accrual_fee_charges_derived=?, " + + "accrual_penalty_charges_derived=? WHERE id=?"; + this.jdbcTemplate.update(repaymetUpdatesql, totalAccInterest, totalAccFee, totalAccPenalty, + scheduleAccrualData.getRepaymentScheduleId()); + final Map accountingBridgeData = deriveAccountingBridgeData(scheduleAccrualData, transactionMap); + this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData); + } catch (Exception e) { + this.transactionManager.rollback(transactionStatus); + throw e; + } + this.transactionManager.commit(transactionStatus); + } + + public Map deriveAccountingBridgeData(final LoanScheduleAccrualData loanScheduleAccrualData, + final Map transactionMap) { + + final Map accountingBridgeData = new LinkedHashMap(); + accountingBridgeData.put("loanId", loanScheduleAccrualData.getLoanId()); + accountingBridgeData.put("loanProductId", loanScheduleAccrualData.getLoanProductId()); + accountingBridgeData.put("officeId", loanScheduleAccrualData.getOfficeId()); + accountingBridgeData.put("currency", loanScheduleAccrualData.getCurrencyData()); + accountingBridgeData.put("cashBasedAccountingEnabled", false); + accountingBridgeData.put("accrualBasedAccountingEnabled", true); + + final List> newLoanTransactions = new ArrayList>(); + newLoanTransactions.add(transactionMap); + + accountingBridgeData.put("newLoanTransactions", newLoanTransactions); + return accountingBridgeData; + } + + public Map toMapData(final Long id, final BigDecimal amount, final BigDecimal interestportion, + final BigDecimal feeportion, final BigDecimal penaltyportion, final LoanScheduleAccrualData loanScheduleAccrualData) { + final Map thisTransactionData = new LinkedHashMap(); + + final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.ACCRUAL_ACCOUNTING); + + thisTransactionData.put("id", id); + thisTransactionData.put("officeId", loanScheduleAccrualData.getOfficeId()); + thisTransactionData.put("type", transactionType); + thisTransactionData.put("reversed", false); + thisTransactionData.put("date", loanScheduleAccrualData.getDueDateAsLocaldate()); + thisTransactionData.put("currency", loanScheduleAccrualData.getCurrencyData()); + thisTransactionData.put("amount", amount); + thisTransactionData.put("principalPortion", null); + thisTransactionData.put("interestPortion", interestportion); + thisTransactionData.put("feeChargesPortion", feeportion); + thisTransactionData.put("penaltyChargesPortion", penaltyportion); + thisTransactionData.put("overPaymentPortion", null); + + return thisTransactionData; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java index ce737e09a..34d2dacce 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformService.java @@ -13,6 +13,7 @@ import org.mifosplatform.portfolio.calendar.data.CalendarData; 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.LoanScheduleAccrualData; import org.mifosplatform.portfolio.loanaccount.data.LoanTermVariationsData; import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData; import org.mifosplatform.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData; @@ -77,4 +78,6 @@ public interface LoanReadPlatformService { DisbursementData retrieveLoanDisbursementDetail(Long loanId, Long disbursementId); Collection retrieveLoanTermVariations(Long loanId, Integer termType); + + Collection retriveScheduleAccrualData(); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 4eb85c95e..868ca1716 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -16,6 +16,7 @@ import java.util.List; import org.apache.commons.lang.StringUtils; import org.joda.time.Days; import org.joda.time.LocalDate; +import org.mifosplatform.accounting.common.AccountingRuleType; import org.mifosplatform.infrastructure.codes.data.CodeValueData; import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService; import org.mifosplatform.infrastructure.core.data.EnumOptionData; @@ -53,6 +54,7 @@ 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.LoanScheduleAccrualData; import org.mifosplatform.portfolio.loanaccount.data.LoanStatusEnumData; import org.mifosplatform.portfolio.loanaccount.data.LoanSummaryData; import org.mifosplatform.portfolio.loanaccount.data.LoanTermVariationsData; @@ -62,6 +64,7 @@ import org.mifosplatform.portfolio.loanaccount.data.RepaymentScheduleRelatedLoan import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment; import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository; +import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus; import org.mifosplatform.portfolio.loanaccount.domain.LoanTermVariationType; import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction; import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository; @@ -1305,4 +1308,69 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { } + @Override + public Collection retriveScheduleAccrualData() { + + LoanScheduleAccrualMapper mapper = new LoanScheduleAccrualMapper(); + final StringBuilder sqlBuilder = new StringBuilder(400); + sqlBuilder + .append("select ") + .append(mapper.schema()) + .append(" where ((if(ls.fee_charges_waived_derived is null , ls.fee_charges_amount,(ls.fee_charges_amount-ls.fee_charges_waived_derived)) <> if(ls.accrual_fee_charges_derived is null,0, ls.accrual_fee_charges_derived))") + .append(" or (if(ls.penalty_charges_waived_derived is null , ls.penalty_charges_amount,(ls.penalty_charges_amount-ls.penalty_charges_waived_derived)) <> if(ls.accrual_penalty_charges_derived is null,0,ls.accrual_penalty_charges_derived))") + .append(" or (if(ls.interest_waived_derived is null , ls.interest_amount,(ls.interest_amount-ls.interest_waived_derived)) <> if(ls.accrual_interest_derived is null,0,ls.accrual_interest_derived)))") + .append(" and loan.loan_status_id=? and mpl.accounting_type=?"); + return this.jdbcTemplate.query(sqlBuilder.toString(), mapper, new Object[] { LoanStatus.ACTIVE.getValue(), + AccountingRuleType.ACCRUAL_BASED.getValue() }); + } + + private static final class LoanScheduleAccrualMapper implements RowMapper { + + public String schema() { + final StringBuilder sqlBuilder = new StringBuilder(400); + sqlBuilder + .append("loan.id as loanId ,if(loan.client_id is null,mg.office_id,mc.office_id) as officeId,") + .append("ls.duedate as duedate,ls.id as scheduleId,loan.product_id as productId,") + .append("if(ls.interest_waived_derived is null,ls.interest_amount,(ls.interest_amount-ls.interest_waived_derived)) as interest,") + .append("if(ls.penalty_charges_waived_derived is null , ls.penalty_charges_amount,(ls.penalty_charges_amount-ls.penalty_charges_waived_derived)) as penalty,") + .append("if(ls.fee_charges_waived_derived is null , ls.fee_charges_amount,(ls.fee_charges_amount-ls.fee_charges_waived_derived)) as charges,") + .append("ls.accrual_interest_derived as accinterest,ls.accrual_fee_charges_derived as accfeecharege,ls.accrual_penalty_charges_derived as accpenalty,") + .append(" loan.currency_code as currencyCode,loan.currency_digits as currencyDigits,loan.currency_multiplesof as inMultiplesOf,") + .append("curr.display_symbol as currencyDisplaySymbol,curr.name as currencyName,curr.internationalized_name_code as currencyNameCode") + .append(" from m_loan_repayment_schedule ls ").append(" left join m_loan loan on loan.id=ls.loan_id ") + .append(" left join m_product_loan mpl on mpl.id = loan.product_id") + .append(" left join m_client mc on mc.id = loan.client_id ").append(" left join m_group mg on mg.id = loan.group_id") + .append(" left join m_currency curr on curr.code = loan.currency_code"); + return sqlBuilder.toString(); + } + + @Override + public LoanScheduleAccrualData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + + final Long loanId = rs.getLong("loanId"); + final Long officeId = rs.getLong("officeId"); + final LocalDate dueDate = JdbcSupport.getLocalDate(rs, "duedate"); + final Long repaymentScheduleId = rs.getLong("scheduleId"); + final Long loanProductId = rs.getLong("productId"); + final BigDecimal interestIncome = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "interest"); + final BigDecimal feeIncome = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "charges"); + final BigDecimal penaltyIncome = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "penalty"); + final BigDecimal accruedInterestIncome = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "accinterest"); + final BigDecimal accruedFeeIncome = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "accfeecharege"); + final BigDecimal accruedPenaltyIncome = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "accpenalty"); + + final String currencyCode = rs.getString("currencyCode"); + final String currencyName = rs.getString("currencyName"); + final String currencyNameCode = rs.getString("currencyNameCode"); + final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol"); + final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits"); + final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf"); + final CurrencyData currencyData = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf, + currencyDisplaySymbol, currencyNameCode); + return new LoanScheduleAccrualData(loanId, officeId, dueDate, repaymentScheduleId, loanProductId, interestIncome, feeIncome, + penaltyIncome, accruedInterestIncome, accruedFeeIncome, accruedPenaltyIncome, currencyData); + } + + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanEnumerations.java index 0f501950e..0c738d6be 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/service/LoanEnumerations.java @@ -309,6 +309,10 @@ public class LoanEnumerations { optionData = new LoanTransactionEnumData(LoanTransactionType.CHARGE_PAYMENT.getValue().longValue(), LoanTransactionType.CHARGE_PAYMENT.getCode(), "Charge Payment"); break; + case ACCRUAL_ACCOUNTING: + optionData = new LoanTransactionEnumData(LoanTransactionType.ACCRUAL_ACCOUNTING.getValue().longValue(), + LoanTransactionType.ACCRUAL_ACCOUNTING.getCode(), "Accrual Accounting"); + break; default: break; }