Fixes integration tests

FINERACT-1557: Fixes for integration tests

FINERACT-1557: Fixes for integration tests

Fixes integration tests
This commit is contained in:
Jose Hernandez
2022-04-14 00:37:55 +02:00
committed by Aleksandar Vidakovic
parent eb11c32ee3
commit 3d3e8c4083
34 changed files with 425 additions and 157 deletions
@@ -131,7 +131,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
+ "group by t2.account_id desc) t1)"; + "group by t2.account_id desc) t1)";
} }
} }
final Object[] paramaterArray = new Object[3]; final Object[] parameterArray = new Object[3];
int arrayPos = 0; int arrayPos = 0;
boolean filtersPresent = false; boolean filtersPresent = false;
if ((accountClassification != null) || StringUtils.isNotBlank(searchParam) || (usage != null) || (manualTransactionsAllowed != null) if ((accountClassification != null) || StringUtils.isNotBlank(searchParam) || (usage != null) || (manualTransactionsAllowed != null)
@@ -143,8 +143,8 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
if (filtersPresent) { if (filtersPresent) {
boolean firstWhereConditionAdded = false; boolean firstWhereConditionAdded = false;
if (accountClassification != null) { if (accountClassification != null) {
sql += " classification_enum like ?"; sql += " classification_enum = ?";
paramaterArray[arrayPos] = accountClassification; parameterArray[arrayPos] = accountClassification.shortValue();
arrayPos = arrayPos + 1; arrayPos = arrayPos + 1;
firstWhereConditionAdded = true; firstWhereConditionAdded = true;
} }
@@ -153,9 +153,9 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
sql += " and "; sql += " and ";
} }
sql += " ( name like %?% or gl_code like %?% )"; sql += " ( name like %?% or gl_code like %?% )";
paramaterArray[arrayPos] = searchParam; parameterArray[arrayPos] = searchParam;
arrayPos = arrayPos + 1; arrayPos = arrayPos + 1;
paramaterArray[arrayPos] = searchParam; parameterArray[arrayPos] = searchParam;
arrayPos = arrayPos + 1; arrayPos = arrayPos + 1;
firstWhereConditionAdded = true; firstWhereConditionAdded = true;
} }
@@ -175,11 +175,7 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
sql += " and "; sql += " and ";
} }
if (manualTransactionsAllowed) { sql += " manual_journal_entries_allowed = " + manualTransactionsAllowed;
sql += " manual_journal_entries_allowed = 1";
} else {
sql += " manual_journal_entries_allowed = 0";
}
firstWhereConditionAdded = true; firstWhereConditionAdded = true;
} }
if (disabled != null) { if (disabled != null) {
@@ -187,18 +183,14 @@ public class GLAccountReadPlatformServiceImpl implements GLAccountReadPlatformSe
sql += " and "; sql += " and ";
} }
if (disabled) { sql += " disabled = " + disabled;
sql += " disabled = 1";
} else {
sql += " disabled = 0";
}
firstWhereConditionAdded = true; firstWhereConditionAdded = true;
} }
} }
sql += " ORDER BY gl_code ASC"; sql += " ORDER BY gl_code ASC";
final Object[] finalObjectArray = Arrays.copyOf(paramaterArray, arrayPos); final Object[] finalObjectArray = Arrays.copyOf(parameterArray, arrayPos);
return this.jdbcTemplate.query(sql, rm, finalObjectArray); // NOSONAR return this.jdbcTemplate.query(sql, rm, finalObjectArray); // NOSONAR
} }
@@ -27,6 +27,7 @@ import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.TimeZone; import java.util.TimeZone;
@@ -40,6 +41,10 @@ public final class DateUtils {
} }
public static ZoneId getSystemZoneId() {
return ZoneId.systemDefault();
}
public static ZoneId getDateTimeZoneOfTenant() { public static ZoneId getDateTimeZoneOfTenant() {
final FineractPlatformTenant tenant = ThreadLocalContextUtil.getTenant(); final FineractPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
ZoneId zone = ZoneId.systemDefault(); ZoneId zone = ZoneId.systemDefault();
@@ -59,13 +64,28 @@ public final class DateUtils {
} }
public static Date getDateOfTenant() { public static Date getDateOfTenant() {
return Date.from(getLocalDateOfTenant().atStartOfDay(getDateTimeZoneOfTenant()).toInstant()); return convertLocalDateToDate(getLocalDateOfTenant());
}
public static Date convertLocalDateToDate(LocalDate localDate) {
return createDate(localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth());
}
public static Date createDate(int year, int month, int day) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month - 1);
cal.set(Calendar.DAY_OF_MONTH, day);
return cal.getTime();
} }
public static LocalDate getLocalDateOfTenant() { public static LocalDate getLocalDateOfTenant() {
final ZoneId zone = getDateTimeZoneOfTenant(); final ZoneId zone = getDateTimeZoneOfTenant();
LocalDate today = LocalDate.now(zone); return LocalDate.now(zone);
return today; }
public static LocalDate getLocalDateOfTenant(final ZoneId zone) {
return LocalDate.now(zone);
} }
public static LocalDateTime getLocalDateTimeOfTenant() { public static LocalDateTime getLocalDateTimeOfTenant() {
@@ -97,6 +97,16 @@ public class DatabaseSpecificSQLGenerator {
} }
} }
public String currentDateTime() {
if (databaseTypeResolver.isMySQL()) {
return "CURRENT_TIMESTAMP()";
} else if (databaseTypeResolver.isPostgreSQL()) {
return "CURRENT_TIMESTAMP";
} else {
throw new IllegalStateException("Database type is not supported for current date " + databaseTypeResolver.databaseType());
}
}
public String subDate(String date, String multiplier, String unit) { public String subDate(String date, String multiplier, String unit) {
if (databaseTypeResolver.isMySQL()) { if (databaseTypeResolver.isMySQL()) {
return format("DATE_SUB(%s, INTERVAL %s %s)", date, multiplier, unit); return format("DATE_SUB(%s, INTERVAL %s %s)", date, multiplier, unit);
@@ -34,4 +34,25 @@ public final class DataTableApiConstant {
public static final String localParamName = "locale"; public static final String localParamName = "locale";
public static final String DATATABLE_RESOURCE_NAME = "dataTables"; public static final String DATATABLE_RESOURCE_NAME = "dataTables";
public static final String CREATEDAT_FIELD_NAME = "created_at";
public static final String UPDATEDAT_FIELD_NAME = "updated_at";
// Field Types
public static final String DATETIME_FIELD_TYPE = "DateTime";
// associationParameters
public static final String allAssociateParamName = "all";
public static final String repaymentScheduleAssociateParamName = "repaymentSchedule";
public static final String originalScheduleAssociateParamName = "originalSchedule";
public static final String transactionsAssociateParamName = "transactions";
public static final String chargesAssociateParamName = "charges";
public static final String guarantorsAssociateParamName = "guarantors";
public static final String collateralAssociateParamName = "collateral";
public static final String notesAssociateParamName = "notes";
public static final String linkedAccountAssociateParamName = "linkedAccount";
public static final String multiDisburseDetailsAssociateParamName = "multiDisburseDetails";
public static final String futureScheduleAssociateParamName = "futureSchedule";
public static final String meetingAssociateParamName = "meeting";
public static final String emiAmountVariationsAssociateParamName = "emiAmountVariations";
public static final String collectionAssociateParamName = "collection";
} }
@@ -329,6 +329,17 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return category.equals(DataTableApiConstant.CATEGORY_PPI); return category.equals(DataTableApiConstant.CATEGORY_PPI);
} }
private JsonElement addColumn(final String name, final String dataType, final boolean isMandatory, final Integer length) {
JsonObject column = new JsonObject();
column.addProperty("name", name);
column.addProperty("type", dataType);
if (dataType.equalsIgnoreCase("string")) {
column.addProperty("length", length);
}
column.addProperty("mandatory", (isMandatory ? "true" : "false"));
return column;
}
@Override @Override
public String getDataTableName(String url) { public String getDataTableName(String url) {
@@ -491,7 +502,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
private void assertDataTableExists(final String datatableName) { private void assertDataTableExists(final String datatableName) {
final String sql = "select (CASE WHEN exists (select 1 from information_schema.tables where table_schema = " final String sql = "select (CASE WHEN exists (select 1 from information_schema.tables where table_schema = "
+ sqlGenerator.currentSchema() + " and table_name = ?) THEN 'true' ELSE 'false' END)"; + sqlGenerator.currentSchema() + " and table_name = ?) THEN 'true' ELSE 'false' END)";
final String dataTableExistsString = this.jdbcTemplate.queryForObject(sql, String.class, new Object[] { datatableName }); // NOSONAR final String dataTableExistsString = this.jdbcTemplate.queryForObject(sql, String.class, new Object[] { datatableName });
final boolean dataTableExists = Boolean.valueOf(dataTableExistsString); final boolean dataTableExists = Boolean.valueOf(dataTableExistsString);
if (!dataTableExists) { if (!dataTableExists) {
throw new PlatformDataIntegrityException("error.msg.invalid.datatable", "Invalid Data Table: " + datatableName, "name", throw new PlatformDataIntegrityException("error.msg.invalid.datatable", "Invalid Data Table: " + datatableName, "name",
@@ -559,7 +570,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
} else if (type.equalsIgnoreCase("Decimal")) { } else if (type.equalsIgnoreCase("Decimal")) {
sqlBuilder = sqlBuilder.append("(19,6)"); sqlBuilder = sqlBuilder.append("(19,6)");
} else if (type.equalsIgnoreCase("Dropdown")) { } else if (type.equalsIgnoreCase("Dropdown")) {
sqlBuilder = sqlBuilder.append("(11)"); if (databaseTypeResolver.isMySQL()) {
sqlBuilder = sqlBuilder.append("(11)");
}
} }
} }
@@ -613,12 +626,20 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
sqlBuilder = sqlBuilder.append("CREATE TABLE " + sqlGenerator.escape(datatableName) + " ("); sqlBuilder = sqlBuilder.append("CREATE TABLE " + sqlGenerator.escape(datatableName) + " (");
if (multiRow) { if (multiRow) {
sqlBuilder = sqlBuilder.append("id BIGINT NOT NULL AUTO_INCREMENT, ") if (databaseTypeResolver.isMySQL()) {
.append(sqlGenerator.escape(fkColumnName) + " BIGINT NOT NULL, "); sqlBuilder = sqlBuilder.append("id BIGINT NOT NULL AUTO_INCREMENT, ");
} else { } else if (databaseTypeResolver.isPostgreSQL()) {
sqlBuilder = sqlBuilder.append(sqlGenerator.escape(fkColumnName) + " BIGINT NOT NULL, "); sqlBuilder = sqlBuilder.append(
"id bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 ), ");
} else {
throw new IllegalStateException("Current database is not supported");
}
} }
sqlBuilder = sqlBuilder.append(sqlGenerator.escape(fkColumnName) + " BIGINT NOT NULL, ");
// Add Created At and Updated At
columns.add(addColumn(DataTableApiConstant.CREATEDAT_FIELD_NAME, DataTableApiConstant.DATETIME_FIELD_TYPE, false, null));
columns.add(addColumn(DataTableApiConstant.UPDATEDAT_FIELD_NAME, DataTableApiConstant.DATETIME_FIELD_TYPE, false, null));
for (final JsonElement column : columns) { for (final JsonElement column : columns) {
parseDatatableColumnObjectForCreate(column.getAsJsonObject(), sqlBuilder, constrainBuilder, dataTableNameAlias, parseDatatableColumnObjectForCreate(column.getAsJsonObject(), sqlBuilder, constrainBuilder, dataTableNameAlias,
codeMappings, isConstraintApproach); codeMappings, isConstraintApproach);
@@ -629,10 +650,12 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
String fullFkName = "fk_" + fkName; String fullFkName = "fk_" + fkName;
if (multiRow) { if (multiRow) {
sqlBuilder = sqlBuilder.append(", PRIMARY KEY (id)") sqlBuilder = sqlBuilder.append(", PRIMARY KEY (id)");
.append(", KEY " + sqlGenerator.escape("fk_" + apptableName.substring(2) + "_id") + " (" if (databaseTypeResolver.isMySQL()) {
+ sqlGenerator.escape(fkColumnName) + ")") sqlBuilder = sqlBuilder.append(", KEY " + sqlGenerator.escape("fk_" + apptableName.substring(2) + "_id") + " ("
.append(", CONSTRAINT " + sqlGenerator.escape(fullFkName) + " ") + sqlGenerator.escape(fkColumnName) + ")");
}
sqlBuilder = sqlBuilder.append(", CONSTRAINT " + sqlGenerator.escape(fullFkName) + " ")
.append("FOREIGN KEY (" + sqlGenerator.escape(fkColumnName) + ") ") .append("FOREIGN KEY (" + sqlGenerator.escape(fkColumnName) + ") ")
.append("REFERENCES " + sqlGenerator.escape(actualAppTableName) + " (id)"); .append("REFERENCES " + sqlGenerator.escape(actualAppTableName) + " (id)");
} else { } else {
@@ -647,6 +670,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
if (databaseTypeResolver.isMySQL()) { if (databaseTypeResolver.isMySQL()) {
sqlBuilder.append(" ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4;"); sqlBuilder.append(" ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4;");
} }
LOG.debug("SQL:: {}", sqlBuilder.toString());
this.jdbcTemplate.execute(sqlBuilder.toString()); this.jdbcTemplate.execute(sqlBuilder.toString());
registerDatatable(datatableName, apptableName, entitySubType); registerDatatable(datatableName, apptableName, entitySubType);
@@ -938,9 +963,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
final boolean isConstraintApproach = this.configurationDomainService.isConstraintApproachEnabledForDatatables(); final boolean isConstraintApproach = this.configurationDomainService.isConstraintApproachEnabledForDatatables();
if (!StringUtils.isBlank(entitySubType)) { if (!StringUtils.isBlank(entitySubType)) {
final String updateLegalFormSQL = "update x_registered_table SET entity_subtype='" + entitySubType String updateLegalFormSQL = "update x_registered_table SET entity_subtype='" + entitySubType
+ "' WHERE registered_table_name = '" + datatableName + "'"; + "' WHERE registered_table_name = '" + datatableName + "'";
this.jdbcTemplate.execute(updateLegalFormSQL); // NOSONAR this.jdbcTemplate.execute(updateLegalFormSQL);
} }
if (!StringUtils.isBlank(apptableName)) { if (!StringUtils.isBlank(apptableName)) {
@@ -1154,7 +1179,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
private int getRowCount(final String datatableName) { private int getRowCount(final String datatableName) {
final String sql = "select count(*) from " + sqlGenerator.escape(datatableName); final String sql = "select count(*) from " + sqlGenerator.escape(datatableName);
return this.jdbcTemplate.queryForObject(sql, Integer.class); // NOSONAR return this.jdbcTemplate.queryForObject(sql, Integer.class);
} }
@Transactional @Transactional
@@ -1476,7 +1501,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
SQLInjectionValidator.validateSQLInput(datatable); SQLInjectionValidator.validateSQLInput(datatable);
final String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = ?"; final String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = ?";
String applicationTableName; String applicationTableName = "";
final SqlRowSet rowSet = jdbcTemplate.queryForRowSet(sql, new Object[] { datatable }); // NOSONAR final SqlRowSet rowSet = jdbcTemplate.queryForRowSet(sql, new Object[] { datatable }); // NOSONAR
if (rowSet.next()) { if (rowSet.next()) {
@@ -1524,6 +1549,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
columnName = sqlGenerator.escape(key); columnName = sqlGenerator.escape(key);
insertColumns += ", " + columnName; insertColumns += ", " + columnName;
selectColumns += "," + pValueWrite + " as " + columnName; selectColumns += "," + pValueWrite + " as " + columnName;
} else {
if (key.equalsIgnoreCase(DataTableApiConstant.CREATEDAT_FIELD_NAME)
|| key.equalsIgnoreCase(DataTableApiConstant.UPDATEDAT_FIELD_NAME)) {
columnName = sqlGenerator.escape(key);
insertColumns += ", " + columnName;
selectColumns += "," + sqlGenerator.currentDateTime() + " as " + columnName;
}
} }
} }
@@ -1626,6 +1658,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
} }
} }
sql += sqlGenerator.escape(key) + " = " + pValueWrite; sql += sqlGenerator.escape(key) + " = " + pValueWrite;
} else {
if (key.equalsIgnoreCase(DataTableApiConstant.UPDATEDAT_FIELD_NAME)) {
sql += ", " + sqlGenerator.escape(key) + " = " + sqlGenerator.currentDateTime();
}
} }
} }
@@ -1879,8 +1915,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
public Long countDatatableEntries(final String datatableName, final Long appTableId, String foreignKeyColumn) { public Long countDatatableEntries(final String datatableName, final Long appTableId, String foreignKeyColumn) {
final String sqlString = "SELECT COUNT(" + sqlGenerator.escape(foreignKeyColumn) + ") FROM " + sqlGenerator.escape(datatableName) final String sqlString = "SELECT COUNT(" + sqlGenerator.escape(foreignKeyColumn) + ") FROM " + sqlGenerator.escape(datatableName)
+ " WHERE " + sqlGenerator.escape(foreignKeyColumn) + "=?"; + " WHERE " + sqlGenerator.escape(foreignKeyColumn) + "=" + appTableId;
final Long count = this.jdbcTemplate.queryForObject(sqlString, Long.class, new Object[] { appTableId }); // NOSONAR final Long count = this.jdbcTemplate.queryForObject(sqlString, Long.class);
return count; return count;
} }
@@ -160,7 +160,7 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService {
public Collection<StaffData> retrieveAllLoanOfficersInOfficeById(final Long officeId) { public Collection<StaffData> retrieveAllLoanOfficersInOfficeById(final Long officeId) {
SQLBuilder extraCriteria = new SQLBuilder(); SQLBuilder extraCriteria = new SQLBuilder();
extraCriteria.addCriteria(" office_id = ", officeId); extraCriteria.addCriteria(" office_id = ", officeId);
extraCriteria.addCriteria(" is_loan_officer = ", 1); extraCriteria.addCriteria(" is_loan_officer = ", true);
return retrieveAllStaff(extraCriteria); return retrieveAllStaff(extraCriteria);
} }
@@ -73,6 +73,10 @@ public class PortfolioAccountDTO {
return this.accountStatus; return this.accountStatus;
} }
public long getFirstAccountStatus() {
return this.accountStatus[0];
}
public Integer getDepositType() { public Integer getDepositType() {
return this.depositType; return this.depositType;
} }
@@ -105,12 +105,9 @@ public class PortfolioAccountReadPlatformServiceImpl implements PortfolioAccount
// sqlParams.add(portfolioAccountDTO.getClientId()); // sqlParams.add(portfolioAccountDTO.getClientId());
Collection<PortfolioAccountData> accounts = null; Collection<PortfolioAccountData> accounts = null;
String sql = null; String sql = null;
String defaultAccountStatus = "300"; long defaultAccountStatus = 300; // Active Status
if (portfolioAccountDTO.getAccountStatus() != null) { if (portfolioAccountDTO.getAccountStatus() != null) {
for (final long status : portfolioAccountDTO.getAccountStatus()) { defaultAccountStatus = portfolioAccountDTO.getFirstAccountStatus();
defaultAccountStatus += ", " + status;
}
defaultAccountStatus = defaultAccountStatus.substring(defaultAccountStatus.indexOf(",") + 1);
} }
final PortfolioAccountType accountType = PortfolioAccountType.fromInt(portfolioAccountDTO.getAccountTypeId()); final PortfolioAccountType accountType = PortfolioAccountType.fromInt(portfolioAccountDTO.getAccountTypeId());
switch (accountType) { switch (accountType) {
@@ -150,11 +147,11 @@ public class PortfolioAccountReadPlatformServiceImpl implements PortfolioAccount
if (portfolioAccountDTO.getDepositType() != null) { if (portfolioAccountDTO.getDepositType() != null) {
sql += " and sa.deposit_type_enum = ?"; sql += " and sa.deposit_type_enum = ?";
sqlParams.add(portfolioAccountDTO.getDepositType()); sqlParams.add(portfolioAccountDTO.getDepositType().shortValue());
} }
if (portfolioAccountDTO.isExcludeOverDraftAccounts()) { if (portfolioAccountDTO.isExcludeOverDraftAccounts()) {
sql += " and sa.allow_overdraft = 0"; sql += " and sa.allow_overdraft = false";
} }
if (portfolioAccountDTO.getClientId() == null && portfolioAccountDTO.getGroupId() != null) { if (portfolioAccountDTO.getClientId() == null && portfolioAccountDTO.getGroupId() != null) {
@@ -74,6 +74,7 @@ import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSer
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.core.service.Page; import org.apache.fineract.infrastructure.core.service.Page;
import org.apache.fineract.infrastructure.core.service.SearchParameters; import org.apache.fineract.infrastructure.core.service.SearchParameters;
import org.apache.fineract.infrastructure.dataqueries.api.DataTableApiConstant;
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData; import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables; import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum; import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
@@ -104,6 +105,7 @@ import org.apache.fineract.portfolio.fund.data.FundData;
import org.apache.fineract.portfolio.fund.service.FundReadPlatformService; 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.service.GroupReadPlatformService; import org.apache.fineract.portfolio.group.service.GroupReadPlatformService;
import org.apache.fineract.portfolio.loanaccount.data.CollectionData;
import org.apache.fineract.portfolio.loanaccount.data.DisbursementData; import org.apache.fineract.portfolio.loanaccount.data.DisbursementData;
import org.apache.fineract.portfolio.loanaccount.data.GlimRepaymentTemplate; import org.apache.fineract.portfolio.loanaccount.data.GlimRepaymentTemplate;
import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData; import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
@@ -494,7 +496,6 @@ public class LoansApiResource {
public String retrieveLoan(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId, public String retrieveLoan(@PathParam("loanId") @Parameter(description = "loanId") final Long loanId,
@DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") @Parameter(description = "staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly, @DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") @Parameter(description = "staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly,
@Context final UriInfo uriInfo) { @Context final UriInfo uriInfo) {
long start = System.currentTimeMillis();
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions); this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
LoanAccountData loanBasicDetails = this.loanReadPlatformService.retrieveOne(loanId); LoanAccountData loanBasicDetails = this.loanReadPlatformService.retrieveOne(loanId);
@@ -542,75 +543,83 @@ public class LoansApiResource {
Collection<LoanTermVariationsData> emiAmountVariations = null; Collection<LoanTermVariationsData> emiAmountVariations = null;
Collection<LoanCollateralResponseData> loanCollateralManagements = null; Collection<LoanCollateralResponseData> loanCollateralManagements = null;
Collection<LoanCollateralManagementData> loanCollateralManagementData = new ArrayList<>(); Collection<LoanCollateralManagementData> loanCollateralManagementData = new ArrayList<>();
CollectionData collectionData = CollectionData.template();
final Set<String> mandatoryResponseParameters = new HashSet<>(); final Set<String> mandatoryResponseParameters = new HashSet<>();
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters()); final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
if (!associationParameters.isEmpty()) { if (!associationParameters.isEmpty()) {
if (associationParameters.contains("all")) { if (associationParameters.contains(DataTableApiConstant.allAssociateParamName)) {
associationParameters.addAll(Arrays.asList("repaymentSchedule", "futureSchedule", "originalSchedule", "transactions", associationParameters.addAll(Arrays.asList(DataTableApiConstant.repaymentScheduleAssociateParamName,
"charges", "guarantors", "collateral", "notes", "linkedAccount", "multiDisburseDetails")); DataTableApiConstant.futureScheduleAssociateParamName, DataTableApiConstant.originalScheduleAssociateParamName,
DataTableApiConstant.transactionsAssociateParamName, DataTableApiConstant.chargesAssociateParamName,
DataTableApiConstant.guarantorsAssociateParamName, DataTableApiConstant.collateralAssociateParamName,
DataTableApiConstant.notesAssociateParamName, DataTableApiConstant.linkedAccountAssociateParamName,
DataTableApiConstant.multiDisburseDetailsAssociateParamName, DataTableApiConstant.collectionAssociateParamName));
} }
ApiParameterHelper.excludeAssociationsForResponseIfProvided(uriInfo.getQueryParameters(), associationParameters); ApiParameterHelper.excludeAssociationsForResponseIfProvided(uriInfo.getQueryParameters(), associationParameters);
if (associationParameters.contains("guarantors")) { if (associationParameters.contains(DataTableApiConstant.guarantorsAssociateParamName)) {
mandatoryResponseParameters.add("guarantors"); mandatoryResponseParameters.add(DataTableApiConstant.guarantorsAssociateParamName);
guarantors = this.guarantorReadPlatformService.retrieveGuarantorsForLoan(loanId); guarantors = this.guarantorReadPlatformService.retrieveGuarantorsForLoan(loanId);
if (CollectionUtils.isEmpty(guarantors)) { if (CollectionUtils.isEmpty(guarantors)) {
guarantors = null; guarantors = null;
} }
} }
if (associationParameters.contains("transactions")) { if (associationParameters.contains(DataTableApiConstant.transactionsAssociateParamName)) {
mandatoryResponseParameters.add("transactions"); mandatoryResponseParameters.add(DataTableApiConstant.transactionsAssociateParamName);
final Collection<LoanTransactionData> currentLoanRepayments = this.loanReadPlatformService.retrieveLoanTransactions(loanId); final Collection<LoanTransactionData> currentLoanRepayments = this.loanReadPlatformService.retrieveLoanTransactions(loanId);
if (!CollectionUtils.isEmpty(currentLoanRepayments)) { if (!CollectionUtils.isEmpty(currentLoanRepayments)) {
loanRepayments = currentLoanRepayments; loanRepayments = currentLoanRepayments;
} }
} }
if (associationParameters.contains("multiDisburseDetails") || associationParameters.contains("repaymentSchedule")) { if (associationParameters.contains(DataTableApiConstant.multiDisburseDetailsAssociateParamName)
mandatoryResponseParameters.add("multiDisburseDetails"); || associationParameters.contains(DataTableApiConstant.repaymentScheduleAssociateParamName)) {
mandatoryResponseParameters.add(DataTableApiConstant.multiDisburseDetailsAssociateParamName);
disbursementData = this.loanReadPlatformService.retrieveLoanDisbursementDetails(loanId); disbursementData = this.loanReadPlatformService.retrieveLoanDisbursementDetails(loanId);
} }
if (associationParameters.contains("emiAmountVariations") || associationParameters.contains("repaymentSchedule")) { if (associationParameters.contains(DataTableApiConstant.emiAmountVariationsAssociateParamName)
mandatoryResponseParameters.add("emiAmountVariations"); || associationParameters.contains(DataTableApiConstant.repaymentScheduleAssociateParamName)) {
mandatoryResponseParameters.add(DataTableApiConstant.emiAmountVariationsAssociateParamName);
emiAmountVariations = this.loanReadPlatformService.retrieveLoanTermVariations(loanId, emiAmountVariations = this.loanReadPlatformService.retrieveLoanTermVariations(loanId,
LoanTermVariationType.EMI_AMOUNT.getValue()); LoanTermVariationType.EMI_AMOUNT.getValue());
} }
if (associationParameters.contains("repaymentSchedule")) { if (associationParameters.contains(DataTableApiConstant.repaymentScheduleAssociateParamName)) {
mandatoryResponseParameters.add("repaymentSchedule"); mandatoryResponseParameters.add(DataTableApiConstant.repaymentScheduleAssociateParamName);
final RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData = loanBasicDetails.repaymentScheduleRelatedData(); final RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData = loanBasicDetails.repaymentScheduleRelatedData();
repaymentSchedule = this.loanReadPlatformService.retrieveRepaymentSchedule(loanId, repaymentScheduleRelatedData, repaymentSchedule = this.loanReadPlatformService.retrieveRepaymentSchedule(loanId, repaymentScheduleRelatedData,
disbursementData, loanBasicDetails.isInterestRecalculationEnabled(), loanBasicDetails.getTotalPaidFeeCharges()); disbursementData, loanBasicDetails.isInterestRecalculationEnabled(), loanBasicDetails.getTotalPaidFeeCharges());
if (associationParameters.contains("futureSchedule") && loanBasicDetails.isInterestRecalculationEnabled()) { if (associationParameters.contains(DataTableApiConstant.futureScheduleAssociateParamName)
mandatoryResponseParameters.add("futureSchedule"); && loanBasicDetails.isInterestRecalculationEnabled()) {
mandatoryResponseParameters.add(DataTableApiConstant.futureScheduleAssociateParamName);
this.calculationPlatformService.updateFutureSchedule(repaymentSchedule, loanId); this.calculationPlatformService.updateFutureSchedule(repaymentSchedule, loanId);
} }
if (associationParameters.contains("originalSchedule") && loanBasicDetails.isInterestRecalculationEnabled() if (associationParameters.contains(DataTableApiConstant.originalScheduleAssociateParamName)
&& loanBasicDetails.isActive()) { && loanBasicDetails.isInterestRecalculationEnabled() && loanBasicDetails.isActive()) {
mandatoryResponseParameters.add("originalSchedule"); mandatoryResponseParameters.add(DataTableApiConstant.originalScheduleAssociateParamName);
LoanScheduleData loanScheduleData = this.loanScheduleHistoryReadPlatformService.retrieveRepaymentArchiveSchedule(loanId, LoanScheduleData loanScheduleData = this.loanScheduleHistoryReadPlatformService.retrieveRepaymentArchiveSchedule(loanId,
repaymentScheduleRelatedData, disbursementData); repaymentScheduleRelatedData, disbursementData);
loanBasicDetails = LoanAccountData.withOriginalSchedule(loanBasicDetails, loanScheduleData); loanBasicDetails = LoanAccountData.withOriginalSchedule(loanBasicDetails, loanScheduleData);
} }
} }
if (associationParameters.contains("charges")) { if (associationParameters.contains(DataTableApiConstant.chargesAssociateParamName)) {
mandatoryResponseParameters.add("charges"); mandatoryResponseParameters.add(DataTableApiConstant.chargesAssociateParamName);
charges = this.loanChargeReadPlatformService.retrieveLoanCharges(loanId); charges = this.loanChargeReadPlatformService.retrieveLoanCharges(loanId);
if (CollectionUtils.isEmpty(charges)) { if (CollectionUtils.isEmpty(charges)) {
charges = null; charges = null;
} }
} }
if (associationParameters.contains("collateral")) { if (associationParameters.contains(DataTableApiConstant.collateralAssociateParamName)) {
mandatoryResponseParameters.add("collateral"); mandatoryResponseParameters.add(DataTableApiConstant.collateralAssociateParamName);
loanCollateralManagements = this.loanCollateralManagementReadPlatformService.getLoanCollateralResponseDataList(loanId); loanCollateralManagements = this.loanCollateralManagementReadPlatformService.getLoanCollateralResponseDataList(loanId);
for (LoanCollateralResponseData loanCollateralManagement : loanCollateralManagements) { for (LoanCollateralResponseData loanCollateralManagement : loanCollateralManagements) {
loanCollateralManagementData.add(loanCollateralManagement.toCommand()); loanCollateralManagementData.add(loanCollateralManagement.toCommand());
@@ -620,24 +629,30 @@ public class LoansApiResource {
} }
} }
if (associationParameters.contains("meeting")) { if (associationParameters.contains(DataTableApiConstant.meetingAssociateParamName)) {
mandatoryResponseParameters.add("meeting"); mandatoryResponseParameters.add(DataTableApiConstant.meetingAssociateParamName);
meeting = this.calendarReadPlatformService.retrieveLoanCalendar(loanId); meeting = this.calendarReadPlatformService.retrieveLoanCalendar(loanId);
} }
if (associationParameters.contains("notes")) { if (associationParameters.contains(DataTableApiConstant.notesAssociateParamName)) {
mandatoryResponseParameters.add("notes"); mandatoryResponseParameters.add(DataTableApiConstant.notesAssociateParamName);
notes = this.noteReadPlatformService.retrieveNotesByResource(loanId, NoteType.LOAN.getValue()); notes = this.noteReadPlatformService.retrieveNotesByResource(loanId, NoteType.LOAN.getValue());
if (CollectionUtils.isEmpty(notes)) { if (CollectionUtils.isEmpty(notes)) {
notes = null; notes = null;
} }
} }
if (associationParameters.contains("linkedAccount")) { if (associationParameters.contains(DataTableApiConstant.linkedAccountAssociateParamName)) {
mandatoryResponseParameters.add("linkedAccount"); mandatoryResponseParameters.add(DataTableApiConstant.linkedAccountAssociateParamName);
linkedAccount = this.accountAssociationsReadPlatformService.retriveLoanLinkedAssociation(loanId); linkedAccount = this.accountAssociationsReadPlatformService.retriveLoanLinkedAssociation(loanId);
} }
if (associationParameters.contains(DataTableApiConstant.collectionAssociateParamName)) {
mandatoryResponseParameters.add(DataTableApiConstant.collectionAssociateParamName);
if (loanBasicDetails.isActive()) {
collectionData = this.loanReadPlatformService.retrieveLoanCollectionData(loanId);
}
}
} }
Collection<LoanProductData> productOptions = null; Collection<LoanProductData> productOptions = null;
@@ -707,8 +722,8 @@ public class LoansApiResource {
loanBasicDetails.clientId(), currencyCode, accountStatus, DepositAccountType.SAVINGS_DEPOSIT.getValue()); loanBasicDetails.clientId(), currencyCode, accountStatus, DepositAccountType.SAVINGS_DEPOSIT.getValue());
accountLinkingOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(portfolioAccountDTO); accountLinkingOptions = this.portfolioAccountReadPlatformService.retrieveAllForLookup(portfolioAccountDTO);
if (!associationParameters.contains("linkedAccount")) { if (!associationParameters.contains(DataTableApiConstant.linkedAccountAssociateParamName)) {
mandatoryResponseParameters.add("linkedAccount"); mandatoryResponseParameters.add(DataTableApiConstant.linkedAccountAssociateParamName);
linkedAccount = this.accountAssociationsReadPlatformService.retriveLoanLinkedAssociation(loanId); linkedAccount = this.accountAssociationsReadPlatformService.retriveLoanLinkedAssociation(loanId);
} }
if (loanBasicDetails.groupId() != null) { if (loanBasicDetails.groupId() != null) {
@@ -740,12 +755,12 @@ public class LoansApiResource {
repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions,
interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers, loanPurposeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, allowedLoanOfficers, loanPurposeOptions,
loanCollateralOptions, calendarOptions, notes, accountLinkingOptions, linkedAccount, disbursementData, emiAmountVariations, loanCollateralOptions, calendarOptions, notes, accountLinkingOptions, linkedAccount, disbursementData, emiAmountVariations,
overdueCharges, paidInAdvanceTemplate, interestRatesPeriods, clientActiveLoanOptions, rates, isRatesEnabled); overdueCharges, paidInAdvanceTemplate, interestRatesPeriods, clientActiveLoanOptions, rates, isRatesEnabled,
collectionData);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters(), final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters(),
mandatoryResponseParameters); mandatoryResponseParameters);
String toReturn = this.toApiJsonSerializer.serialize(settings, loanAccount, this.loanDataParameters); return this.toApiJsonSerializer.serialize(settings, loanAccount, this.loanDataParameters);
return toReturn;
} }
@GET @GET
@@ -0,0 +1,90 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.loanaccount.data;
import java.math.BigDecimal;
import java.time.LocalDate;
public final class CollectionData {
private final BigDecimal availableDisbursementAmount;
private final int pastDueDays;
private final LocalDate nextPaymentDueDate;
private final int delinquentDays;
private final LocalDate delinquentDate;
private final BigDecimal delinquentAmount;
private final LocalDate lastPaymentDate;
private final BigDecimal lastPaymentAmount;
private CollectionData(BigDecimal availableDisbursementAmount, int pastDueDays, LocalDate nextPaymentDueDate, int delinquentDays,
LocalDate delinquentDate, BigDecimal delinquentAmount, LocalDate lastPaymentDate, BigDecimal lastPaymentAmount) {
this.availableDisbursementAmount = availableDisbursementAmount;
this.pastDueDays = pastDueDays;
this.nextPaymentDueDate = nextPaymentDueDate;
this.delinquentDays = delinquentDays;
this.delinquentDate = delinquentDate;
this.delinquentAmount = delinquentAmount;
this.lastPaymentDate = lastPaymentDate;
this.lastPaymentAmount = lastPaymentAmount;
}
public static CollectionData instance(BigDecimal availableDisbursementAmount, int pastDueDays, LocalDate nextPaymentDueDate,
int delinquentDays, LocalDate delinquentDate, BigDecimal delinquentAmount, LocalDate lastPaymentDate,
BigDecimal lastPaymentAmount) {
return new CollectionData(availableDisbursementAmount, pastDueDays, nextPaymentDueDate, delinquentDays, delinquentDate,
delinquentAmount, lastPaymentDate, lastPaymentAmount);
}
public static CollectionData template() {
final BigDecimal zero = BigDecimal.ZERO;
return new CollectionData(zero, 0, null, 0, null, zero, null, zero);
}
public BigDecimal getAvailableDisbursementAmount() {
return availableDisbursementAmount;
}
public int getPastDueDays() {
return pastDueDays;
}
public LocalDate getNextPaymentDueDate() {
return nextPaymentDueDate;
}
public int getDelinquentDays() {
return delinquentDays;
}
public LocalDate getDelinquentDate() {
return delinquentDate;
}
public BigDecimal getDelinquentAmount() {
return delinquentAmount;
}
public LocalDate getLastPaymentDate() {
return lastPaymentDate;
}
public BigDecimal getLastPaymentAmount() {
return lastPaymentAmount;
}
}
@@ -238,6 +238,8 @@ public final class LoanAccountData {
private Long groupId; private Long groupId;
private LocalDate expectedDisbursementDate; private LocalDate expectedDisbursementDate;
private final CollectionData delinquent;
public static LoanAccountData importInstanceIndividual(EnumOptionData loanTypeEnumOption, Long clientId, Long productId, public static LoanAccountData importInstanceIndividual(EnumOptionData loanTypeEnumOption, Long clientId, Long productId,
Long loanOfficerId, LocalDate submittedOnDate, Long fundId, BigDecimal principal, Integer numberOfRepayments, Long loanOfficerId, LocalDate submittedOnDate, Long fundId, BigDecimal principal, Integer numberOfRepayments,
Integer repaymentEvery, EnumOptionData repaidEveryFrequencyEnums, Integer loanTermFrequency, Integer repaymentEvery, EnumOptionData repaidEveryFrequencyEnums, Integer loanTermFrequency,
@@ -423,6 +425,7 @@ public final class LoanAccountData {
this.isEqualAmortization = null; this.isEqualAmortization = null;
this.isRatesEnabled = false; this.isRatesEnabled = false;
this.fixedPrincipalPercentagePerInstallment = null; this.fixedPrincipalPercentagePerInstallment = null;
this.delinquent = null;
} }
public Integer getRowIndex() { public Integer getRowIndex() {
@@ -588,6 +591,7 @@ public final class LoanAccountData {
final List<RateData> rates = null; final List<RateData> rates = null;
final Boolean isRatesEnabled = false; final Boolean isRatesEnabled = false;
final BigDecimal fixedPrincipalPercentagePerInstallment = null; final BigDecimal fixedPrincipalPercentagePerInstallment = null;
final CollectionData delinquent = CollectionData.template();
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
@@ -609,8 +613,7 @@ public final class LoanAccountData {
interestRecalculationData, originalSchedule, createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, interestRecalculationData, originalSchedule, createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods,
isVariableInstallmentsAllowed, minimumGap, maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, isVariableInstallmentsAllowed, minimumGap, maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup,
closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization, rates, isRatesEnabled, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization, rates, isRatesEnabled,
fixedPrincipalPercentagePerInstallment); fixedPrincipalPercentagePerInstallment, delinquent);
} }
/** /**
@@ -734,6 +737,7 @@ public final class LoanAccountData {
final List<RateData> rates = null; final List<RateData> rates = null;
final Boolean isRatesEnabled = false; final Boolean isRatesEnabled = false;
final BigDecimal fixedPrincipalPercentagePerInstallment = null; final BigDecimal fixedPrincipalPercentagePerInstallment = null;
final CollectionData delinquent = CollectionData.template();
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
@@ -755,8 +759,7 @@ public final class LoanAccountData {
originalSchedule, createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, originalSchedule, createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods,
isVariableInstallmentsAllowed, minimumGap, maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, isVariableInstallmentsAllowed, minimumGap, maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup,
closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization, rates, isRatesEnabled, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization, rates, isRatesEnabled,
fixedPrincipalPercentagePerInstallment); fixedPrincipalPercentagePerInstallment, delinquent);
} }
public static LoanAccountData populateClientDefaults(final LoanAccountData acc, final LoanAccountData clientAcc) { public static LoanAccountData populateClientDefaults(final LoanAccountData acc, final LoanAccountData clientAcc) {
@@ -787,7 +790,7 @@ public final class LoanAccountData {
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed, acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
acc.fixedPrincipalPercentagePerInstallment); acc.fixedPrincipalPercentagePerInstallment, acc.delinquent);
} }
/** /**
@@ -913,6 +916,7 @@ public final class LoanAccountData {
final List<RateData> rates = null; final List<RateData> rates = null;
final Boolean isRatesEnabled = false; final Boolean isRatesEnabled = false;
final BigDecimal fixedPrincipalPercentagePerInstallment = null; final BigDecimal fixedPrincipalPercentagePerInstallment = null;
final CollectionData delinquent = CollectionData.template();
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
@@ -934,8 +938,7 @@ public final class LoanAccountData {
originalSchedule, createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, originalSchedule, createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods,
isVariableInstallmentsAllowed, minimumGap, maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, isVariableInstallmentsAllowed, minimumGap, maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup,
closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization, rates, isRatesEnabled, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization, rates, isRatesEnabled,
fixedPrincipalPercentagePerInstallment); fixedPrincipalPercentagePerInstallment, delinquent);
} }
public static LoanAccountData populateGroupDefaults(final LoanAccountData acc, final LoanAccountData groupAcc) { public static LoanAccountData populateGroupDefaults(final LoanAccountData acc, final LoanAccountData groupAcc) {
@@ -965,8 +968,7 @@ public final class LoanAccountData {
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed, acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
acc.fixedPrincipalPercentagePerInstallment); acc.fixedPrincipalPercentagePerInstallment, acc.delinquent);
} }
public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product, public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product,
@@ -1107,6 +1109,7 @@ public final class LoanAccountData {
final BigDecimal topupAmount = null; final BigDecimal topupAmount = null;
final List<RateData> rates = null; final List<RateData> rates = null;
final Boolean isRatesEnabled = false; final Boolean isRatesEnabled = false;
final CollectionData delinquent = CollectionData.template();
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
loanType, product.getId(), product.getName(), product.getDescription(), product.isLinkedToFloatingInterestRates(), loanType, product.getId(), product.getName(), product.getDescription(), product.isLinkedToFloatingInterestRates(),
@@ -1133,7 +1136,7 @@ public final class LoanAccountData {
product.isVariableInstallmentsAllowed(), product.getMinimumGapBetweenInstallments(), product.isVariableInstallmentsAllowed(), product.getMinimumGapBetweenInstallments(),
product.getMaximumGapBetweenInstallments(), subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, product.getMaximumGapBetweenInstallments(), subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId,
closureLoanAccountNo, topupAmount, product.isEqualAmortization(), rates, isRatesEnabled, closureLoanAccountNo, topupAmount, product.isEqualAmortization(), rates, isRatesEnabled,
product.getFixedPrincipalPercentagePerInstallment()); product.getFixedPrincipalPercentagePerInstallment(), delinquent);
} }
public static LoanAccountData populateLoanProductDefaults(final LoanAccountData acc, final LoanProductData product) { public static LoanAccountData populateLoanProductDefaults(final LoanAccountData acc, final LoanProductData product) {
@@ -1175,6 +1178,7 @@ public final class LoanAccountData {
netDisbursalAmount = netDisbursalAmount.subtract(charge.getAmount()); netDisbursalAmount = netDisbursalAmount.subtract(charge.getAmount());
} }
} }
final CollectionData delinquent = CollectionData.template();
return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName,
acc.clientOfficeId, acc.group, acc.loanType, product.getId(), product.getName(), product.getDescription(), acc.clientOfficeId, acc.group, acc.loanType, product.getId(), product.getName(), product.getDescription(),
@@ -1202,8 +1206,7 @@ public final class LoanAccountData {
product.isVariableInstallmentsAllowed(), product.getMinimumGapBetweenInstallments(), product.isVariableInstallmentsAllowed(), product.getMinimumGapBetweenInstallments(),
product.getMaximumGapBetweenInstallments(), acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup, product.getMaximumGapBetweenInstallments(), acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, product.isEqualAmortization(), acc.rates, acc.isRatesEnabled, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, product.isEqualAmortization(), acc.rates, acc.isRatesEnabled,
product.getFixedPrincipalPercentagePerInstallment()); product.getFixedPrincipalPercentagePerInstallment(), delinquent);
} }
/* /*
@@ -1273,6 +1276,7 @@ public final class LoanAccountData {
final Collection<LoanAccountSummaryData> clientActiveLoanOptions = null; final Collection<LoanAccountSummaryData> clientActiveLoanOptions = null;
final List<RateData> rates = null; final List<RateData> rates = null;
final Boolean isRatesEnabled = false; final Boolean isRatesEnabled = false;
final CollectionData delinquent = CollectionData.template();
return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group,
loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName,
@@ -1293,7 +1297,7 @@ public final class LoanAccountData {
isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule, isNPA, daysInMonthType, daysInYearType, isInterestRecalculationEnabled, interestRecalculationData, originalSchedule,
createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap, createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, isVariableInstallmentsAllowed, minimumGap,
maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, maximumGap, subStatus, canUseForTopup, clientActiveLoanOptions, isTopup, closureLoanId, closureLoanAccountNo, topupAmount,
isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment); isEqualAmortization, rates, isRatesEnabled, fixedPrincipalPercentagePerInstallment, delinquent);
} }
/* /*
@@ -1316,7 +1320,8 @@ public final class LoanAccountData {
final PortfolioAccountData linkedAccount, final Collection<DisbursementData> disbursementDetails, final PortfolioAccountData linkedAccount, final Collection<DisbursementData> disbursementDetails,
final Collection<LoanTermVariationsData> emiAmountVariations, final Collection<ChargeData> overdueCharges, final Collection<LoanTermVariationsData> emiAmountVariations, final Collection<ChargeData> overdueCharges,
final PaidInAdvanceData paidInAdvance, Collection<InterestRatePeriodData> interestRatesPeriods, final PaidInAdvanceData paidInAdvance, Collection<InterestRatePeriodData> interestRatesPeriods,
final Collection<LoanAccountSummaryData> clientActiveLoanOptions, final List<RateData> rates, final Boolean isRatesEnabled) { final Collection<LoanAccountSummaryData> clientActiveLoanOptions, final List<RateData> rates, final Boolean isRatesEnabled,
final CollectionData delinquent) {
LoanProductConfigurableAttributes loanProductConfigurableAttributes = null; LoanProductConfigurableAttributes loanProductConfigurableAttributes = null;
if (acc.product != null) { if (acc.product != null) {
loanProductConfigurableAttributes = acc.product.getloanProductConfigurableAttributes(); loanProductConfigurableAttributes = acc.product.getloanProductConfigurableAttributes();
@@ -1346,7 +1351,7 @@ public final class LoanAccountData {
acc.createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, acc.isVariableInstallmentsAllowed, acc.createStandingInstructionAtDisbursement, paidInAdvance, interestRatesPeriods, acc.isVariableInstallmentsAllowed,
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, clientActiveLoanOptions, acc.isTopup, acc.closureLoanId, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, clientActiveLoanOptions, acc.isTopup, acc.closureLoanId,
acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, rates, isRatesEnabled, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, rates, isRatesEnabled,
acc.fixedPrincipalPercentagePerInstallment); acc.fixedPrincipalPercentagePerInstallment, delinquent);
} }
public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final Collection<LoanProductData> productOptions, public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final Collection<LoanProductData> productOptions,
@@ -1359,7 +1364,7 @@ public final class LoanAccountData {
acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null, acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null,
allowedLoanOfficers, acc.loanPurposeOptions, acc.loanCollateralOptions, calendarOptions, acc.notes, accountLinkingOptions, allowedLoanOfficers, acc.loanPurposeOptions, acc.loanCollateralOptions, calendarOptions, acc.notes, accountLinkingOptions,
acc.linkedAccount, acc.disbursementDetails, acc.emiAmountVariations, acc.overdueCharges, acc.paidInAdvance, acc.linkedAccount, acc.disbursementDetails, acc.emiAmountVariations, acc.overdueCharges, acc.paidInAdvance,
acc.interestRatesPeriods, acc.clientActiveLoanOptions, acc.rates, isRatesEnabled); acc.interestRatesPeriods, acc.clientActiveLoanOptions, acc.rates, isRatesEnabled, acc.delinquent);
} }
public static LoanAccountData associateGroup(final LoanAccountData acc, final GroupGeneralData group) { public static LoanAccountData associateGroup(final LoanAccountData acc, final GroupGeneralData group) {
@@ -1389,7 +1394,7 @@ public final class LoanAccountData {
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed, acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
acc.fixedPrincipalPercentagePerInstallment); acc.fixedPrincipalPercentagePerInstallment, acc.delinquent);
} }
public static LoanAccountData associateMemberVariations(final LoanAccountData acc, final Map<Long, Integer> memberLoanCycle) { public static LoanAccountData associateMemberVariations(final LoanAccountData acc, final Map<Long, Integer> memberLoanCycle) {
@@ -1455,8 +1460,7 @@ public final class LoanAccountData {
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed, acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
acc.fixedPrincipalPercentagePerInstallment); acc.fixedPrincipalPercentagePerInstallment, acc.delinquent);
} }
public static LoanAccountData withInterestRecalculationCalendarData(final LoanAccountData acc, final CalendarData calendarData, public static LoanAccountData withInterestRecalculationCalendarData(final LoanAccountData acc, final CalendarData calendarData,
@@ -1490,7 +1494,7 @@ public final class LoanAccountData {
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed, acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
acc.fixedPrincipalPercentagePerInstallment); acc.fixedPrincipalPercentagePerInstallment, acc.delinquent);
} }
public static LoanAccountData withLoanCalendarData(final LoanAccountData acc, final CalendarData calendarData) { public static LoanAccountData withLoanCalendarData(final LoanAccountData acc, final CalendarData calendarData) {
@@ -1519,7 +1523,7 @@ public final class LoanAccountData {
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed, acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
acc.fixedPrincipalPercentagePerInstallment); acc.fixedPrincipalPercentagePerInstallment, acc.delinquent);
} }
public static LoanAccountData withOriginalSchedule(final LoanAccountData acc, final LoanScheduleData originalSchedule) { public static LoanAccountData withOriginalSchedule(final LoanAccountData acc, final LoanScheduleData originalSchedule) {
@@ -1549,7 +1553,7 @@ public final class LoanAccountData {
acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed, acc.createStandingInstructionAtDisbursement, acc.paidInAdvance, acc.interestRatesPeriods, acc.isVariableInstallmentsAllowed,
acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup, acc.minimumGap, acc.maximumGap, acc.subStatus, acc.canUseForTopup, acc.clientActiveLoanOptions, acc.isTopup,
acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled, acc.closureLoanId, acc.closureLoanAccountNo, acc.topupAmount, acc.isEqualAmortization, acc.rates, acc.isRatesEnabled,
acc.fixedPrincipalPercentagePerInstallment); acc.fixedPrincipalPercentagePerInstallment, acc.delinquent);
} }
private LoanAccountData(final Long id, // private LoanAccountData(final Long id, //
@@ -1602,7 +1606,7 @@ public final class LoanAccountData {
final Integer minimumGap, final Integer maximumGap, final EnumOptionData subStatus, final Boolean canUseForTopup, final Integer minimumGap, final Integer maximumGap, final EnumOptionData subStatus, final Boolean canUseForTopup,
final Collection<LoanAccountSummaryData> clientActiveLoanOptions, final boolean isTopup, final Long closureLoanId, final Collection<LoanAccountSummaryData> clientActiveLoanOptions, final boolean isTopup, final Long closureLoanId,
final String closureLoanAccountNo, final BigDecimal topupAmount, final boolean isEqualAmortization, final List<RateData> rates, final String closureLoanAccountNo, final BigDecimal topupAmount, final boolean isEqualAmortization, final List<RateData> rates,
final Boolean isRatesEnabled, final BigDecimal fixedPrincipalPercentagePerInstallment) { final Boolean isRatesEnabled, final BigDecimal fixedPrincipalPercentagePerInstallment, final CollectionData delinquent) {
this.id = id; this.id = id;
this.accountNo = accountNo; this.accountNo = accountNo;
@@ -1789,6 +1793,7 @@ public final class LoanAccountData {
this.isEqualAmortization = isEqualAmortization; this.isEqualAmortization = isEqualAmortization;
this.rates = rates; this.rates = rates;
this.fixedPrincipalPercentagePerInstallment = fixedPrincipalPercentagePerInstallment; this.fixedPrincipalPercentagePerInstallment = fixedPrincipalPercentagePerInstallment;
this.delinquent = delinquent;
} }
public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() { public RepaymentScheduleRelatedLoanData repaymentScheduleRelatedData() {
@@ -28,6 +28,7 @@ import org.apache.fineract.infrastructure.core.service.SearchParameters;
import org.apache.fineract.organisation.staff.data.StaffData; import org.apache.fineract.organisation.staff.data.StaffData;
import org.apache.fineract.portfolio.calendar.data.CalendarData; import org.apache.fineract.portfolio.calendar.data.CalendarData;
import org.apache.fineract.portfolio.floatingrates.data.InterestRatePeriodData; import org.apache.fineract.portfolio.floatingrates.data.InterestRatePeriodData;
import org.apache.fineract.portfolio.loanaccount.data.CollectionData;
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.LoanApprovalData; import org.apache.fineract.portfolio.loanaccount.data.LoanApprovalData;
@@ -147,4 +148,5 @@ public interface LoanReadPlatformService {
List<LoanRepaymentScheduleInstallmentData> getRepaymentDataResponse(Long loanId); List<LoanRepaymentScheduleInstallmentData> getRepaymentDataResponse(Long loanId);
CollectionData retrieveLoanCollectionData(Long loanId);
} }
@@ -81,6 +81,7 @@ 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.api.LoanApiConstants;
import org.apache.fineract.portfolio.loanaccount.data.CollectionData;
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;
@@ -2349,4 +2350,58 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
final String sql = "select count(*) from m_loan"; final String sql = "select count(*) from m_loan";
return this.jdbcTemplate.queryForObject(sql, Integer.class); return this.jdbcTemplate.queryForObject(sql, Integer.class);
} }
@Override
public CollectionData retrieveLoanCollectionData(Long loanId) {
final CollectionDataMapper mapper = new CollectionDataMapper(sqlGenerator);
String sql = "select " + mapper.schema();
CollectionData collectionData = this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { loanId });
return collectionData;
}
private static final class CollectionDataMapper implements RowMapper<CollectionData> {
private final DatabaseSpecificSQLGenerator sqlGenerator;
CollectionDataMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
this.sqlGenerator = sqlGenerator;
}
public String schema() {
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append(
"l.id as loanId, coalesce((l.approved_principal - l.principal_disbursed_derived), 0) as availableDisbursementAmount, ");
sqlBuilder.append(sqlGenerator.dateDiff(sqlGenerator.currentDate(), "laa.overdue_since_date_derived") + " as pastDueDays, ");
sqlBuilder.append(
"(select coalesce(min(lrs.duedate), null) as duedate from m_loan_repayment_schedule lrs where lrs.loan_id=l.id and lrs.completed_derived is false and lrs.duedate >= "
+ sqlGenerator.currentDate() + ") as nextPaymentDueDate, ");
sqlBuilder.append(sqlGenerator.dateDiff(sqlGenerator.currentDate(), "laa.overdue_since_date_derived") + " as delinquentDays, ");
sqlBuilder.append(
sqlGenerator.currentDate() + " as delinquentDate, coalesce(laa.total_overdue_derived, 0) as delinquentAmount, ");
sqlBuilder.append("lre.transactionDate as lastPaymentDate, coalesce(lre.amount, 0) as lastPaymentAmount ");
sqlBuilder.append("from m_loan l inner join m_loan_arrears_aging laa on laa.loan_id = l.id ");
sqlBuilder.append(
"left join (select lt.loan_id, lt.transaction_date as transactionDate, lt.amount as amount from m_loan_transaction lt ");
sqlBuilder.append(
"where lt.is_reversed = false and lt.transaction_type_enum=2 order by lt.transaction_date desc limit 1) lre on lre.loan_id = l.id ");
sqlBuilder.append("where l.id=? ");
return sqlBuilder.toString();
}
@Override
public CollectionData mapRow(ResultSet rs, int rowNum) throws SQLException {
final LocalDate nextPaymentDueDate = JdbcSupport.getLocalDate(rs, "nextPaymentDueDate");
final LocalDate delinquentDate = JdbcSupport.getLocalDate(rs, "delinquentDate");
final LocalDate lastPaymentDate = JdbcSupport.getLocalDate(rs, "lastPaymentDate");
final BigDecimal availableDisbursementAmount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "availableDisbursementAmount");
final BigDecimal delinquentAmount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "delinquentAmount");
final BigDecimal lastPaymentAmount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "lastPaymentAmount");
final int pastDueDays = rs.getInt("pastDueDays");
final int delinquentDays = rs.getInt("delinquentDays");
return CollectionData.instance(availableDisbursementAmount, pastDueDays, nextPaymentDueDate, delinquentDays, delinquentDate,
delinquentAmount, lastPaymentDate, lastPaymentAmount);
}
}
} }
@@ -32,7 +32,7 @@
<!-- See https://github.com/apache/fineract/#logging-guidelines for why by default we log only to INFO, only (WARN and) ERROR <!-- See https://github.com/apache/fineract/#logging-guidelines for why by default we log only to INFO, only (WARN and) ERROR
but it's still possible to override this using java -Dlogging.level.root=info -jar fineract-provider.jar, as per https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-custom-log-levels --> but it's still possible to override this using java -Dlogging.level.root=info -jar fineract-provider.jar, as per https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-custom-log-levels -->
<root level="warn"> <root level="info">
<appender-ref ref="CONSOLE" /> <appender-ref ref="CONSOLE" />
</root> </root>
@@ -24,7 +24,7 @@
<resetJUL>false</resetJUL> <resetJUL>false</resetJUL>
</contextListener> </contextListener>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" target="System.out" class="ch.qos.logback.core.ConsoleAppender">
<withJansi>true</withJansi> <withJansi>true</withJansi>
<encoder> <encoder>
<pattern>%green(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%thread] %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern> <pattern>%green(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%thread] %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern>
@@ -40,6 +40,7 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
@@ -3399,7 +3400,7 @@ public class ClientLoanIntegrationTest {
public void testLoanScheduleWithInterestRecalculation_WITH_REST_SAME_AS_REPAYMENT_INTEREST_COMPOUND_NONE_STRATEGY_REDUCE_EMI() { public void testLoanScheduleWithInterestRecalculation_WITH_REST_SAME_AS_REPAYMENT_INTEREST_COMPOUND_NONE_STRATEGY_REDUCE_EMI() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
@@ -3509,7 +3510,7 @@ public class ClientLoanIntegrationTest {
private void testLoanScheduleWithInterestRecalculation_WITH_REST_SAME_AS_REPAYMENT_INTEREST_COMPOUND_NONE_STRATEGY_REDUCE_EMI_PRE_CLOSE_INTEREST( private void testLoanScheduleWithInterestRecalculation_WITH_REST_SAME_AS_REPAYMENT_INTEREST_COMPOUND_NONE_STRATEGY_REDUCE_EMI_PRE_CLOSE_INTEREST(
String preCloseInterestStrategy, String preCloseAmount) { String preCloseInterestStrategy, String preCloseAmount) {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
@@ -3590,7 +3591,7 @@ public class ClientLoanIntegrationTest {
public void testLoanScheduleWithInterestRecalculation_WITH_REST_SAME_AS_REPAYMENT_INTEREST_COMPOUND_NONE_STRATEGY_REDUCE_EMI_WITH_INSTALLMENT_CHARGE() { public void testLoanScheduleWithInterestRecalculation_WITH_REST_SAME_AS_REPAYMENT_INTEREST_COMPOUND_NONE_STRATEGY_REDUCE_EMI_WITH_INSTALLMENT_CHARGE() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
@@ -3688,7 +3689,7 @@ public class ClientLoanIntegrationTest {
public void testLoanScheduleWithInterestRecalculation_WITH_REST_DAILY_INTEREST_COMPOUND_INTEREST_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS() { public void testLoanScheduleWithInterestRecalculation_WITH_REST_DAILY_INTEREST_COMPOUND_INTEREST_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
@@ -3802,7 +3803,7 @@ public class ClientLoanIntegrationTest {
public void testLoanScheduleWithInterestRecalculation_WITH_REST_WEEKLY_INTEREST_COMPOUND_INTEREST_FEE_STRATEGY_REDUCE_NEXT_INSTALLMENTS() { public void testLoanScheduleWithInterestRecalculation_WITH_REST_WEEKLY_INTEREST_COMPOUND_INTEREST_FEE_STRATEGY_REDUCE_NEXT_INSTALLMENTS() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
@@ -3939,7 +3940,7 @@ public class ClientLoanIntegrationTest {
String preCloseInterestStrategy, String preCloseAmount) { String preCloseInterestStrategy, String preCloseAmount) {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
@@ -4041,7 +4042,7 @@ public class ClientLoanIntegrationTest {
throws InterruptedException { throws InterruptedException {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
@@ -4157,7 +4158,7 @@ public class ClientLoanIntegrationTest {
this.periodicAccrualAccountingHelper = new PeriodicAccrualAccountingHelper(this.requestSpec, this.responseSpec); this.periodicAccrualAccountingHelper = new PeriodicAccrualAccountingHelper(this.requestSpec, this.responseSpec);
this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec); this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
final Account assetAccount = this.accountHelper.createAssetAccount(); final Account assetAccount = this.accountHelper.createAssetAccount();
@@ -4263,7 +4264,7 @@ public class ClientLoanIntegrationTest {
public void testLoanScheduleWithInterestRecalculation_WITH_CURRENT_REPAYMENT_BASED_ARREARS_AGEING() { public void testLoanScheduleWithInterestRecalculation_WITH_CURRENT_REPAYMENT_BASED_ARREARS_AGEING() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
@@ -4345,7 +4346,7 @@ public class ClientLoanIntegrationTest {
public void testLoanScheduleWithInterestRecalculation_WITH_ORIGINAL_REPAYMENT_BASED_ARREARS_AGEING() { public void testLoanScheduleWithInterestRecalculation_WITH_ORIGINAL_REPAYMENT_BASED_ARREARS_AGEING() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
@@ -4440,7 +4441,7 @@ public class ClientLoanIntegrationTest {
final String preCloseAmount) { final String preCloseAmount) {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
@@ -5390,7 +5391,7 @@ public class ClientLoanIntegrationTest {
public void testLoanScheduleWithInterestRecalculation_WITH_INTEREST_FIRST_STRATEGY_AND_REST_DAILY_INTEREST_COMPOUND_INTEREST_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS() { public void testLoanScheduleWithInterestRecalculation_WITH_INTEREST_FIRST_STRATEGY_AND_REST_DAILY_INTEREST_COMPOUND_INTEREST_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
@@ -5505,7 +5506,7 @@ public class ClientLoanIntegrationTest {
public void testLoanScheduleWithInterestRecalculation_WITH_INTEREST_FIRST_STRATEGY_AND_REST_DAILY_INTEREST_COMPOUND_INTEREST_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS_EARLY_REPAYMENT() { public void testLoanScheduleWithInterestRecalculation_WITH_INTEREST_FIRST_STRATEGY_AND_REST_DAILY_INTEREST_COMPOUND_INTEREST_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS_EARLY_REPAYMENT() {
this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar todaysDate = Calendar.getInstance(Utils.getTimeZoneOfTenant());
@@ -374,7 +374,7 @@ public class ClientSavingsIntegrationTest {
balance -= chargeAmt; balance -= chargeAmt;
assertEquals(balance, summary.get("accountBalance"), "Verifying opening Balance"); assertEquals(balance, summary.get("accountBalance"), "Verifying opening Balance");
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance(); Calendar todaysDate = Calendar.getInstance();
final String TRANSACTION_DATE = dateFormat.format(todaysDate.getTime()); final String TRANSACTION_DATE = dateFormat.format(todaysDate.getTime());
final String withdrawAmt = "800"; final String withdrawAmt = "800";
@@ -2284,7 +2284,7 @@ public class ClientSavingsIntegrationTest {
assertEquals(balance, summary.get("availableBalance"), "Verifying available Balance is -1000"); assertEquals(balance, summary.get("availableBalance"), "Verifying available Balance is -1000");
Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, "1200", Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, "1200",
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID); SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance(); Calendar todaysDate = Calendar.getInstance();
final String TRANSACTION_DATE = dateFormat.format(todaysDate.getTime()); final String TRANSACTION_DATE = dateFormat.format(todaysDate.getTime());
@@ -2348,7 +2348,7 @@ public class ClientSavingsIntegrationTest {
Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, "1200", Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, "1200",
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID); SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance(); Calendar todaysDate = Calendar.getInstance();
final String TRANSACTION_DATE = dateFormat.format(todaysDate.getTime()); final String TRANSACTION_DATE = dateFormat.format(todaysDate.getTime());
@@ -2412,7 +2412,7 @@ public class ClientSavingsIntegrationTest {
Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, "1100", Integer depositTransactionId = (Integer) this.savingsAccountHelper.depositToSavingsAccount(savingsId, "1100",
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID); SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance(); Calendar todaysDate = Calendar.getInstance();
final String TRANSACTION_DATE = dateFormat.format(todaysDate.getTime()); final String TRANSACTION_DATE = dateFormat.format(todaysDate.getTime());
@@ -2488,7 +2488,7 @@ public class ClientSavingsIntegrationTest {
// hold // hold
SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID); SavingsAccountHelper.TRANSACTION_DATE, CommonConstants.RESPONSE_RESOURCE_ID);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Calendar todaysDate = Calendar.getInstance(); Calendar todaysDate = Calendar.getInstance();
final String TRANSACTION_DATE = dateFormat.format(todaysDate.getTime()); final String TRANSACTION_DATE = dateFormat.format(todaysDate.getTime());
@@ -31,6 +31,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import org.apache.fineract.integrationtests.common.CalendarHelper; import org.apache.fineract.integrationtests.common.CalendarHelper;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.GroupHelper; import org.apache.fineract.integrationtests.common.GroupHelper;
@@ -69,7 +70,7 @@ public class DisbursalAndRepaymentScheduleTest {
private final String numberOfRepayments = "12"; private final String numberOfRepayments = "12";
private final String interestRatePerPeriod = "18"; private final String interestRatePerPeriod = "18";
private final SimpleDateFormat dateFormatterStandard = new SimpleDateFormat("dd MMMM yyyy"); private final SimpleDateFormat dateFormatterStandard = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
@BeforeEach @BeforeEach
public void setup() { public void setup() {
@@ -31,6 +31,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CollateralManagementHelper; import org.apache.fineract.integrationtests.common.CollateralManagementHelper;
import org.apache.fineract.integrationtests.common.Utils; import org.apache.fineract.integrationtests.common.Utils;
@@ -436,7 +437,7 @@ public class LoanDisbursementDetailsIntegrationTest {
private String formatExpectedDisbursementDate(String expectedDisbursementDate) throws ParseException { private String formatExpectedDisbursementDate(String expectedDisbursementDate) throws ParseException {
SimpleDateFormat source = new SimpleDateFormat("[yyyy, MM, dd]"); SimpleDateFormat source = new SimpleDateFormat("[yyyy, MM, dd]");
SimpleDateFormat target = new SimpleDateFormat("dd MMMM yyyy"); SimpleDateFormat target = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
String date = target.format(source.parse(expectedDisbursementDate)); String date = target.format(source.parse(expectedDisbursementDate));
return date; return date;
@@ -36,6 +36,7 @@ import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import org.apache.fineract.integrationtests.common.CalendarHelper; import org.apache.fineract.integrationtests.common.CalendarHelper;
import org.apache.fineract.integrationtests.common.CenterDomain; import org.apache.fineract.integrationtests.common.CenterDomain;
import org.apache.fineract.integrationtests.common.CenterHelper; import org.apache.fineract.integrationtests.common.CenterHelper;
@@ -103,7 +104,7 @@ public class LoanReschedulingWithinCenterTest {
associateClientsToGroup(groupId, clientId); associateClientsToGroup(groupId, clientId);
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar today = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar today = Calendar.getInstance(Utils.getTimeZoneOfTenant());
today.add(Calendar.DAY_OF_MONTH, -14); today.add(Calendar.DAY_OF_MONTH, -14);
@@ -193,7 +194,7 @@ public class LoanReschedulingWithinCenterTest {
} }
private Integer createCalendarMeeting(Integer centerId) { private Integer createCalendarMeeting(Integer centerId) {
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar today = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar today = Calendar.getInstance(Utils.getTimeZoneOfTenant());
final String startDate = dateFormat.format(today.getTime()); final String startDate = dateFormat.format(today.getTime());
@@ -236,7 +237,7 @@ public class LoanReschedulingWithinCenterTest {
associateClientsToGroup(groupId, clientId); associateClientsToGroup(groupId, clientId);
// CREATE A LOAN PRODUCT // CREATE A LOAN PRODUCT
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar today = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar today = Calendar.getInstance(Utils.getTimeZoneOfTenant());
today.add(Calendar.DAY_OF_MONTH, -14); today.add(Calendar.DAY_OF_MONTH, -14);
@@ -33,6 +33,7 @@ import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.CollateralManagementHelper; import org.apache.fineract.integrationtests.common.CollateralManagementHelper;
import org.apache.fineract.integrationtests.common.PaymentTypeDomain; import org.apache.fineract.integrationtests.common.PaymentTypeDomain;
@@ -50,7 +51,7 @@ public class RepaymentWithPostDatedChecksTest {
private ResponseSpecification responseSpec; private ResponseSpecification responseSpec;
private RequestSpecification requestSpec; private RequestSpecification requestSpec;
private final SimpleDateFormat dateFormatterStandard = new SimpleDateFormat("dd MMMM yyyy"); private final SimpleDateFormat dateFormatterStandard = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
private LoanTransactionHelper loanTransactionHelper; private LoanTransactionHelper loanTransactionHelper;
@BeforeEach @BeforeEach
@@ -95,7 +96,7 @@ public class RepaymentWithPostDatedChecksTest {
List<HashMap> postDatedChecks = new ArrayList<>(); List<HashMap> postDatedChecks = new ArrayList<>();
Gson gson = new Gson(); Gson gson = new Gson();
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
// Get the first installment date // Get the first installment date
@@ -509,7 +509,8 @@ public class SchedulerJobsTestResults {
"Verifying Loan Repayment in Advance after Running Update Loan Paid in Advance Scheduler Job"); "Verifying Loan Repayment in Advance after Running Update Loan Paid in Advance Scheduler Job");
} }
// Invalid test case as it won't affect summary (Loan summary is properly updated before running this job) // Invalid test case as it won't affect summary (Loan summary is properly
// updated before running this job)
@Disabled @Disabled
@Test @Test
public void testUpdateLoanSummaryJobOutcome() throws InterruptedException { public void testUpdateLoanSummaryJobOutcome() throws InterruptedException {
@@ -575,11 +576,12 @@ public class SchedulerJobsTestResults {
DateFormat monthDayFormat = new SimpleDateFormat("dd MMMM", Locale.US); DateFormat monthDayFormat = new SimpleDateFormat("dd MMMM", Locale.US);
Calendar todaysDate = Calendar.getInstance(); Calendar todaysDate = Calendar.getInstance();
todaysDate.add(Calendar.WEEK_OF_YEAR, -1);
final String VALID_FROM = dateFormat.format(todaysDate.getTime());
final String MONTH_DAY = monthDayFormat.format(todaysDate.getTime()); final String MONTH_DAY = monthDayFormat.format(todaysDate.getTime());
todaysDate.add(Calendar.WEEK_OF_YEAR, -1);
final String VALID_FROM = dateFormat.format(todaysDate.getTime());
todaysDate.add(Calendar.YEAR, 1); todaysDate.add(Calendar.YEAR, 1);
final String VALID_TO = dateFormat.format(todaysDate.getTime()); final String VALID_TO = dateFormat.format(todaysDate.getTime());
@@ -880,7 +882,8 @@ public class SchedulerJobsTestResults {
private Integer createSavingsProduct(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, private Integer createSavingsProduct(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final String minOpenningBalance) { final String minOpenningBalance) {
// system.out.println("------------------------------CREATING NEW SAVINGS PRODUCT // system.out.println("------------------------------CREATING NEW SAVINGS
// PRODUCT
// ---------------------------------------"); // ---------------------------------------");
SavingsProductHelper savingsProductHelper = new SavingsProductHelper(); SavingsProductHelper savingsProductHelper = new SavingsProductHelper();
final String savingsProductJSON = savingsProductHelper // final String savingsProductJSON = savingsProductHelper //
@@ -892,7 +895,8 @@ public class SchedulerJobsTestResults {
} }
private Integer createSavingsProduct(final String minOpenningBalance, final Account... accounts) { private Integer createSavingsProduct(final String minOpenningBalance, final Account... accounts) {
// system.out.println("------------------------------CREATING NEW SAVINGS PRODUCT // system.out.println("------------------------------CREATING NEW SAVINGS
// PRODUCT
// ---------------------------------------"); // ---------------------------------------");
final String savingsProductJSON = new SavingsProductHelper().withInterestCompoundingPeriodTypeAsDaily() // final String savingsProductJSON = new SavingsProductHelper().withInterestCompoundingPeriodTypeAsDaily() //
.withInterestPostingPeriodTypeAsQuarterly() // .withInterestPostingPeriodTypeAsQuarterly() //
@@ -958,7 +962,8 @@ public class SchedulerJobsTestResults {
} }
private Integer createFixedDepositProduct(final String validFrom, final String validTo) { private Integer createFixedDepositProduct(final String validFrom, final String validTo) {
// system.out.println("------------------------------CREATING NEW FIXED DEPOSIT PRODUCT // system.out.println("------------------------------CREATING NEW FIXED DEPOSIT
// PRODUCT
// ---------------------------------------"); // ---------------------------------------");
FixedDepositProductHelper fixedDepositProductHelper = new FixedDepositProductHelper(requestSpec, responseSpec); FixedDepositProductHelper fixedDepositProductHelper = new FixedDepositProductHelper(requestSpec, responseSpec);
final String fixedDepositProductJSON = fixedDepositProductHelper // final String fixedDepositProductJSON = fixedDepositProductHelper //
@@ -970,7 +975,8 @@ public class SchedulerJobsTestResults {
private Integer applyForFixedDepositApplication(final String clientID, final String productID, final String submittedOnDate, private Integer applyForFixedDepositApplication(final String clientID, final String productID, final String submittedOnDate,
final String penalInterestType, String savingsId) { final String penalInterestType, String savingsId) {
// system.out.println("--------------------------------APPLYING FOR FIXED DEPOSIT ACCOUNT // system.out.println("--------------------------------APPLYING FOR FIXED
// DEPOSIT ACCOUNT
// --------------------------------"); // --------------------------------");
final String fixedDepositApplicationJSON = new FixedDepositAccountHelper(requestSpec, responseSpec) final String fixedDepositApplicationJSON = new FixedDepositAccountHelper(requestSpec, responseSpec)
.withSubmittedOnDate(submittedOnDate).withSavings(savingsId).transferInterest(true) .withSubmittedOnDate(submittedOnDate).withSavings(savingsId).transferInterest(true)
@@ -31,6 +31,7 @@ import java.io.OutputStream;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.apache.fineract.infrastructure.bulkimport.constants.ClientEntityConstants; import org.apache.fineract.infrastructure.bulkimport.constants.ClientEntityConstants;
@@ -105,7 +106,7 @@ public class ClientEntityImportHandlerTest {
Sheet staffSheet = workbook.getSheet(TemplatePopulateImportConstants.STAFF_SHEET_NAME); Sheet staffSheet = workbook.getSheet(TemplatePopulateImportConstants.STAFF_SHEET_NAME);
firstClientRow.createCell(ClientEntityConstants.OFFICE_NAME_COL).setCellValue(staffSheet.getRow(1).getCell(0).getStringCellValue()); firstClientRow.createCell(ClientEntityConstants.OFFICE_NAME_COL).setCellValue(staffSheet.getRow(1).getCell(0).getStringCellValue());
firstClientRow.createCell(ClientEntityConstants.STAFF_NAME_COL).setCellValue(staffSheet.getRow(1).getCell(1).getStringCellValue()); firstClientRow.createCell(ClientEntityConstants.STAFF_NAME_COL).setCellValue(staffSheet.getRow(1).getCell(1).getStringCellValue());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM yyyy"); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Date incoporationDate = simpleDateFormat.parse("14 May 2001"); Date incoporationDate = simpleDateFormat.parse("14 May 2001");
firstClientRow.createCell(ClientEntityConstants.INCOPORATION_DATE_COL).setCellValue(incoporationDate); firstClientRow.createCell(ClientEntityConstants.INCOPORATION_DATE_COL).setCellValue(incoporationDate);
Date validTill = simpleDateFormat.parse("14 May 2019"); Date validTill = simpleDateFormat.parse("14 May 2019");
@@ -36,6 +36,7 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
@@ -178,7 +179,7 @@ public class LoanImportHandlerTest {
firstLoanRow.createCell(LoanConstants.CLIENT_EXTERNAL_ID).setCellValue(externalId); firstLoanRow.createCell(LoanConstants.CLIENT_EXTERNAL_ID).setCellValue(externalId);
firstLoanRow.createCell(LoanConstants.PRODUCT_COL).setCellValue(loanProductJson.getString("name")); firstLoanRow.createCell(LoanConstants.PRODUCT_COL).setCellValue(loanProductJson.getString("name"));
firstLoanRow.createCell(LoanConstants.LOAN_OFFICER_NAME_COL).setCellValue((String) staffMap.get("displayName")); firstLoanRow.createCell(LoanConstants.LOAN_OFFICER_NAME_COL).setCellValue((String) staffMap.get("displayName"));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM yyyy"); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Date date = simpleDateFormat.parse("13 May 2017"); Date date = simpleDateFormat.parse("13 May 2017");
firstLoanRow.createCell(LoanConstants.SUBMITTED_ON_DATE_COL).setCellValue(date); firstLoanRow.createCell(LoanConstants.SUBMITTED_ON_DATE_COL).setCellValue(date);
firstLoanRow.createCell(LoanConstants.APPROVED_DATE_COL).setCellValue(date); firstLoanRow.createCell(LoanConstants.APPROVED_DATE_COL).setCellValue(date);
@@ -30,6 +30,7 @@ import java.io.OutputStream;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale;
import org.apache.fineract.infrastructure.bulkimport.constants.OfficeConstants; import org.apache.fineract.infrastructure.bulkimport.constants.OfficeConstants;
import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants; import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
import org.apache.fineract.integrationtests.common.OfficeHelper; import org.apache.fineract.integrationtests.common.OfficeHelper;
@@ -72,7 +73,7 @@ public class OfficeImportHandlerTest {
.setCellValue(firstOfficeRow.getCell(OfficeConstants.LOOKUP_OFFICE_COL).getStringCellValue()); .setCellValue(firstOfficeRow.getCell(OfficeConstants.LOOKUP_OFFICE_COL).getStringCellValue());
firstOfficeRow.createCell(OfficeConstants.PARENT_OFFICE_ID_COL) firstOfficeRow.createCell(OfficeConstants.PARENT_OFFICE_ID_COL)
.setCellValue(firstOfficeRow.getCell(OfficeConstants.LOOKUP_OFFICE_ID_COL).getNumericCellValue()); .setCellValue(firstOfficeRow.getCell(OfficeConstants.LOOKUP_OFFICE_ID_COL).getNumericCellValue());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM yyyy"); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Date date = simpleDateFormat.parse("14 May 2001"); Date date = simpleDateFormat.parse("14 May 2001");
firstOfficeRow.createCell(OfficeConstants.OPENED_ON_COL).setCellValue(date); firstOfficeRow.createCell(OfficeConstants.OPENED_ON_COL).setCellValue(date);
@@ -33,6 +33,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
@@ -134,7 +135,7 @@ public class SavingsImportHandlerTest {
firstSavingsRow.createCell(SavingsConstants.PRODUCT_COL) firstSavingsRow.createCell(SavingsConstants.PRODUCT_COL)
.setCellValue(savingsProductSheet.getRow(1).getCell(1).getStringCellValue()); .setCellValue(savingsProductSheet.getRow(1).getCell(1).getStringCellValue());
firstSavingsRow.createCell(SavingsConstants.FIELD_OFFICER_NAME_COL).setCellValue((String) staffMap.get("displayName")); firstSavingsRow.createCell(SavingsConstants.FIELD_OFFICER_NAME_COL).setCellValue((String) staffMap.get("displayName"));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM yyyy"); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
Date date = simpleDateFormat.parse("13 May 2017"); Date date = simpleDateFormat.parse("13 May 2017");
firstSavingsRow.createCell(SavingsConstants.SUBMITTED_ON_DATE_COL).setCellValue(date); firstSavingsRow.createCell(SavingsConstants.SUBMITTED_ON_DATE_COL).setCellValue(date);
firstSavingsRow.createCell(SavingsConstants.APPROVED_DATE_COL).setCellValue(date); firstSavingsRow.createCell(SavingsConstants.APPROVED_DATE_COL).setCellValue(date);
@@ -26,6 +26,7 @@ import io.restassured.specification.ResponseSpecification;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.Locale;
import org.apache.fineract.integrationtests.common.charges.ChargesHelper; import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@@ -102,7 +103,7 @@ public class ClientChargesTest {
* Now pay client charge for 20 USD and ensure the outstanding amount is updated properly * Now pay client charge for 20 USD and ensure the outstanding amount is updated properly
*/ */
ResponseSpecification responseSpecFailure = new ResponseSpecBuilder().expectStatusCode(400).build(); ResponseSpecification responseSpecFailure = new ResponseSpecBuilder().expectStatusCode(400).build();
DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
dateFormat.setTimeZone(Utils.getTimeZoneOfTenant()); dateFormat.setTimeZone(Utils.getTimeZoneOfTenant());
Calendar today = Calendar.getInstance(Utils.getTimeZoneOfTenant()); Calendar today = Calendar.getInstance(Utils.getTimeZoneOfTenant());
today.add(Calendar.DAY_OF_MONTH, 2); today.add(Calendar.DAY_OF_MONTH, 2);
@@ -33,6 +33,7 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.integrationtests.common.accounting.Account; import org.apache.fineract.integrationtests.common.accounting.Account;
@@ -258,7 +259,7 @@ public class ProvisioningIntegrationTest {
String date = (String) item.get("createdDate"); String date = (String) item.get("createdDate");
DateFormat formatter = new SimpleDateFormat("MMM dd, yyyy"); DateFormat formatter = new SimpleDateFormat("MMM dd, yyyy");
Date date1 = formatter.parse(date); Date date1 = formatter.parse(date);
DateFormat simple = new SimpleDateFormat("dd MMMM yyyy"); DateFormat simple = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
String formattedString = simple String formattedString = simple
.format(Date.from(Utils.getLocalDateOfTenant().atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant())); .format(Date.from(Utils.getLocalDateOfTenant().atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant()));
Date currentDate = simple.parse(formattedString); Date currentDate = simple.parse(formattedString);
@@ -124,6 +124,12 @@ public class LoanTransactionHelper {
return (ArrayList) Utils.performServerGet(requestSpec, responseSpec, URL, "charges"); return (ArrayList) Utils.performServerGet(requestSpec, responseSpec, URL, "charges");
} }
public ArrayList getLoanTransactions(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer loanID) {
final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?associations=transactions&" + Utils.TENANT_IDENTIFIER;
return (ArrayList) Utils.performServerGet(requestSpec, responseSpec, URL, "transactions");
}
public ArrayList getLoanFutureRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public ArrayList getLoanFutureRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final Integer loanID) { final Integer loanID) {
final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule,futureSchedule&" final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule,futureSchedule&"
@@ -133,7 +139,7 @@ public class LoanTransactionHelper {
} }
public HashMap getLoanSummary(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final Integer loanID) { public HashMap getLoanSummary(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final Integer loanID) {
final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?associations=all&" + Utils.TENANT_IDENTIFIER; final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?" + Utils.TENANT_IDENTIFIER;
final HashMap response = Utils.performServerGet(requestSpec, responseSpec, URL, "summary"); final HashMap response = Utils.performServerGet(requestSpec, responseSpec, URL, "summary");
return response; return response;
} }
@@ -731,7 +737,7 @@ public class LoanTransactionHelper {
public void checkAccrualTransactionForRepayment(final LocalDate transactionDate, final Float interestPortion, final Float feePortion, public void checkAccrualTransactionForRepayment(final LocalDate transactionDate, final Float interestPortion, final Float feePortion,
final Float penaltyPortion, final Integer loanID) { final Float penaltyPortion, final Integer loanID) {
ArrayList<HashMap> transactions = (ArrayList<HashMap>) getLoanDetail(this.requestSpec, this.responseSpec, loanID, "transactions"); ArrayList<HashMap> transactions = (ArrayList<HashMap>) getLoanTransactions(this.requestSpec, this.responseSpec, loanID);
boolean isTransactionFound = false; boolean isTransactionFound = false;
for (int i = 0; i < transactions.size(); i++) { for (int i = 0; i < transactions.size(); i++) {
HashMap transactionType = (HashMap) transactions.get(i).get("type"); HashMap transactionType = (HashMap) transactions.get(i).get("type");
@@ -26,6 +26,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.integrationtests.common.Utils; import org.apache.fineract.integrationtests.common.Utils;
@@ -46,7 +47,7 @@ public final class ProvisioningHelper {
final HashMap<String, Object> map = new HashMap<>(); final HashMap<String, Object> map = new HashMap<>();
map.put("loanProducts", addLoanProducts(loanProducts)); map.put("loanProducts", addLoanProducts(loanProducts));
map.put("definitions", addProvisioningCategories(categories, liability, expense)); map.put("definitions", addProvisioningCategories(categories, liability, expense));
DateFormat simple = new SimpleDateFormat("dd MMMM yyyy"); DateFormat simple = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
String formattedString = simple String formattedString = simple
.format(Date.from(Utils.getLocalDateOfTenant().atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant())); .format(Date.from(Utils.getLocalDateOfTenant().atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant()));
@@ -61,7 +62,7 @@ public final class ProvisioningHelper {
map.put("createjournalentries", Boolean.FALSE); map.put("createjournalentries", Boolean.FALSE);
map.put("locale", "en"); map.put("locale", "en");
map.put("dateFormat", "dd MMMM yyyy"); map.put("dateFormat", "dd MMMM yyyy");
DateFormat simple = new SimpleDateFormat("dd MMMM yyyy"); DateFormat simple = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
map.put("date", map.put("date",
simple.format(Date.from(Utils.getLocalDateOfTenant().atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant()))); simple.format(Date.from(Utils.getLocalDateOfTenant().atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant())));
String provisioningEntryCreateJson = new Gson().toJson(map); String provisioningEntryCreateJson = new Gson().toJson(map);
@@ -73,7 +74,7 @@ public final class ProvisioningHelper {
map.put("createjournalentries", Boolean.TRUE); map.put("createjournalentries", Boolean.TRUE);
map.put("locale", "en"); map.put("locale", "en");
map.put("dateFormat", "dd MMMM yyyy"); map.put("dateFormat", "dd MMMM yyyy");
DateFormat simple = new SimpleDateFormat("dd MMMM yyyy"); DateFormat simple = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
map.put("date", map.put("date",
simple.format(Date.from(Utils.getLocalDateOfTenant().atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant()))); simple.format(Date.from(Utils.getLocalDateOfTenant().atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant())));
String provisioningEntryCreateJson = new Gson().toJson(map); String provisioningEntryCreateJson = new Gson().toJson(map);
@@ -250,12 +250,8 @@ public class ShareAccountIntegrationTests {
Assertions.assertEquals("shareAccountStatusType.rejected", String.valueOf(statusMap.get("code"))); Assertions.assertEquals("shareAccountStatusType.rejected", String.valueOf(statusMap.get("code")));
Map<String, Object> timelineMap = (Map<String, Object>) shareAccountData.get("timeline"); Map<String, Object> timelineMap = (Map<String, Object>) shareAccountData.get("timeline");
List<Integer> dateList = (List<Integer>) timelineMap.get("rejectedDate"); List<Integer> dateList = (List<Integer>) timelineMap.get("rejectedDate");
Calendar cal = Calendar.getInstance(); Date rejectedDate = DateUtils.createDate(dateList.get(0), dateList.get(1), dateList.get(2));
cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); Assertions.assertEquals(simple.format(DateUtils.convertLocalDateToDate(Utils.getLocalDateOfTenant())), simple.format(rejectedDate));
Date rejectedDate = cal.getTime();
Assertions.assertEquals(
simple.format(Date.from(Utils.getLocalDateOfTenant().atStartOfDay(DateUtils.getDateTimeZoneOfTenant()).toInstant())),
simple.format(rejectedDate));
List<Map<String, Object>> transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares"); List<Map<String, Object>> transactions = (List<Map<String, Object>>) shareAccountData.get("purchasedShares");
Assertions.assertNotNull(transactions); Assertions.assertNotNull(transactions);
@@ -264,9 +260,7 @@ public class ShareAccountIntegrationTests {
Map<String, Object> transaction = transactions.get(i); Map<String, Object> transaction = transactions.get(i);
Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type"); Map<String, Object> transactionTypeMap = (Map<String, Object>) transaction.get("type");
dateList = (List<Integer>) transaction.get("purchasedDate"); dateList = (List<Integer>) transaction.get("purchasedDate");
cal = Calendar.getInstance(); Date date = DateUtils.createDate(dateList.get(0), dateList.get(1), dateList.get(2));
cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2));
Date date = cal.getTime();
String transactionType = (String) transactionTypeMap.get("code"); String transactionType = (String) transactionTypeMap.get("code");
if (transactionType.equals("purchasedSharesType.purchased")) { if (transactionType.equals("purchasedSharesType.purchased")) {
Assertions.assertEquals("25", String.valueOf(transaction.get("numberOfShares"))); Assertions.assertEquals("25", String.valueOf(transaction.get("numberOfShares")));
@@ -25,6 +25,7 @@ import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.integrationtests.common.Utils; import org.apache.fineract.integrationtests.common.Utils;
@@ -107,7 +108,7 @@ public class ShareProductHelper {
this.marketPrices = new ArrayList<>(); this.marketPrices = new ArrayList<>();
LocalDate currentDate = DateUtils.getLocalDateOfTenant(); LocalDate currentDate = DateUtils.getLocalDateOfTenant();
String[] prices = { "3.0", "4.0", "5.0", "6.0", "7.0" }; String[] prices = { "3.0", "4.0", "5.0", "6.0", "7.0" };
DateFormat simple = new SimpleDateFormat("dd MMMM yyyy"); DateFormat simple = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
for (int i = 0; i < prices.length; i++) { for (int i = 0; i < prices.length; i++) {
currentDate = currentDate.plusMonths(2); currentDate = currentDate.plusMonths(2);
Map<String, String> marketPrice = new HashMap<>(); Map<String, String> marketPrice = new HashMap<>();
@@ -26,6 +26,7 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.apache.fineract.integrationtests.common.accounting.Account; import org.apache.fineract.integrationtests.common.accounting.Account;
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder; import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
@@ -297,7 +298,7 @@ public class VariableInstallmentsDecliningBalanceHelper {
cal.set(Calendar.MONTH, (int) list.get(1) - 1); cal.set(Calendar.MONTH, (int) list.get(1) - 1);
cal.set(Calendar.DAY_OF_MONTH, (int) list.get(2)); cal.set(Calendar.DAY_OF_MONTH, (int) list.get(2));
Date date = cal.getTime(); Date date = cal.getTime();
DateFormat requiredFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat requiredFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
return requiredFormat.format(date); return requiredFormat.format(date);
} }
@@ -26,6 +26,7 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.apache.fineract.integrationtests.common.accounting.Account; import org.apache.fineract.integrationtests.common.accounting.Account;
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder; import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
@@ -208,7 +209,7 @@ public class VariableInstallmentsFlatHelper {
cal.set(Calendar.MONTH, (int) list.get(1) - 1); cal.set(Calendar.MONTH, (int) list.get(1) - 1);
cal.set(Calendar.DAY_OF_MONTH, (int) list.get(2)); cal.set(Calendar.DAY_OF_MONTH, (int) list.get(2));
Date date = cal.getTime(); Date date = cal.getTime();
DateFormat requiredFormat = new SimpleDateFormat("dd MMMM yyyy"); DateFormat requiredFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.US);
return requiredFormat.format(date); return requiredFormat.format(date);
} }