+1
-1
@@ -69,7 +69,7 @@ public final class AccrualAccountingDataValidator {
|
|||||||
.resource(PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME);
|
.resource(PERIODIC_ACCRUAL_ACCOUNTING_RESOURCE_NAME);
|
||||||
|
|
||||||
final LocalDate date = this.fromApiJsonHelper.extractLocalDateNamed(accrueTillParamName, element);
|
final LocalDate date = this.fromApiJsonHelper.extractLocalDateNamed(accrueTillParamName, element);
|
||||||
baseDataValidator.reset().parameter(accrueTillParamName).value(date).notNull().validateDateBefore(DateUtils.getLocalDateOfTenant());
|
baseDataValidator.reset().parameter(accrueTillParamName).value(date).notNull().validateDateBefore(DateUtils.getBusinessLocalDate());
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -67,7 +67,7 @@ public class GLClosureWritePlatformServiceJpaRepositoryImpl implements GLClosure
|
|||||||
final Office office = this.officeRepositoryWrapper.findOneWithNotFoundDetection(officeId);
|
final Office office = this.officeRepositoryWrapper.findOneWithNotFoundDetection(officeId);
|
||||||
// TODO: Get Tenant specific date
|
// TODO: Get Tenant specific date
|
||||||
// ensure closure date is not in the future
|
// ensure closure date is not in the future
|
||||||
final Date todaysDate = new Date();
|
final Date todaysDate = DateUtils.getBusinessDate();
|
||||||
final Date closureDate = command.dateValueOfParameterNamed(GLClosureJsonInputParams.CLOSING_DATE.getValue());
|
final Date closureDate = command.dateValueOfParameterNamed(GLClosureJsonInputParams.CLOSING_DATE.getValue());
|
||||||
if (closureDate.after(todaysDate)) {
|
if (closureDate.after(todaysDate)) {
|
||||||
throw new GLClosureInvalidException(GlClosureInvalidReason.FUTURE_DATE, closureDate);
|
throw new GLClosureInvalidException(GlClosureInvalidReason.FUTURE_DATE, closureDate);
|
||||||
|
|||||||
+1
-1
@@ -427,7 +427,7 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
final OfficeOpeningBalancesData officeOpeningBalancesData = OfficeOpeningBalancesData.createNew(officeId, officeData.name(),
|
final OfficeOpeningBalancesData officeOpeningBalancesData = OfficeOpeningBalancesData.createNew(officeId, officeData.name(),
|
||||||
transactionDate, contraAccount, assetAccountOpeningBalances, liabityAccountOpeningBalances, incomeAccountOpeningBalances,
|
transactionDate, contraAccount, assetAccountOpeningBalances, liabityAccountOpeningBalances, incomeAccountOpeningBalances,
|
||||||
|
|||||||
+2
-1
@@ -72,6 +72,7 @@ import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
|
|||||||
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.apache.fineract.organisation.office.domain.Office;
|
import org.apache.fineract.organisation.office.domain.Office;
|
||||||
import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
|
import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
|
||||||
@@ -562,7 +563,7 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
|
|||||||
final LocalDate entryLocalDate = command.getTransactionDate();
|
final LocalDate entryLocalDate = command.getTransactionDate();
|
||||||
final Date transactionDate = Date.from(entryLocalDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
final Date transactionDate = Date.from(entryLocalDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||||
// shouldn't be in the future
|
// shouldn't be in the future
|
||||||
final Date todaysDate = new Date();
|
final Date todaysDate = DateUtils.getBusinessDate();
|
||||||
if (transactionDate.after(todaysDate)) {
|
if (transactionDate.after(todaysDate)) {
|
||||||
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.FUTURE_DATE, transactionDate, null, null);
|
throw new JournalEntryInvalidException(GlJournalEntryInvalidReason.FUTURE_DATE, transactionDate, null, null);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -65,7 +65,7 @@ public class ProvisioningEntriesDefinitionJsonDeserializer implements Provisioni
|
|||||||
baseDataValidator.reset().parameter(JSON_DATEFORMAT_PARAM).value(dateformat).notBlank();
|
baseDataValidator.reset().parameter(JSON_DATEFORMAT_PARAM).value(dateformat).notBlank();
|
||||||
LocalDate localDate = this.fromApiJsonHelper.extractLocalDateNamed(JSON_DATE_PARAM, element);
|
LocalDate localDate = this.fromApiJsonHelper.extractLocalDateNamed(JSON_DATE_PARAM, element);
|
||||||
baseDataValidator.reset().parameter(JSON_DATE_PARAM).value(localDate).notBlank();
|
baseDataValidator.reset().parameter(JSON_DATE_PARAM).value(localDate).notBlank();
|
||||||
baseDataValidator.reset().parameter(JSON_DATE_PARAM).value(localDate).validateDateBeforeOrEqual(DateUtils.getLocalDateOfTenant());
|
baseDataValidator.reset().parameter(JSON_DATE_PARAM).value(localDate).validateDateBeforeOrEqual(DateUtils.getBusinessLocalDate());
|
||||||
if (this.fromApiJsonHelper.parameterExists(JSON_CREATEJOURNALENTRIES_PARAM, element)) {
|
if (this.fromApiJsonHelper.parameterExists(JSON_CREATEJOURNALENTRIES_PARAM, element)) {
|
||||||
Boolean bool = this.fromApiJsonHelper.extractBooleanNamed(JSON_CREATEJOURNALENTRIES_PARAM, element);
|
Boolean bool = this.fromApiJsonHelper.extractBooleanNamed(JSON_CREATEJOURNALENTRIES_PARAM, element);
|
||||||
baseDataValidator.reset().parameter(JSON_CREATEJOURNALENTRIES_PARAM).value(bool).validateForBooleanValue();
|
baseDataValidator.reset().parameter(JSON_CREATEJOURNALENTRIES_PARAM).value(bool).validateForBooleanValue();
|
||||||
|
|||||||
+1
-1
@@ -135,7 +135,7 @@ public class ProvisioningEntriesWritePlatformServiceJpaRepositoryImpl implements
|
|||||||
@Override
|
@Override
|
||||||
@CronTarget(jobName = JobName.GENERATE_LOANLOSS_PROVISIONING)
|
@CronTarget(jobName = JobName.GENERATE_LOANLOSS_PROVISIONING)
|
||||||
public void generateLoanLossProvisioningAmount() {
|
public void generateLoanLossProvisioningAmount() {
|
||||||
Date currentDate = Date.from(DateUtils.getLocalDateOfTenant().atStartOfDay(ZoneId.systemDefault()).toInstant());
|
Date currentDate = DateUtils.getBusinessDate();
|
||||||
boolean addJournalEntries = true;
|
boolean addJournalEntries = true;
|
||||||
try {
|
try {
|
||||||
Collection<ProvisioningCriteriaData> criteriaCollection = this.provisioningCriteriaReadPlatformService
|
Collection<ProvisioningCriteriaData> criteriaCollection = this.provisioningCriteriaReadPlatformService
|
||||||
|
|||||||
+11
-16
@@ -22,33 +22,27 @@ import java.time.LocalDate;
|
|||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.fineract.adhocquery.data.AdHocData;
|
import org.apache.fineract.adhocquery.data.AdHocData;
|
||||||
import org.apache.fineract.adhocquery.domain.ReportRunFrequency;
|
import org.apache.fineract.adhocquery.domain.ReportRunFrequency;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||||
import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
|
import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
|
||||||
import org.apache.fineract.infrastructure.jobs.service.JobName;
|
import org.apache.fineract.infrastructure.jobs.service.JobName;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@Service(value = "adHocScheduledJobRunnerService")
|
@Service(value = "adHocScheduledJobRunnerService")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
public class AdHocScheduledJobRunnerServiceImpl implements AdHocScheduledJobRunnerService {
|
public class AdHocScheduledJobRunnerServiceImpl implements AdHocScheduledJobRunnerService {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AdHocScheduledJobRunnerServiceImpl.class);
|
|
||||||
private final AdHocReadPlatformService adHocReadPlatformService;
|
private final AdHocReadPlatformService adHocReadPlatformService;
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||||
@Autowired
|
|
||||||
public AdHocScheduledJobRunnerServiceImpl(final JdbcTemplate jdbcTemplate, final AdHocReadPlatformService adHocReadPlatformService) {
|
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
|
||||||
this.adHocReadPlatformService = adHocReadPlatformService;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
@@ -99,18 +93,19 @@ public class AdHocScheduledJobRunnerServiceImpl implements AdHocScheduledJobRunn
|
|||||||
.append(adhoc.getQuery());
|
.append(adhoc.getQuery());
|
||||||
if (insertSqlBuilder.length() > 0) {
|
if (insertSqlBuilder.length() > 0) {
|
||||||
final int result = this.jdbcTemplate.update(insertSqlBuilder.toString());
|
final int result = this.jdbcTemplate.update(insertSqlBuilder.toString());
|
||||||
LOG.info("{}: Records affected by generateClientSchedule: {}", ThreadLocalContextUtil.getTenant().getName(),
|
log.info("{}: Records affected by generateClientSchedule: {}", ThreadLocalContextUtil.getTenant().getName(),
|
||||||
result);
|
result);
|
||||||
|
|
||||||
this.jdbcTemplate.update("UPDATE m_adhoc SET last_run=? WHERE id=?", new Date(), adhoc.getId());
|
this.jdbcTemplate.update("UPDATE m_adhoc SET last_run=? WHERE id=?", DateUtils.getLocalDateTimeOfTenant(),
|
||||||
|
adhoc.getId());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG.info("{}: Skipping execution of {}, scheduled for execution on {}",
|
log.info("{}: Skipping execution of {}, scheduled for execution on {}",
|
||||||
new Object[] { ThreadLocalContextUtil.getTenant().getName(), adhoc.getName(), next });
|
new Object[] { ThreadLocalContextUtil.getTenant().getName(), adhoc.getName(), next });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
LOG.info("{}: Nothing to update by generateClientSchedule", ThreadLocalContextUtil.getTenant().getName());
|
log.info("{}: Nothing to update by generateClientSchedule", ThreadLocalContextUtil.getTenant().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -222,15 +222,15 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
|||||||
private void publishEvent(final String entityName, final String actionName, JsonCommand command, final Object result) {
|
private void publishEvent(final String entityName, final String actionName, JsonCommand command, final Object result) {
|
||||||
Gson gson = new Gson();
|
Gson gson = new Gson();
|
||||||
try {
|
try {
|
||||||
final String authToken = ThreadLocalContextUtil.getAuthToken();
|
|
||||||
final String tenantIdentifier = ThreadLocalContextUtil.getTenant().getTenantIdentifier();
|
|
||||||
final AppUser appUser = this.context.authenticatedUser(CommandWrapper.wrap(actionName, entityName, null, null));
|
final AppUser appUser = this.context.authenticatedUser(CommandWrapper.wrap(actionName, entityName, null, null));
|
||||||
|
|
||||||
final HookEventSource hookEventSource = new HookEventSource(entityName, actionName);
|
final HookEventSource hookEventSource = new HookEventSource(entityName, actionName);
|
||||||
|
|
||||||
// TODO: Add support for publishing array events
|
// TODO: Add support for publishing array events
|
||||||
if (command.json() != null && command.json().startsWith("{")) {
|
if (command.json() != null && command.json().startsWith("{")) {
|
||||||
Type type = new TypeToken<Map<String, Object>>() {}.getType();
|
Type type = new TypeToken<Map<String, Object>>() {
|
||||||
|
|
||||||
|
}.getType();
|
||||||
Map<String, Object> myMap = gson.fromJson(command.json(), type);
|
Map<String, Object> myMap = gson.fromJson(command.json(), type);
|
||||||
|
|
||||||
Map<String, Object> reqmap = new HashMap<>();
|
Map<String, Object> reqmap = new HashMap<>();
|
||||||
@@ -264,7 +264,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
|||||||
|
|
||||||
final String serializedResult = this.toApiResultJsonSerializer.serialize(reqmap);
|
final String serializedResult = this.toApiResultJsonSerializer.serialize(reqmap);
|
||||||
|
|
||||||
final HookEvent applicationEvent = new HookEvent(hookEventSource, serializedResult, tenantIdentifier, appUser, authToken);
|
final HookEvent applicationEvent = new HookEvent(hookEventSource, serializedResult, appUser,
|
||||||
|
ThreadLocalContextUtil.getContext());
|
||||||
|
|
||||||
applicationContext.publishEvent(applicationEvent);
|
applicationContext.publishEvent(applicationEvent);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-15
@@ -18,12 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.bulkimport.data;
|
package org.apache.fineract.infrastructure.bulkimport.data;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractContext;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractEvent;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
import org.springframework.context.ApplicationEvent;
|
|
||||||
|
|
||||||
public final class BulkImportEvent extends ApplicationEvent {
|
public final class BulkImportEvent extends FineractEvent {
|
||||||
|
|
||||||
private final String tenantIdentifier;
|
|
||||||
|
|
||||||
private final Workbook workbook;
|
private final Workbook workbook;
|
||||||
|
|
||||||
@@ -33,23 +32,18 @@ public final class BulkImportEvent extends ApplicationEvent {
|
|||||||
|
|
||||||
private final String dateFormat;
|
private final String dateFormat;
|
||||||
|
|
||||||
private BulkImportEvent(final String tenantIdentifier, final Workbook workbook, final Long importId, final String locale,
|
private BulkImportEvent(final Object source, final Workbook workbook, final Long importId, final String locale, final String dateFormat,
|
||||||
final String dateFormat) {
|
FineractContext context) {
|
||||||
super(BulkImportEvent.class);
|
super(source, context);
|
||||||
this.tenantIdentifier = tenantIdentifier;
|
|
||||||
this.workbook = workbook;
|
this.workbook = workbook;
|
||||||
this.importId = importId;
|
this.importId = importId;
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
this.dateFormat = dateFormat;
|
this.dateFormat = dateFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BulkImportEvent instance(final String tenantIdentifier, final Workbook workbook, final Long importId, final String locale,
|
public static BulkImportEvent instance(final Object source, final Workbook workbook, final Long importId, final String locale,
|
||||||
final String dateFormat) {
|
final String dateFormat, FineractContext context) {
|
||||||
return new BulkImportEvent(tenantIdentifier, workbook, importId, locale, dateFormat);
|
return new BulkImportEvent(source, workbook, importId, locale, dateFormat, context);
|
||||||
}
|
|
||||||
|
|
||||||
public String getTenantIdentifier() {
|
|
||||||
return tenantIdentifier;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Workbook getWorkbook() {
|
public Workbook getWorkbook() {
|
||||||
|
|||||||
+2
-5
@@ -21,7 +21,6 @@ package org.apache.fineract.infrastructure.bulkimport.importhandler.chartofaccou
|
|||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
|
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
|
||||||
@@ -47,6 +46,7 @@ import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
|||||||
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
|
import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
import org.apache.poi.ss.usermodel.IndexedColors;
|
import org.apache.poi.ss.usermodel.IndexedColors;
|
||||||
@@ -234,10 +234,7 @@ public class ChartOfAccountsImportHandler implements ImportHandler {
|
|||||||
|
|
||||||
// for opening balance
|
// for opening balance
|
||||||
private JournalEntryData readAddJournalEntries(Row row, String locale, String dateFormat) {
|
private JournalEntryData readAddJournalEntries(Row row, String locale, String dateFormat) {
|
||||||
LocalDate transactionDateCheck = LocalDate.now(ZoneId.systemDefault());
|
transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
if (transactionDateCheck != null) {
|
|
||||||
transactionDate = transactionDateCheck;
|
|
||||||
}
|
|
||||||
|
|
||||||
String officeName = ImportHandlerUtils.readAsString(ChartOfAcountsConstants.OFFICE_COL, row);
|
String officeName = ImportHandlerUtils.readAsString(ChartOfAcountsConstants.OFFICE_COL, row);
|
||||||
Long officeId = ImportHandlerUtils.readAsLong(ChartOfAcountsConstants.OFFICE_COL_ID, row);
|
Long officeId = ImportHandlerUtils.readAsLong(ChartOfAcountsConstants.OFFICE_COL_ID, row);
|
||||||
|
|||||||
+1
-1
@@ -99,7 +99,7 @@ public class SharedProductsSheetPopulator extends AbstractWorkbookPopulator {
|
|||||||
BigDecimal marketValue = shareProductData.getUnitPrice();
|
BigDecimal marketValue = shareProductData.getUnitPrice();
|
||||||
Collection<ShareProductMarketPriceData> marketDataSet = shareProductData.getMarketPrice();
|
Collection<ShareProductMarketPriceData> marketDataSet = shareProductData.getMarketPrice();
|
||||||
if (marketDataSet != null && !marketDataSet.isEmpty()) {
|
if (marketDataSet != null && !marketDataSet.isEmpty()) {
|
||||||
Date currentDate = DateUtils.getDateOfTenant();
|
Date currentDate = DateUtils.getBusinessDate();
|
||||||
for (ShareProductMarketPriceData data : marketDataSet) {
|
for (ShareProductMarketPriceData data : marketDataSet) {
|
||||||
Date futureDate = data.getStartDate();
|
Date futureDate = data.getStartDate();
|
||||||
if (currentDate.after(futureDate)) {
|
if (currentDate.after(futureDate)) {
|
||||||
|
|||||||
+1
-5
@@ -30,7 +30,6 @@ import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
|
|||||||
import org.apache.fineract.infrastructure.bulkimport.domain.ImportDocument;
|
import org.apache.fineract.infrastructure.bulkimport.domain.ImportDocument;
|
||||||
import org.apache.fineract.infrastructure.bulkimport.domain.ImportDocumentRepository;
|
import org.apache.fineract.infrastructure.bulkimport.domain.ImportDocumentRepository;
|
||||||
import org.apache.fineract.infrastructure.bulkimport.importhandler.ImportHandler;
|
import org.apache.fineract.infrastructure.bulkimport.importhandler.ImportHandler;
|
||||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
|
||||||
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
@@ -66,10 +65,7 @@ public class BulkImportEventListener implements ApplicationListener<BulkImportEv
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onApplicationEvent(final BulkImportEvent event) {
|
public void onApplicationEvent(final BulkImportEvent event) {
|
||||||
|
ThreadLocalContextUtil.init(event.getContext());
|
||||||
final String tenantIdentifier = event.getTenantIdentifier();
|
|
||||||
final FineractPlatformTenant tenant = this.tenantDetailsService.loadTenantById(tenantIdentifier);
|
|
||||||
ThreadLocalContextUtil.setTenant(tenant);
|
|
||||||
ImportHandler importHandler = null;
|
ImportHandler importHandler = null;
|
||||||
final ImportDocument importDocument = this.importRepository.findById(event.getImportId()).orElse(null);
|
final ImportDocument importDocument = this.importRepository.findById(event.getImportId()).orElse(null);
|
||||||
final GlobalEntityType entityType = GlobalEntityType.fromInt(importDocument.getEntityType());
|
final GlobalEntityType entityType = GlobalEntityType.fromInt(importDocument.getEntityType());
|
||||||
|
|||||||
+1
-1
@@ -251,7 +251,7 @@ public class BulkImportWorkbookPopulatorServiceImpl implements BulkImportWorkboo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Response buildResponse(final Workbook workbook, final String entity) {
|
private Response buildResponse(final Workbook workbook, final String entity) {
|
||||||
String filename = entity + DateUtils.getLocalDateOfTenant().toString() + ".xls";
|
String filename = entity + DateUtils.getBusinessLocalDate().toString() + ".xls";
|
||||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
try {
|
try {
|
||||||
workbook.write(baos);
|
workbook.write(baos);
|
||||||
|
|||||||
+2
-2
@@ -195,8 +195,8 @@ public class BulkImportWorkbookServiceImpl implements BulkImportWorkbookService
|
|||||||
final ImportDocument importDocument = ImportDocument.instance(document, DateUtils.getLocalDateTimeOfTenant(), entityType.getValue(),
|
final ImportDocument importDocument = ImportDocument.instance(document, DateUtils.getLocalDateTimeOfTenant(), entityType.getValue(),
|
||||||
this.securityContext.authenticatedUser(), ImportHandlerUtils.getNumberOfRows(workbook.getSheetAt(0), primaryColumn));
|
this.securityContext.authenticatedUser(), ImportHandlerUtils.getNumberOfRows(workbook.getSheetAt(0), primaryColumn));
|
||||||
this.importDocumentRepository.saveAndFlush(importDocument);
|
this.importDocumentRepository.saveAndFlush(importDocument);
|
||||||
BulkImportEvent event = BulkImportEvent.instance(ThreadLocalContextUtil.getTenant().getTenantIdentifier(), workbook,
|
BulkImportEvent event = BulkImportEvent.instance(this, workbook, importDocument.getId(), locale, dateFormat,
|
||||||
importDocument.getId(), locale, dateFormat);
|
ThreadLocalContextUtil.getContext());
|
||||||
applicationContext.publishEvent(event);
|
applicationContext.publishEvent(event);
|
||||||
return importDocument.getId();
|
return importDocument.getId();
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -18,12 +18,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.businessdate.service;
|
package org.apache.fineract.infrastructure.businessdate.service;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
|
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
|
|
||||||
public interface BusinessDateReadPlatformService {
|
public interface BusinessDateReadPlatformService {
|
||||||
|
|
||||||
List<BusinessDateData> findAll();
|
List<BusinessDateData> findAll();
|
||||||
|
|
||||||
BusinessDateData findByType(String type);
|
BusinessDateData findByType(String type);
|
||||||
|
|
||||||
|
HashMap<BusinessDateType, LocalDate> getBusinessDates();
|
||||||
}
|
}
|
||||||
|
|||||||
+22
@@ -18,6 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.businessdate.service;
|
package org.apache.fineract.infrastructure.businessdate.service;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@@ -28,6 +31,8 @@ import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateReposi
|
|||||||
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
import org.apache.fineract.infrastructure.businessdate.exception.BusinessDateNotFoundException;
|
import org.apache.fineract.infrastructure.businessdate.exception.BusinessDateNotFoundException;
|
||||||
import org.apache.fineract.infrastructure.businessdate.mapper.BusinessDateMapper;
|
import org.apache.fineract.infrastructure.businessdate.mapper.BusinessDateMapper;
|
||||||
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -37,6 +42,7 @@ public class BusinessDateReadPlatformServiceImpl implements BusinessDateReadPlat
|
|||||||
|
|
||||||
private final BusinessDateRepository repository;
|
private final BusinessDateRepository repository;
|
||||||
private final BusinessDateMapper mapper;
|
private final BusinessDateMapper mapper;
|
||||||
|
private final ConfigurationDomainService configurationDomainService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<BusinessDateData> findAll() {
|
public List<BusinessDateData> findAll() {
|
||||||
@@ -60,4 +66,20 @@ public class BusinessDateReadPlatformServiceImpl implements BusinessDateReadPlat
|
|||||||
}
|
}
|
||||||
return mapper.map(businessDate.get());
|
return mapper.map(businessDate.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HashMap<BusinessDateType, LocalDate> getBusinessDates() {
|
||||||
|
HashMap<BusinessDateType, LocalDate> businessDateMap = new HashMap<>();
|
||||||
|
ZoneId zone = DateUtils.getDateTimeZoneOfTenant();
|
||||||
|
LocalDate tenantDate = LocalDate.now(zone);
|
||||||
|
businessDateMap.put(BusinessDateType.BUSINESS_DATE, tenantDate);
|
||||||
|
if (configurationDomainService.isBusinessDateEnabled()) {
|
||||||
|
final List<BusinessDateData> businessDateDataList = this.findAll();
|
||||||
|
for (BusinessDateData businessDateData : businessDateDataList) {
|
||||||
|
businessDateMap.put(BusinessDateType.valueOf(businessDateData.getType()), businessDateData.getDate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return businessDateMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -95,6 +95,7 @@ public class BusinessDateWritePlatformServiceImpl implements BusinessDateWritePl
|
|||||||
List<Throwable> exceptions = new ArrayList<>();
|
List<Throwable> exceptions = new ArrayList<>();
|
||||||
Map<String, Object> changes = new HashMap<>();
|
Map<String, Object> changes = new HashMap<>();
|
||||||
Optional<BusinessDate> businessDateEntity = repository.findByType(businessDateType);
|
Optional<BusinessDate> businessDateEntity = repository.findByType(businessDateType);
|
||||||
|
|
||||||
LocalDate businessDate = businessDateEntity.map(BusinessDate::getDate).orElse(DateUtils.getLocalDateOfTenant());
|
LocalDate businessDate = businessDateEntity.map(BusinessDate::getDate).orElse(DateUtils.getLocalDateOfTenant());
|
||||||
businessDate = businessDate.plusDays(1);
|
businessDate = businessDate.plusDays(1);
|
||||||
try {
|
try {
|
||||||
|
|||||||
+2
-2
@@ -185,7 +185,7 @@ public class EmailCampaign extends AbstractPersistableCustom {
|
|||||||
} else {
|
} else {
|
||||||
emailAttachmentFileFormat = ScheduledEmailAttachmentFileFormat.instance(2);
|
emailAttachmentFileFormat = ScheduledEmailAttachmentFileFormat.instance(2);
|
||||||
}
|
}
|
||||||
LocalDate submittedOnDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
|
||||||
if (command.hasParameter(EmailCampaignValidator.submittedOnDateParamName)) {
|
if (command.hasParameter(EmailCampaignValidator.submittedOnDateParamName)) {
|
||||||
submittedOnDate = command.localDateValueOfParameterNamed(EmailCampaignValidator.submittedOnDateParamName);
|
submittedOnDate = command.localDateValueOfParameterNamed(EmailCampaignValidator.submittedOnDateParamName);
|
||||||
}
|
}
|
||||||
@@ -474,7 +474,7 @@ public class EmailCampaign extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDateInTheFuture(final LocalDate localDate) {
|
private boolean isDateInTheFuture(final LocalDate localDate) {
|
||||||
return localDate.isAfter(DateUtils.getLocalDateOfTenant());
|
return localDate.isAfter(DateUtils.getBusinessLocalDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Report getBusinessRuleId() {
|
public Report getBusinessRuleId() {
|
||||||
|
|||||||
+1
-4
@@ -18,8 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.campaigns.email.domain;
|
package org.apache.fineract.infrastructure.campaigns.email.domain;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -109,8 +107,7 @@ public class EmailMessage extends AbstractPersistableCustom {
|
|||||||
this.emailSubject = emailSubject;
|
this.emailSubject = emailSubject;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.campaignName = campaignName;
|
this.campaignName = campaignName;
|
||||||
this.submittedOnDate = Date
|
this.submittedOnDate = DateUtils.getBusinessDate();
|
||||||
.from(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()).atStartOfDay(ZoneId.systemDefault()).toInstant());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> update(final JsonCommand command) {
|
public Map<String, Object> update(final JsonCommand command) {
|
||||||
|
|||||||
+2
-2
@@ -170,7 +170,7 @@ public class SmsCampaign extends AbstractPersistableCustom {
|
|||||||
final String paramValue = command.jsonFragment(SmsCampaignValidator.paramValue);
|
final String paramValue = command.jsonFragment(SmsCampaignValidator.paramValue);
|
||||||
|
|
||||||
final String message = command.stringValueOfParameterNamed(SmsCampaignValidator.message);
|
final String message = command.stringValueOfParameterNamed(SmsCampaignValidator.message);
|
||||||
LocalDate submittedOnDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
|
||||||
if (command.hasParameter(SmsCampaignValidator.submittedOnDateParamName)) {
|
if (command.hasParameter(SmsCampaignValidator.submittedOnDateParamName)) {
|
||||||
submittedOnDate = command.localDateValueOfParameterNamed(SmsCampaignValidator.submittedOnDateParamName);
|
submittedOnDate = command.localDateValueOfParameterNamed(SmsCampaignValidator.submittedOnDateParamName);
|
||||||
}
|
}
|
||||||
@@ -484,7 +484,7 @@ public class SmsCampaign extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDateInTheFuture(final LocalDate localDate) {
|
private boolean isDateInTheFuture(final LocalDate localDate) {
|
||||||
return localDate.isAfter(DateUtils.getLocalDateOfTenant());
|
return localDate.isAfter(DateUtils.getBusinessLocalDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Report getBusinessRuleId() {
|
public Report getBusinessRuleId() {
|
||||||
|
|||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* 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.infrastructure.core.api;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.temporal.ChronoField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer for Java Local Date Time {@link LocalDateTime} that returns the date in array format to match previous
|
||||||
|
* Jackson functionality.
|
||||||
|
*/
|
||||||
|
public class LocalDateTimeAdapter implements JsonSerializer<LocalDateTime> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public JsonElement serialize(final LocalDateTime src, final Type typeOfSrc, final JsonSerializationContext context) {
|
||||||
|
JsonArray array = null;
|
||||||
|
if (src != null) {
|
||||||
|
array = new JsonArray();
|
||||||
|
array.add(new JsonPrimitive(src.get(ChronoField.YEAR_OF_ERA)));
|
||||||
|
array.add(new JsonPrimitive(src.getMonthValue()));
|
||||||
|
array.add(new JsonPrimitive(src.getDayOfMonth()));
|
||||||
|
array.add(new JsonPrimitive(src.getHour()));
|
||||||
|
array.add(new JsonPrimitive(src.getMinute()));
|
||||||
|
array.add(new JsonPrimitive(src.getSecond()));
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1092,7 +1092,7 @@ public class DataValidatorBuilder {
|
|||||||
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
|
final StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append(this.resource).append(".")
|
||||||
.append(this.parameter).append(".is.greater.than.date");
|
.append(this.parameter).append(".is.greater.than.date");
|
||||||
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
|
final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter `").append(this.parameter)
|
||||||
.append("` must be less than or equal to the provided date").append(date);
|
.append("` must be less than or equal to the provided date: ").append(date);
|
||||||
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
|
final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(),
|
||||||
defaultEnglishMessage.toString(), this.parameter, dateVal, date);
|
defaultEnglishMessage.toString(), this.parameter, dateVal, date);
|
||||||
this.dataValidationErrors.add(error);
|
this.dataValidationErrors.add(error);
|
||||||
|
|||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* 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.infrastructure.core.domain;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum ActionContext {
|
||||||
|
|
||||||
|
DEFAULT(0, "Default context", BusinessDateType.BUSINESS_DATE), COB(1, "Close of Business context", BusinessDateType.COB_DATE);
|
||||||
|
|
||||||
|
private final int order;
|
||||||
|
private final String description;
|
||||||
|
private final BusinessDateType businessDateType;
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* 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.infrastructure.core.domain;
|
||||||
|
|
||||||
|
public interface ContextHolder {
|
||||||
|
|
||||||
|
FineractContext getContext();
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* 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.infrastructure.core.domain;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public class FineractContext implements Serializable {
|
||||||
|
|
||||||
|
private final String contextHolder;
|
||||||
|
private final FineractPlatformTenant tenantContext;
|
||||||
|
private final String authTokenContext;
|
||||||
|
private final HashMap<BusinessDateType, LocalDate> businessDateContext;
|
||||||
|
private final ActionContext actionContext;
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* 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.infrastructure.core.domain;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
public abstract class FineractEvent extends ApplicationEvent implements ContextHolder, Serializable {
|
||||||
|
|
||||||
|
private final FineractContext context;
|
||||||
|
|
||||||
|
public FineractEvent(Object source, FineractContext context) {
|
||||||
|
super(source);
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FineractContext getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-1
@@ -18,7 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.core.domain;
|
package org.apache.fineract.infrastructure.core.domain;
|
||||||
|
|
||||||
public class FineractPlatformTenant {
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class FineractPlatformTenant implements Serializable {
|
||||||
|
|
||||||
private final Long id;
|
private final Long id;
|
||||||
private final String tenantIdentifier;
|
private final String tenantIdentifier;
|
||||||
|
|||||||
+2
-1
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.core.domain;
|
package org.apache.fineract.infrastructure.core.domain;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -25,7 +26,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
/**
|
/**
|
||||||
* Holds Tenant's DB server connection connection details.
|
* Holds Tenant's DB server connection connection details.
|
||||||
*/
|
*/
|
||||||
public class FineractPlatformTenantConnection {
|
public class FineractPlatformTenantConnection implements Serializable {
|
||||||
|
|
||||||
private final Long connectionId;
|
private final Long connectionId;
|
||||||
private final String schemaServer;
|
private final String schemaServer;
|
||||||
|
|||||||
+4
-3
@@ -25,6 +25,7 @@ import java.sql.ResultSet;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -48,11 +49,11 @@ public final class JdbcSupport {
|
|||||||
return dateTime;
|
return dateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ZonedDateTime getLocalDateTime(final ResultSet rs, final String columnName) throws SQLException {
|
public static LocalDateTime getLocalDateTime(final ResultSet rs, final String columnName) throws SQLException {
|
||||||
ZonedDateTime dateTime = null;
|
LocalDateTime dateTime = null;
|
||||||
final Timestamp dateValue = rs.getTimestamp(columnName);
|
final Timestamp dateValue = rs.getTimestamp(columnName);
|
||||||
if (dateValue != null) {
|
if (dateValue != null) {
|
||||||
dateTime = ZonedDateTime.ofInstant(new Date(dateValue.getTime()).toInstant(), getDateTimeZoneOfTenant());
|
dateTime = LocalDateTime.ofInstant(new Date(dateValue.getTime()).toInstant(), getDateTimeZoneOfTenant());
|
||||||
}
|
}
|
||||||
return dateTime;
|
return dateTime;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -22,6 +22,7 @@ import com.google.gson.ExclusionStrategy;
|
|||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.time.MonthDay;
|
import java.time.MonthDay;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
@@ -32,6 +33,7 @@ import org.apache.fineract.infrastructure.core.api.DateAdapter;
|
|||||||
import org.apache.fineract.infrastructure.core.api.JodaDateTimeAdapter;
|
import org.apache.fineract.infrastructure.core.api.JodaDateTimeAdapter;
|
||||||
import org.apache.fineract.infrastructure.core.api.JodaMonthDayAdapter;
|
import org.apache.fineract.infrastructure.core.api.JodaMonthDayAdapter;
|
||||||
import org.apache.fineract.infrastructure.core.api.LocalDateAdapter;
|
import org.apache.fineract.infrastructure.core.api.LocalDateAdapter;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.LocalDateTimeAdapter;
|
||||||
import org.apache.fineract.infrastructure.core.api.LocalTimeAdapter;
|
import org.apache.fineract.infrastructure.core.api.LocalTimeAdapter;
|
||||||
import org.apache.fineract.infrastructure.core.api.ParameterListExclusionStrategy;
|
import org.apache.fineract.infrastructure.core.api.ParameterListExclusionStrategy;
|
||||||
import org.apache.fineract.infrastructure.core.api.ParameterListInclusionStrategy;
|
import org.apache.fineract.infrastructure.core.api.ParameterListInclusionStrategy;
|
||||||
@@ -112,5 +114,6 @@ public final class GoogleGsonSerializerHelper {
|
|||||||
builder.registerTypeAdapter(LocalTime.class, new LocalTimeAdapter());
|
builder.registerTypeAdapter(LocalTime.class, new LocalTimeAdapter());
|
||||||
builder.registerTypeAdapter(ZonedDateTime.class, new JodaDateTimeAdapter());
|
builder.registerTypeAdapter(ZonedDateTime.class, new JodaDateTimeAdapter());
|
||||||
builder.registerTypeAdapter(MonthDay.class, new JodaMonthDayAdapter());
|
builder.registerTypeAdapter(MonthDay.class, new JodaMonthDayAdapter());
|
||||||
|
builder.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-14
@@ -18,10 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.core.serialization;
|
package org.apache.fineract.infrastructure.core.serialization;
|
||||||
|
|
||||||
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
|
|
||||||
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
|
|
||||||
import static java.time.temporal.ChronoField.YEAR_OF_ERA;
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
@@ -46,7 +42,6 @@ import java.util.Set;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
|
||||||
import org.springframework.format.number.NumberStyleFormatter;
|
import org.springframework.format.number.NumberStyleFormatter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -301,19 +296,14 @@ public class JsonParserHelper {
|
|||||||
final JsonObject object = element.getAsJsonObject();
|
final JsonObject object = element.getAsJsonObject();
|
||||||
|
|
||||||
if (object.has(parameterName) && object.get(parameterName).isJsonArray()) {
|
if (object.has(parameterName) && object.get(parameterName).isJsonArray()) {
|
||||||
|
|
||||||
parametersPassedInCommand.add(parameterName);
|
parametersPassedInCommand.add(parameterName);
|
||||||
|
|
||||||
final JsonArray dateArray = object.get(parameterName).getAsJsonArray();
|
final JsonArray dateArray = object.get(parameterName).getAsJsonArray();
|
||||||
|
final int year = dateArray.get(0).getAsInt();
|
||||||
|
final int month = dateArray.get(1).getAsInt();
|
||||||
|
final int day = dateArray.get(2).getAsInt();
|
||||||
|
|
||||||
final Integer year = dateArray.get(0).getAsInt();
|
value = LocalDate.of(year, month, day);
|
||||||
final Integer month = dateArray.get(1).getAsInt();
|
|
||||||
final Integer day = dateArray.get(2).getAsInt();
|
|
||||||
|
|
||||||
value = LocalDate.now(DateUtils.getDateTimeZoneOfTenant()).with(YEAR_OF_ERA, year).with(MONTH_OF_YEAR, month)
|
|
||||||
.with(DAY_OF_MONTH, day);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-17
@@ -26,6 +26,7 @@ import java.time.LocalDateTime;
|
|||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeFormatterBuilder;
|
||||||
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.Calendar;
|
||||||
@@ -38,8 +39,12 @@ import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
|
|||||||
|
|
||||||
public final class DateUtils {
|
public final class DateUtils {
|
||||||
|
|
||||||
public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
|
||||||
public static final DateTimeFormatter DEFAULT_DATETIME_FORMATER = DateTimeFormatter.ofPattern(DEFAULT_DATETIME_FORMAT);
|
public static final String DEFAULT_DATETIME_FORMAT = DEFAULT_DATE_FORMAT + " HH:mm:ss";
|
||||||
|
public static final DateTimeFormatter DEFAULT_DATETIME_FORMATER = new DateTimeFormatterBuilder().appendPattern(DEFAULT_DATETIME_FORMAT)
|
||||||
|
.toFormatter();
|
||||||
|
public static final DateTimeFormatter DEFAULT_DATE_FORMATER = new DateTimeFormatterBuilder().appendPattern(DEFAULT_DATE_FORMAT)
|
||||||
|
.toFormatter();
|
||||||
|
|
||||||
private DateUtils() {
|
private DateUtils() {
|
||||||
|
|
||||||
@@ -51,11 +56,7 @@ public final class DateUtils {
|
|||||||
|
|
||||||
public static ZoneId getDateTimeZoneOfTenant() {
|
public static ZoneId getDateTimeZoneOfTenant() {
|
||||||
final FineractPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
|
final FineractPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
|
||||||
ZoneId zone = ZoneId.systemDefault();
|
return ZoneId.of(tenant.getTimezoneId());
|
||||||
if (tenant != null) {
|
|
||||||
zone = ZoneId.of(tenant.getTimezoneId());
|
|
||||||
}
|
|
||||||
return zone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TimeZone getTimeZoneOfTenant() {
|
public static TimeZone getTimeZoneOfTenant() {
|
||||||
@@ -71,7 +72,7 @@ public final class DateUtils {
|
|||||||
return convertLocalDateToDate(getLocalDateOfTenant());
|
return convertLocalDateToDate(getLocalDateOfTenant());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Date convertLocalDateToDate(LocalDate localDate) {
|
private static Date convertLocalDateToDate(LocalDate localDate) {
|
||||||
return createDate(localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth());
|
return createDate(localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,14 +93,9 @@ public final class DateUtils {
|
|||||||
return LocalDate.now(zone);
|
return LocalDate.now(zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LocalDate getLocalDateOfTenant(final ZoneId zone) {
|
|
||||||
return LocalDate.now(zone);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LocalDateTime getLocalDateTimeOfTenant() {
|
public static LocalDateTime getLocalDateTimeOfTenant() {
|
||||||
final ZoneId zone = getDateTimeZoneOfTenant();
|
final ZoneId zone = getDateTimeZoneOfTenant();
|
||||||
LocalDateTime today = LocalDateTime.now(zone).truncatedTo(ChronoUnit.SECONDS);
|
return LocalDateTime.now(zone).truncatedTo(ChronoUnit.SECONDS);
|
||||||
return today;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Date parseDate(final String stringDate, final String pattern, final ZoneId zoneId) {
|
public static Date parseDate(final String stringDate, final String pattern, final ZoneId zoneId) {
|
||||||
@@ -128,7 +124,8 @@ public final class DateUtils {
|
|||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||||
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.date.pattern",
|
final ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.date.pattern",
|
||||||
"The parameter date (" + stringDate + ") is invalid w.r.t. pattern " + pattern, "date", stringDate, pattern);
|
"The parameter `date` (value: " + stringDate + ") is invalid w.r.t. pattern `" + pattern + "`", "date", stringDate,
|
||||||
|
pattern);
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
|
||||||
dataValidationErrors, e);
|
dataValidationErrors, e);
|
||||||
@@ -142,11 +139,19 @@ public final class DateUtils {
|
|||||||
public static String formatToSqlDate(final Date date) {
|
public static String formatToSqlDate(final Date date) {
|
||||||
final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
|
final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
df.setTimeZone(getTimeZoneOfTenant());
|
df.setTimeZone(getTimeZoneOfTenant());
|
||||||
final String formattedSqlDate = df.format(date);
|
return df.format(date);
|
||||||
return formattedSqlDate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isDateInTheFuture(final LocalDate localDate) {
|
public static boolean isDateInTheFuture(final LocalDate localDate) {
|
||||||
return localDate.isAfter(getLocalDateOfTenant());
|
return localDate.isAfter(getLocalDateOfTenant());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static LocalDate getBusinessLocalDate() {
|
||||||
|
return ThreadLocalContextUtil.getBusinessDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Date getBusinessDate() {
|
||||||
|
return Date.from(ThreadLocalContextUtil.getBusinessDate().atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+63
-18
@@ -18,6 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.core.service;
|
package org.apache.fineract.infrastructure.core.service;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.ActionContext;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractContext;
|
||||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
@@ -26,29 +31,25 @@ import org.springframework.util.Assert;
|
|||||||
*/
|
*/
|
||||||
public final class ThreadLocalContextUtil {
|
public final class ThreadLocalContextUtil {
|
||||||
|
|
||||||
private ThreadLocalContextUtil() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String CONTEXT_TENANTS = "tenants";
|
public static final String CONTEXT_TENANTS = "tenants";
|
||||||
|
|
||||||
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
|
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
|
||||||
|
private static final ThreadLocal<FineractPlatformTenant> tenantContext = new ThreadLocal<>();
|
||||||
private static final ThreadLocal<FineractPlatformTenant> tenantcontext = new ThreadLocal<>();
|
|
||||||
|
|
||||||
private static final ThreadLocal<String> authTokenContext = new ThreadLocal<>();
|
private static final ThreadLocal<String> authTokenContext = new ThreadLocal<>();
|
||||||
|
private static final ThreadLocal<HashMap<BusinessDateType, LocalDate>> businessDateContext = new ThreadLocal<>();
|
||||||
|
private static final ThreadLocal<ActionContext> actionContext = new ThreadLocal<>();
|
||||||
|
|
||||||
public static void setTenant(final FineractPlatformTenant tenant) {
|
private ThreadLocalContextUtil() {}
|
||||||
Assert.notNull(tenant, "tenant cannot be null");
|
|
||||||
tenantcontext.set(tenant);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FineractPlatformTenant getTenant() {
|
public static FineractPlatformTenant getTenant() {
|
||||||
return tenantcontext.get();
|
return tenantContext.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setTenant(final FineractPlatformTenant tenant) {
|
||||||
|
tenantContext.set(tenant);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearTenant() {
|
public static void clearTenant() {
|
||||||
tenantcontext.remove();
|
tenantContext.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getDataSourceContext() {
|
public static String getDataSourceContext() {
|
||||||
@@ -63,12 +64,56 @@ public final class ThreadLocalContextUtil {
|
|||||||
contextHolder.remove();
|
contextHolder.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setAuthToken(final String authToken) {
|
|
||||||
authTokenContext.set(authToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getAuthToken() {
|
public static String getAuthToken() {
|
||||||
return authTokenContext.get();
|
return authTokenContext.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setAuthToken(final String authToken) {
|
||||||
|
authTokenContext.set(authToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map is not serializable, but Hashmap is
|
||||||
|
public static HashMap<BusinessDateType, LocalDate> getBusinessDates() {
|
||||||
|
Assert.notNull(businessDateContext.get(), "Business dates cannot be null!");
|
||||||
|
return businessDateContext.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setBusinessDates(HashMap<BusinessDateType, LocalDate> dates) {
|
||||||
|
Assert.notNull(dates, "Business dates cannot be null!");
|
||||||
|
businessDateContext.set(dates);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LocalDate getBusinessDateByType(BusinessDateType businessDateType) {
|
||||||
|
Assert.notNull(businessDateType, "Business date type cannot be null!");
|
||||||
|
LocalDate localDate = getBusinessDates().get(businessDateType);
|
||||||
|
Assert.notNull(localDate, String.format("Business date with type `%s` is not initialised!", businessDateType));
|
||||||
|
return localDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LocalDate getBusinessDate() {
|
||||||
|
BusinessDateType businessDateType = getActionContext().getBusinessDateType();
|
||||||
|
return getBusinessDateByType(businessDateType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ActionContext getActionContext() {
|
||||||
|
return actionContext.get() == null ? ActionContext.DEFAULT : actionContext.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setActionContext(ActionContext context) {
|
||||||
|
Assert.notNull(context, "context cannot be null");
|
||||||
|
actionContext.set(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FineractContext getContext() {
|
||||||
|
return new FineractContext(getDataSourceContext(), getTenant(), getAuthToken(), getBusinessDates(), getActionContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init(final FineractContext fineractContext) {
|
||||||
|
Assert.notNull(fineractContext, "FineractContext cannot be null during synchronisation!");
|
||||||
|
setDataSourceContext(fineractContext.getContextHolder());
|
||||||
|
setTenant(fineractContext.getTenantContext());
|
||||||
|
setAuthToken(fineractContext.getAuthTokenContext());
|
||||||
|
setBusinessDates(fineractContext.getBusinessDateContext());
|
||||||
|
setActionContext(fineractContext.getActionContext());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-6
@@ -20,6 +20,7 @@ package org.apache.fineract.infrastructure.core.service.database;
|
|||||||
|
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -87,26 +88,36 @@ public class DatabaseSpecificSQLGenerator {
|
|||||||
return format("SELECT COUNT(*) FROM (%s) AS temp", sql);
|
return format("SELECT COUNT(*) FROM (%s) AS temp", sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String currentDate() {
|
public String currentBusinessDate() {
|
||||||
if (databaseTypeResolver.isMySQL()) {
|
if (databaseTypeResolver.isMySQL()) {
|
||||||
return "CURDATE()";
|
return format("DATE('%s')", DateUtils.getBusinessLocalDate().format(DateUtils.DEFAULT_DATE_FORMATER));
|
||||||
} else if (databaseTypeResolver.isPostgreSQL()) {
|
} else if (databaseTypeResolver.isPostgreSQL()) {
|
||||||
return "CURRENT_DATE";
|
return format("DATE '%s'", DateUtils.getBusinessLocalDate().format(DateUtils.DEFAULT_DATE_FORMATER));
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Database type is not supported for current date " + databaseTypeResolver.databaseType());
|
throw new IllegalStateException("Database type is not supported for current date " + databaseTypeResolver.databaseType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String currentDateTime() {
|
public String currentTenantDate() {
|
||||||
if (databaseTypeResolver.isMySQL()) {
|
if (databaseTypeResolver.isMySQL()) {
|
||||||
return "CURRENT_TIMESTAMP()";
|
return format("DATE('%s')", DateUtils.getLocalDateOfTenant().format(DateUtils.DEFAULT_DATE_FORMATER));
|
||||||
} else if (databaseTypeResolver.isPostgreSQL()) {
|
} else if (databaseTypeResolver.isPostgreSQL()) {
|
||||||
return "CURRENT_TIMESTAMP";
|
return format("DATE '%s'", DateUtils.getLocalDateOfTenant().format(DateUtils.DEFAULT_DATE_FORMATER));
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Database type is not supported for current date " + databaseTypeResolver.databaseType());
|
throw new IllegalStateException("Database type is not supported for current date " + databaseTypeResolver.databaseType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String currentTenantDateTime() {
|
||||||
|
if (databaseTypeResolver.isMySQL()) {
|
||||||
|
return format("TIMESTAMP('%s')", DateUtils.getLocalDateTimeOfTenant().format(DateUtils.DEFAULT_DATETIME_FORMATER));
|
||||||
|
} else if (databaseTypeResolver.isPostgreSQL()) {
|
||||||
|
return format("TIMESTAMP '%s'", DateUtils.getLocalDateTimeOfTenant().format(DateUtils.DEFAULT_DATETIME_FORMATER));
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Database type is not supported for current date time" + 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);
|
||||||
|
|||||||
+7
-21
@@ -79,7 +79,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.dao.DataIntegrityViolationException;
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
import org.springframework.dao.EmptyResultDataAccessException;
|
import org.springframework.dao.EmptyResultDataAccessException;
|
||||||
import org.springframework.jdbc.BadSqlGrammarException;
|
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||||
import org.springframework.jdbc.support.GeneratedKeyHolder;
|
import org.springframework.jdbc.support.GeneratedKeyHolder;
|
||||||
@@ -671,29 +670,15 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
|||||||
|
|
||||||
registerDatatable(datatableName, apptableName, entitySubType);
|
registerDatatable(datatableName, apptableName, entitySubType);
|
||||||
registerColumnCodeMapping(codeMappings);
|
registerColumnCodeMapping(codeMappings);
|
||||||
} catch (final JpaSystemException | DataIntegrityViolationException e) {
|
} catch (final PersistenceException | DataAccessException e) {
|
||||||
final Throwable realCause = e.getCause();
|
final Throwable realCause = e.getCause();
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable");
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable");
|
||||||
|
|
||||||
if (realCause.getMessage().toLowerCase().contains("duplicate column name")) {
|
if (realCause.getMessage().toLowerCase().contains("duplicate column name")) {
|
||||||
baseDataValidator.reset().parameter("name").failWithCode("duplicate.column.name");
|
baseDataValidator.reset().parameter("name").failWithCode("duplicate.column.name");
|
||||||
} else if (realCause.getMessage().contains("Table") && realCause.getMessage().contains("already exists")) {
|
} else if ((realCause.getMessage().contains("Table") || realCause.getMessage().contains("relation"))
|
||||||
baseDataValidator.reset().parameter("datatableName").value(datatableName).failWithCode("datatable.already.exists");
|
&& realCause.getMessage().contains("already exists")) {
|
||||||
} else if (realCause.getMessage().contains("Column") && realCause.getMessage().contains("big")) {
|
|
||||||
baseDataValidator.reset().parameter("column").failWithCode("length.too.big");
|
|
||||||
} else if (realCause.getMessage().contains("Row") && realCause.getMessage().contains("large")) {
|
|
||||||
baseDataValidator.reset().parameter("row").failWithCode("size.too.large");
|
|
||||||
}
|
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
|
||||||
} catch (final PersistenceException | BadSqlGrammarException ee) {
|
|
||||||
Throwable realCause = ExceptionUtils.getRootCause(ee.getCause());
|
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
|
||||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable");
|
|
||||||
if (realCause.getMessage().toLowerCase().contains("duplicate column name")) {
|
|
||||||
baseDataValidator.reset().parameter("name").failWithCode("duplicate.column.name");
|
|
||||||
} else if (realCause.getMessage().contains("Table") && realCause.getMessage().contains("already exists")) {
|
|
||||||
baseDataValidator.reset().parameter("datatableName").value(datatableName).failWithCode("datatable.already.exists");
|
baseDataValidator.reset().parameter("datatableName").value(datatableName).failWithCode("datatable.already.exists");
|
||||||
} else if (realCause.getMessage().contains("Column") && realCause.getMessage().contains("big")) {
|
} else if (realCause.getMessage().contains("Column") && realCause.getMessage().contains("big")) {
|
||||||
baseDataValidator.reset().parameter("column").failWithCode("length.too.big");
|
baseDataValidator.reset().parameter("column").failWithCode("length.too.big");
|
||||||
@@ -1132,7 +1117,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
|||||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable");
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable");
|
||||||
if (realCause.getMessage().toLowerCase().contains("duplicate column name")) {
|
if (realCause.getMessage().toLowerCase().contains("duplicate column name")) {
|
||||||
baseDataValidator.reset().parameter("name").failWithCode("duplicate.column.name");
|
baseDataValidator.reset().parameter("name").failWithCode("duplicate.column.name");
|
||||||
} else if (realCause.getMessage().contains("Table") && realCause.getMessage().contains("already exists")) {
|
} else if ((realCause.getMessage().contains("Table") || realCause.getMessage().contains("relation"))
|
||||||
|
&& realCause.getMessage().contains("already exists")) {
|
||||||
baseDataValidator.reset().parameter("datatableName").value(datatableName).failWithCode("datatable.already.exists");
|
baseDataValidator.reset().parameter("datatableName").value(datatableName).failWithCode("datatable.already.exists");
|
||||||
} else if (realCause.getMessage().contains("Column") && realCause.getMessage().contains("big")) {
|
} else if (realCause.getMessage().contains("Column") && realCause.getMessage().contains("big")) {
|
||||||
baseDataValidator.reset().parameter("column").failWithCode("length.too.big");
|
baseDataValidator.reset().parameter("column").failWithCode("length.too.big");
|
||||||
@@ -1569,7 +1555,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
|||||||
|| key.equalsIgnoreCase(DataTableApiConstant.UPDATEDAT_FIELD_NAME)) {
|
|| key.equalsIgnoreCase(DataTableApiConstant.UPDATEDAT_FIELD_NAME)) {
|
||||||
columnName = sqlGenerator.escape(key);
|
columnName = sqlGenerator.escape(key);
|
||||||
insertColumns += ", " + columnName;
|
insertColumns += ", " + columnName;
|
||||||
selectColumns += "," + sqlGenerator.currentDateTime() + " as " + columnName;
|
selectColumns += "," + sqlGenerator.currentTenantDateTime() + " as " + columnName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1675,7 +1661,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
|||||||
sql += sqlGenerator.escape(key) + " = " + pValueWrite;
|
sql += sqlGenerator.escape(key) + " = " + pValueWrite;
|
||||||
} else {
|
} else {
|
||||||
if (key.equalsIgnoreCase(DataTableApiConstant.UPDATEDAT_FIELD_NAME)) {
|
if (key.equalsIgnoreCase(DataTableApiConstant.UPDATEDAT_FIELD_NAME)) {
|
||||||
sql += ", " + sqlGenerator.escape(key) + " = " + sqlGenerator.currentDateTime();
|
sql += ", " + sqlGenerator.escape(key) + " = " + sqlGenerator.currentTenantDateTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-33
@@ -18,47 +18,21 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.hooks.event;
|
package org.apache.fineract.infrastructure.hooks.event;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractContext;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractEvent;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
import org.springframework.context.ApplicationEvent;
|
|
||||||
|
|
||||||
public class HookEvent extends ApplicationEvent {
|
@Getter
|
||||||
|
public class HookEvent extends FineractEvent {
|
||||||
|
|
||||||
private final String payload;
|
private final String payload;
|
||||||
|
|
||||||
private final String tenantIdentifier;
|
|
||||||
|
|
||||||
private final AppUser appUser;
|
private final AppUser appUser;
|
||||||
|
|
||||||
private final String authToken;
|
public HookEvent(final HookEventSource source, final String payload, final AppUser appUser, FineractContext fineractContext) {
|
||||||
|
super(source, fineractContext);
|
||||||
public HookEvent(final HookEventSource source, final String payload, final String tenantIdentifier, final AppUser appUser,
|
|
||||||
final String authToken) {
|
|
||||||
super(source);
|
|
||||||
this.payload = payload;
|
this.payload = payload;
|
||||||
this.tenantIdentifier = tenantIdentifier;
|
|
||||||
this.appUser = appUser;
|
this.appUser = appUser;
|
||||||
this.authToken = authToken;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPayload() {
|
|
||||||
return this.payload;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HookEventSource getSource() {
|
|
||||||
return (HookEventSource) super.source;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTenantIdentifier() {
|
|
||||||
return this.tenantIdentifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AppUser getAppUser() {
|
|
||||||
return this.appUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthToken() {
|
|
||||||
return this.authToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-10
@@ -21,7 +21,7 @@ package org.apache.fineract.infrastructure.hooks.listener;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
import org.apache.fineract.infrastructure.core.domain.FineractContext;
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
||||||
import org.apache.fineract.infrastructure.hooks.event.HookEvent;
|
import org.apache.fineract.infrastructure.hooks.event.HookEvent;
|
||||||
@@ -29,7 +29,6 @@ import org.apache.fineract.infrastructure.hooks.event.HookEventSource;
|
|||||||
import org.apache.fineract.infrastructure.hooks.processor.HookProcessor;
|
import org.apache.fineract.infrastructure.hooks.processor.HookProcessor;
|
||||||
import org.apache.fineract.infrastructure.hooks.processor.HookProcessorProvider;
|
import org.apache.fineract.infrastructure.hooks.processor.HookProcessorProvider;
|
||||||
import org.apache.fineract.infrastructure.hooks.service.HookReadPlatformService;
|
import org.apache.fineract.infrastructure.hooks.service.HookReadPlatformService;
|
||||||
import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
|
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -40,18 +39,15 @@ public class FineractHookListener implements HookListener {
|
|||||||
|
|
||||||
private final HookProcessorProvider hookProcessorProvider;
|
private final HookProcessorProvider hookProcessorProvider;
|
||||||
private final HookReadPlatformService hookReadPlatformService;
|
private final HookReadPlatformService hookReadPlatformService;
|
||||||
private final TenantDetailsService tenantDetailsService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onApplicationEvent(final HookEvent event) {
|
public void onApplicationEvent(final HookEvent event) {
|
||||||
final String tenantIdentifier = event.getTenantIdentifier();
|
ThreadLocalContextUtil.init(event.getContext());
|
||||||
final FineractPlatformTenant tenant = this.tenantDetailsService.loadTenantById(tenantIdentifier);
|
|
||||||
ThreadLocalContextUtil.setTenant(tenant);
|
|
||||||
|
|
||||||
final AppUser appUser = event.getAppUser();
|
final AppUser appUser = event.getAppUser();
|
||||||
final String authToken = event.getAuthToken();
|
|
||||||
|
|
||||||
final HookEventSource hookEventSource = event.getSource();
|
final HookEventSource hookEventSource = (HookEventSource) event.getSource();
|
||||||
|
final FineractContext fineractContext = event.getContext();
|
||||||
final String entityName = hookEventSource.getEntityName();
|
final String entityName = hookEventSource.getEntityName();
|
||||||
final String actionName = hookEventSource.getActionName();
|
final String actionName = hookEventSource.getActionName();
|
||||||
final String payload = event.getPayload();
|
final String payload = event.getPayload();
|
||||||
@@ -62,10 +58,11 @@ public class FineractHookListener implements HookListener {
|
|||||||
for (final Hook hook : hooks) {
|
for (final Hook hook : hooks) {
|
||||||
final HookProcessor processor = this.hookProcessorProvider.getProcessor(hook);
|
final HookProcessor processor = this.hookProcessorProvider.getProcessor(hook);
|
||||||
try {
|
try {
|
||||||
processor.process(hook, appUser, payload, entityName, actionName, tenantIdentifier, authToken);
|
processor.process(hook, payload, entityName, actionName, fineractContext);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.error("Hook {} failed in HookProcessor {} for tenantIdentifier/user {}/{}, entityName: {}, actionName: {}, payload {} ",
|
log.error("Hook {} failed in HookProcessor {} for tenantIdentifier/user {}/{}, entityName: {}, actionName: {}, payload {} ",
|
||||||
hook.getId(), processor.getClass().getSimpleName(), tenantIdentifier, appUser, entityName, actionName, payload, e);
|
hook.getId(), processor.getClass().getSimpleName(), fineractContext.getTenantContext().getTenantIdentifier(),
|
||||||
|
appUser.getDisplayName(), entityName, actionName, payload, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-7
@@ -27,9 +27,9 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractContext;
|
||||||
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
||||||
import org.apache.fineract.infrastructure.hooks.domain.HookConfiguration;
|
import org.apache.fineract.infrastructure.hooks.domain.HookConfiguration;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
|
|
||||||
@@ -40,8 +40,8 @@ public class ElasticSearchHookProcessor implements HookProcessor {
|
|||||||
private final ProcessorHelper processorHelper;
|
private final ProcessorHelper processorHelper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(final Hook hook, @SuppressWarnings("unused") final AppUser appUser, final String payload, final String entityName,
|
public void process(final Hook hook, final String payload, final String entityName, final String actionName,
|
||||||
final String actionName, final String tenantIdentifier, final String authToken) {
|
final FineractContext context) {
|
||||||
|
|
||||||
final Set<HookConfiguration> config = hook.getHookConfig();
|
final Set<HookConfiguration> config = hook.getHookConfig();
|
||||||
|
|
||||||
@@ -58,13 +58,13 @@ public class ElasticSearchHookProcessor implements HookProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendRequest(url, contentType, payload, entityName, actionName, tenantIdentifier, authToken);
|
sendRequest(url, contentType, payload, entityName, actionName, context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void sendRequest(final String url, final String contentType, final String payload, final String entityName,
|
private void sendRequest(final String url, final String contentType, final String payload, final String entityName,
|
||||||
final String actionName, final String tenantIdentifier, @SuppressWarnings("unused") final String authToken) {
|
final String actionName, final FineractContext context) {
|
||||||
|
|
||||||
final String fineractEndpointUrl = System.getProperty("baseUrl");
|
final String fineractEndpointUrl = System.getProperty("baseUrl");
|
||||||
final WebHookService service = processorHelper.createWebHookService(url);
|
final WebHookService service = processorHelper.createWebHookService(url);
|
||||||
@@ -74,11 +74,13 @@ public class ElasticSearchHookProcessor implements HookProcessor {
|
|||||||
|
|
||||||
if (contentType.equalsIgnoreCase("json") || contentType.contains("json")) {
|
if (contentType.equalsIgnoreCase("json") || contentType.contains("json")) {
|
||||||
final JsonObject json = new Gson().fromJson(payload, JsonObject.class);
|
final JsonObject json = new Gson().fromJson(payload, JsonObject.class);
|
||||||
service.sendJsonRequest(entityName, actionName, tenantIdentifier, fineractEndpointUrl, json).enqueue(callback);
|
service.sendJsonRequest(entityName, actionName, context.getTenantContext().getTenantIdentifier(), fineractEndpointUrl, json)
|
||||||
|
.enqueue(callback);
|
||||||
} else {
|
} else {
|
||||||
Map<String, String> map = new HashMap<>();
|
Map<String, String> map = new HashMap<>();
|
||||||
map = new Gson().fromJson(payload, map.getClass());
|
map = new Gson().fromJson(payload, map.getClass());
|
||||||
service.sendFormRequest(entityName, actionName, tenantIdentifier, fineractEndpointUrl, map).enqueue(callback);
|
service.sendFormRequest(entityName, actionName, context.getTenantContext().getTenantIdentifier(), fineractEndpointUrl, map)
|
||||||
|
.enqueue(callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -18,12 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.hooks.processor;
|
package org.apache.fineract.infrastructure.hooks.processor;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractContext;
|
||||||
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
|
|
||||||
public interface HookProcessor {
|
public interface HookProcessor {
|
||||||
|
|
||||||
void process(Hook hook, AppUser appUser, String payload, String entityName, String actionName, String tenantIdentifier,
|
void process(Hook hook, String payload, String entityName, String actionName, FineractContext context) throws Exception;
|
||||||
String authToken) throws Exception;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -30,6 +30,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractContext;
|
||||||
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||||
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
||||||
import org.apache.fineract.infrastructure.hooks.domain.HookConfiguration;
|
import org.apache.fineract.infrastructure.hooks.domain.HookConfiguration;
|
||||||
@@ -41,7 +42,6 @@ import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
|
|||||||
import org.apache.fineract.template.domain.Template;
|
import org.apache.fineract.template.domain.Template;
|
||||||
import org.apache.fineract.template.domain.TemplateRepository;
|
import org.apache.fineract.template.domain.TemplateRepository;
|
||||||
import org.apache.fineract.template.service.TemplateMergeService;
|
import org.apache.fineract.template.service.TemplateMergeService;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -57,8 +57,8 @@ public class MessageGatewayHookProcessor implements HookProcessor {
|
|||||||
private final SmsMessageScheduledJobService smsMessageScheduledJobService;
|
private final SmsMessageScheduledJobService smsMessageScheduledJobService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(final Hook hook, @SuppressWarnings("unused") final AppUser appUser, final String payload, final String entityName,
|
public void process(final Hook hook, final String payload, final String entityName, final String actionName,
|
||||||
final String actionName, final String tenantIdentifier, final String authToken) throws IOException {
|
final FineractContext context) throws IOException {
|
||||||
|
|
||||||
final Set<HookConfiguration> config = hook.getHookConfig();
|
final Set<HookConfiguration> config = hook.getHookConfig();
|
||||||
|
|
||||||
@@ -89,7 +89,9 @@ public class MessageGatewayHookProcessor implements HookProcessor {
|
|||||||
|
|
||||||
// 2.1 : get customer details for basic template mapping
|
// 2.1 : get customer details for basic template mapping
|
||||||
// 2.2 : cook up scope map
|
// 2.2 : cook up scope map
|
||||||
Type type = new TypeToken<Map<String, String>>() {}.getType();
|
Type type = new TypeToken<Map<String, String>>() {
|
||||||
|
|
||||||
|
}.getType();
|
||||||
Map<String, Object> reqMap = new Gson().fromJson(payload, type);
|
Map<String, Object> reqMap = new Gson().fromJson(payload, type);
|
||||||
if (reqMap.get("clientId") != null) {
|
if (reqMap.get("clientId") != null) {
|
||||||
Long clientId = (Long) reqMap.get("clientId");
|
Long clientId = (Long) reqMap.get("clientId");
|
||||||
|
|||||||
+10
-9
@@ -30,6 +30,7 @@ import java.io.IOException;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractContext;
|
||||||
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
||||||
import org.apache.fineract.infrastructure.hooks.domain.HookConfiguration;
|
import org.apache.fineract.infrastructure.hooks.domain.HookConfiguration;
|
||||||
import org.apache.fineract.infrastructure.hooks.domain.HookConfigurationRepository;
|
import org.apache.fineract.infrastructure.hooks.domain.HookConfigurationRepository;
|
||||||
@@ -37,7 +38,6 @@ import org.apache.fineract.infrastructure.hooks.processor.data.SmsProviderData;
|
|||||||
import org.apache.fineract.portfolio.client.domain.Client;
|
import org.apache.fineract.portfolio.client.domain.Client;
|
||||||
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
|
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
|
||||||
import org.apache.fineract.template.service.TemplateMergeService;
|
import org.apache.fineract.template.service.TemplateMergeService;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
|
|
||||||
@@ -51,17 +51,17 @@ public class TwilioHookProcessor implements HookProcessor {
|
|||||||
private final ProcessorHelper processorHelper;
|
private final ProcessorHelper processorHelper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(final Hook hook, @SuppressWarnings("unused") final AppUser appUser, final String payload, final String entityName,
|
public void process(final Hook hook, final String payload, final String entityName, final String actionName,
|
||||||
final String actionName, final String tenantIdentifier, final String authToken) throws IOException {
|
final FineractContext context) throws IOException {
|
||||||
|
|
||||||
final SmsProviderData smsProviderData = new SmsProviderData(hook.getHookConfig());
|
final SmsProviderData smsProviderData = new SmsProviderData(hook.getHookConfig());
|
||||||
|
|
||||||
sendRequest(smsProviderData, payload, entityName, actionName, tenantIdentifier, authToken, hook);
|
sendRequest(smsProviderData, payload, entityName, actionName, hook, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void sendRequest(final SmsProviderData smsProviderData, final String payload, String entityName, String actionName,
|
private void sendRequest(final SmsProviderData smsProviderData, final String payload, String entityName, String actionName,
|
||||||
final String tenantIdentifier, final String authToken, final Hook hook) throws IOException {
|
final Hook hook, final FineractContext context) throws IOException {
|
||||||
|
|
||||||
final WebHookService service = processorHelper.createWebHookService(smsProviderData.getUrl());
|
final WebHookService service = processorHelper.createWebHookService(smsProviderData.getUrl());
|
||||||
|
|
||||||
@@ -72,8 +72,8 @@ public class TwilioHookProcessor implements HookProcessor {
|
|||||||
if (apiKey == null) {
|
if (apiKey == null) {
|
||||||
smsProviderData.setUrl(null);
|
smsProviderData.setUrl(null);
|
||||||
smsProviderData.setEndpoint(System.getProperty("baseUrl"));
|
smsProviderData.setEndpoint(System.getProperty("baseUrl"));
|
||||||
smsProviderData.setTenantId(tenantIdentifier);
|
smsProviderData.setTenantId(context.getTenantContext().getTenantIdentifier());
|
||||||
smsProviderData.setMifosToken(authToken);
|
smsProviderData.setMifosToken(context.getAuthTokenContext());
|
||||||
apiKey = service.sendSmsBridgeConfigRequest(smsProviderData).execute().body();
|
apiKey = service.sendSmsBridgeConfigRequest(smsProviderData).execute().body();
|
||||||
final HookConfiguration apiKeyEntry = HookConfiguration.createNew(hook, "string", apiKeyName, apiKey);
|
final HookConfiguration apiKeyEntry = HookConfiguration.createNew(hook, "string", apiKeyName, apiKey);
|
||||||
this.hookConfigurationRepository.save(apiKeyEntry);
|
this.hookConfigurationRepository.save(apiKeyEntry);
|
||||||
@@ -84,14 +84,15 @@ public class TwilioHookProcessor implements HookProcessor {
|
|||||||
if (hook.getUgdTemplate() != null) {
|
if (hook.getUgdTemplate() != null) {
|
||||||
entityName = "sms";
|
entityName = "sms";
|
||||||
actionName = "send";
|
actionName = "send";
|
||||||
json = processUgdTemplate(payload, hook, authToken);
|
json = processUgdTemplate(payload, hook, context.getAuthTokenContext());
|
||||||
if (json == null) {
|
if (json == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
json = JsonParser.parseString(payload).getAsJsonObject();
|
json = JsonParser.parseString(payload).getAsJsonObject();
|
||||||
}
|
}
|
||||||
service.sendSmsBridgeRequest(entityName, actionName, tenantIdentifier, apiKey, json).enqueue(callback);
|
service.sendSmsBridgeRequest(entityName, actionName, context.getTenantContext().getTenantIdentifier(), apiKey, json)
|
||||||
|
.enqueue(callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-7
@@ -28,9 +28,9 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractContext;
|
||||||
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
import org.apache.fineract.infrastructure.hooks.domain.Hook;
|
||||||
import org.apache.fineract.infrastructure.hooks.domain.HookConfiguration;
|
import org.apache.fineract.infrastructure.hooks.domain.HookConfiguration;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
|
|
||||||
@@ -41,8 +41,8 @@ public class WebHookProcessor implements HookProcessor {
|
|||||||
private final ProcessorHelper processorHelper;
|
private final ProcessorHelper processorHelper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(final Hook hook, @SuppressWarnings("unused") final AppUser appUser, final String payload, final String entityName,
|
public void process(final Hook hook, final String payload, final String entityName, final String actionName,
|
||||||
final String actionName, final String tenantIdentifier, final String authToken) {
|
final FineractContext context) {
|
||||||
|
|
||||||
final Set<HookConfiguration> config = hook.getHookConfig();
|
final Set<HookConfiguration> config = hook.getHookConfig();
|
||||||
|
|
||||||
@@ -59,12 +59,12 @@ public class WebHookProcessor implements HookProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendRequest(url, contentType, payload, entityName, actionName, tenantIdentifier, authToken);
|
sendRequest(url, contentType, payload, entityName, actionName, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void sendRequest(final String url, final String contentType, final String payload, final String entityName,
|
private void sendRequest(final String url, final String contentType, final String payload, final String entityName,
|
||||||
final String actionName, final String tenantIdentifier, @SuppressWarnings("unused") final String authToken) {
|
final String actionName, final FineractContext context) {
|
||||||
|
|
||||||
final String fineractEndpointUrl = System.getProperty("baseUrl");
|
final String fineractEndpointUrl = System.getProperty("baseUrl");
|
||||||
final WebHookService service = processorHelper.createWebHookService(url);
|
final WebHookService service = processorHelper.createWebHookService(url);
|
||||||
@@ -74,11 +74,13 @@ public class WebHookProcessor implements HookProcessor {
|
|||||||
|
|
||||||
if (contentType.equalsIgnoreCase("json") || contentType.contains("json")) {
|
if (contentType.equalsIgnoreCase("json") || contentType.contains("json")) {
|
||||||
final JsonObject json = JsonParser.parseString(payload).getAsJsonObject();
|
final JsonObject json = JsonParser.parseString(payload).getAsJsonObject();
|
||||||
service.sendJsonRequest(entityName, actionName, tenantIdentifier, fineractEndpointUrl, json).enqueue(callback);
|
service.sendJsonRequest(entityName, actionName, context.getTenantContext().getTenantIdentifier(), fineractEndpointUrl, json)
|
||||||
|
.enqueue(callback);
|
||||||
} else {
|
} else {
|
||||||
Map<String, String> map = new HashMap<>();
|
Map<String, String> map = new HashMap<>();
|
||||||
map = new Gson().fromJson(payload, map.getClass());
|
map = new Gson().fromJson(payload, map.getClass());
|
||||||
service.sendFormRequest(entityName, actionName, tenantIdentifier, fineractEndpointUrl, map).enqueue(callback);
|
service.sendFormRequest(entityName, actionName, context.getTenantContext().getTenantIdentifier(), fineractEndpointUrl, map)
|
||||||
|
.enqueue(callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-13
@@ -18,7 +18,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.jobs.service;
|
package org.apache.fineract.infrastructure.jobs.service;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.apache.fineract.infrastructure.jobs.domain.ScheduledJobDetail;
|
import org.apache.fineract.infrastructure.jobs.domain.ScheduledJobDetail;
|
||||||
import org.apache.fineract.infrastructure.jobs.domain.ScheduledJobRunHistory;
|
import org.apache.fineract.infrastructure.jobs.domain.ScheduledJobRunHistory;
|
||||||
@@ -29,7 +34,6 @@ import org.quartz.JobExecutionException;
|
|||||||
import org.quartz.JobKey;
|
import org.quartz.JobKey;
|
||||||
import org.quartz.JobListener;
|
import org.quartz.JobListener;
|
||||||
import org.quartz.Trigger;
|
import org.quartz.Trigger;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
||||||
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
|
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
|
||||||
@@ -39,26 +43,17 @@ import org.springframework.stereotype.Component;
|
|||||||
/**
|
/**
|
||||||
* Global job Listener class to set Tenant details to {@link ThreadLocalContextUtil} for batch Job and stores the batch
|
* Global job Listener class to set Tenant details to {@link ThreadLocalContextUtil} for batch Job and stores the batch
|
||||||
* job status to database after the execution
|
* job status to database after the execution
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class SchedulerJobListener implements JobListener {
|
public class SchedulerJobListener implements JobListener {
|
||||||
|
|
||||||
private int stackTraceLevel = 0;
|
|
||||||
|
|
||||||
private final String name = SchedulerServiceConstants.DEFAULT_LISTENER_NAME;
|
private final String name = SchedulerServiceConstants.DEFAULT_LISTENER_NAME;
|
||||||
|
|
||||||
private final SchedularWritePlatformService schedularService;
|
private final SchedularWritePlatformService schedularService;
|
||||||
|
|
||||||
private final AppUserRepositoryWrapper userRepository;
|
private final AppUserRepositoryWrapper userRepository;
|
||||||
|
|
||||||
private final GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
|
private final GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
|
||||||
|
private final BusinessDateReadPlatformService businessDateReadPlatformService;
|
||||||
@Autowired
|
private int stackTraceLevel = 0;
|
||||||
public SchedulerJobListener(final SchedularWritePlatformService schedularService, final AppUserRepositoryWrapper userRepository) {
|
|
||||||
this.schedularService = schedularService;
|
|
||||||
this.userRepository = userRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@@ -71,6 +66,8 @@ public class SchedulerJobListener implements JobListener {
|
|||||||
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, user.getPassword(),
|
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, user.getPassword(),
|
||||||
authoritiesMapper.mapAuthorities(user.getAuthorities()));
|
authoritiesMapper.mapAuthorities(user.getAuthorities()));
|
||||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||||
|
HashMap<BusinessDateType, LocalDate> businessDates = businessDateReadPlatformService.getBusinessDates();
|
||||||
|
ThreadLocalContextUtil.setBusinessDates(businessDates);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+9
-7
@@ -20,6 +20,11 @@ package org.apache.fineract.infrastructure.jobs.service;
|
|||||||
|
|
||||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
|
||||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
|
import org.apache.fineract.infrastructure.security.service.TenantDetailsService;
|
||||||
@@ -30,10 +35,10 @@ import org.quartz.Trigger.CompletedExecutionInstruction;
|
|||||||
import org.quartz.TriggerListener;
|
import org.quartz.TriggerListener;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class SchedulerTriggerListener implements TriggerListener {
|
public class SchedulerTriggerListener implements TriggerListener {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(SchedulerTriggerListener.class);
|
private static final Logger LOG = LoggerFactory.getLogger(SchedulerTriggerListener.class);
|
||||||
@@ -42,12 +47,7 @@ public class SchedulerTriggerListener implements TriggerListener {
|
|||||||
private final SchedularWritePlatformService schedularService;
|
private final SchedularWritePlatformService schedularService;
|
||||||
private final TenantDetailsService tenantDetailsService;
|
private final TenantDetailsService tenantDetailsService;
|
||||||
|
|
||||||
@Autowired
|
private final BusinessDateReadPlatformService businessDateReadPlatformService;
|
||||||
public SchedulerTriggerListener(final SchedularWritePlatformService schedularService, final TenantDetailsService tenantDetailsService) {
|
|
||||||
this.schedularService = schedularService;
|
|
||||||
this.tenantDetailsService = tenantDetailsService;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@@ -66,6 +66,8 @@ public class SchedulerTriggerListener implements TriggerListener {
|
|||||||
final String tenantIdentifier = trigger.getJobDataMap().getString(SchedulerServiceConstants.TENANT_IDENTIFIER);
|
final String tenantIdentifier = trigger.getJobDataMap().getString(SchedulerServiceConstants.TENANT_IDENTIFIER);
|
||||||
final FineractPlatformTenant tenant = this.tenantDetailsService.loadTenantById(tenantIdentifier);
|
final FineractPlatformTenant tenant = this.tenantDetailsService.loadTenantById(tenantIdentifier);
|
||||||
ThreadLocalContextUtil.setTenant(tenant);
|
ThreadLocalContextUtil.setTenant(tenant);
|
||||||
|
HashMap<BusinessDateType, LocalDate> businessDates = businessDateReadPlatformService.getBusinessDates();
|
||||||
|
ThreadLocalContextUtil.setBusinessDates(businessDates);
|
||||||
final JobKey key = trigger.getJobKey();
|
final JobKey key = trigger.getJobKey();
|
||||||
final String jobKey = key.getName() + SchedulerServiceConstants.JOB_KEY_SEPERATOR + key.getGroup();
|
final String jobKey = key.getName() + SchedulerServiceConstants.JOB_KEY_SEPERATOR + key.getGroup();
|
||||||
String triggerType = SchedulerServiceConstants.TRIGGER_TYPE_CRON;
|
String triggerType = SchedulerServiceConstants.TRIGGER_TYPE_CRON;
|
||||||
|
|||||||
+9
-1
@@ -19,11 +19,15 @@
|
|||||||
package org.apache.fineract.infrastructure.security.filter;
|
package org.apache.fineract.infrastructure.security.filter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.HashMap;
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import org.apache.commons.lang3.time.StopWatch;
|
import org.apache.commons.lang3.time.StopWatch;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
|
||||||
import org.apache.fineract.infrastructure.cache.domain.CacheType;
|
import org.apache.fineract.infrastructure.cache.domain.CacheType;
|
||||||
import org.apache.fineract.infrastructure.cache.service.CacheWritePlatformService;
|
import org.apache.fineract.infrastructure.cache.service.CacheWritePlatformService;
|
||||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
@@ -80,6 +84,9 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
|
|||||||
@Autowired
|
@Autowired
|
||||||
private BasicAuthTenantDetailsService basicAuthTenantDetailsService;
|
private BasicAuthTenantDetailsService basicAuthTenantDetailsService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BusinessDateReadPlatformService businessDateReadPlatformService;
|
||||||
|
|
||||||
private final String tenantRequestHeader = "Fineract-Platform-TenantId";
|
private final String tenantRequestHeader = "Fineract-Platform-TenantId";
|
||||||
private final boolean exceptionIfHeaderMissing = true;
|
private final boolean exceptionIfHeaderMissing = true;
|
||||||
|
|
||||||
@@ -119,8 +126,9 @@ public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFil
|
|||||||
isReportRequest = true;
|
isReportRequest = true;
|
||||||
}
|
}
|
||||||
final FineractPlatformTenant tenant = this.basicAuthTenantDetailsService.loadTenantById(tenantIdentifier, isReportRequest);
|
final FineractPlatformTenant tenant = this.basicAuthTenantDetailsService.loadTenantById(tenantIdentifier, isReportRequest);
|
||||||
|
|
||||||
ThreadLocalContextUtil.setTenant(tenant);
|
ThreadLocalContextUtil.setTenant(tenant);
|
||||||
|
HashMap<BusinessDateType, LocalDate> businessDates = this.businessDateReadPlatformService.getBusinessDates();
|
||||||
|
ThreadLocalContextUtil.setBusinessDates(businessDates);
|
||||||
String authToken = request.getHeader("Authorization");
|
String authToken = request.getHeader("Authorization");
|
||||||
|
|
||||||
if (authToken != null && authToken.startsWith("Basic ")) {
|
if (authToken != null && authToken.startsWith("Basic ")) {
|
||||||
|
|||||||
+18
-20
@@ -19,13 +19,20 @@
|
|||||||
package org.apache.fineract.infrastructure.security.filter;
|
package org.apache.fineract.infrastructure.security.filter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.time.StopWatch;
|
import org.apache.commons.lang3.time.StopWatch;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
|
||||||
import org.apache.fineract.infrastructure.cache.domain.CacheType;
|
import org.apache.fineract.infrastructure.cache.domain.CacheType;
|
||||||
import org.apache.fineract.infrastructure.cache.service.CacheWritePlatformService;
|
import org.apache.fineract.infrastructure.cache.service.CacheWritePlatformService;
|
||||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
@@ -35,9 +42,6 @@ import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
|||||||
import org.apache.fineract.infrastructure.security.data.PlatformRequestLog;
|
import org.apache.fineract.infrastructure.security.data.PlatformRequestLog;
|
||||||
import org.apache.fineract.infrastructure.security.exception.InvalidTenantIdentiferException;
|
import org.apache.fineract.infrastructure.security.exception.InvalidTenantIdentiferException;
|
||||||
import org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetailsService;
|
import org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetailsService;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -56,30 +60,23 @@ import org.springframework.web.filter.GenericFilterBean;
|
|||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
@ConditionalOnProperty("fineract.security.oauth.enabled")
|
@ConditionalOnProperty("fineract.security.oauth.enabled")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
public class TenantAwareTenantIdentifierFilter extends GenericFilterBean {
|
public class TenantAwareTenantIdentifierFilter extends GenericFilterBean {
|
||||||
|
|
||||||
private static boolean firstRequestProcessed = false;
|
private static AtomicBoolean firstRequestProcessed = new AtomicBoolean();
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(TenantAwareTenantIdentifierFilter.class);
|
|
||||||
|
|
||||||
private final BasicAuthTenantDetailsService basicAuthTenantDetailsService;
|
private final BasicAuthTenantDetailsService basicAuthTenantDetailsService;
|
||||||
private final ToApiJsonSerializer<PlatformRequestLog> toApiJsonSerializer;
|
private final ToApiJsonSerializer<PlatformRequestLog> toApiJsonSerializer;
|
||||||
private final ConfigurationDomainService configurationDomainService;
|
private final ConfigurationDomainService configurationDomainService;
|
||||||
private final CacheWritePlatformService cacheWritePlatformService;
|
private final CacheWritePlatformService cacheWritePlatformService;
|
||||||
|
|
||||||
|
private final BusinessDateReadPlatformService businessDateReadPlatformService;
|
||||||
|
|
||||||
private final String tenantRequestHeader = "Fineract-Platform-TenantId";
|
private final String tenantRequestHeader = "Fineract-Platform-TenantId";
|
||||||
private final boolean exceptionIfHeaderMissing = true;
|
private final boolean exceptionIfHeaderMissing = true;
|
||||||
private final String apiUri = "/api/v1/";
|
private final String apiUri = "/api/v1/";
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public TenantAwareTenantIdentifierFilter(final BasicAuthTenantDetailsService basicAuthTenantDetailsService,
|
|
||||||
final ToApiJsonSerializer<PlatformRequestLog> toApiJsonSerializer, final ConfigurationDomainService configurationDomainService,
|
|
||||||
final CacheWritePlatformService cacheWritePlatformService) {
|
|
||||||
this.basicAuthTenantDetailsService = basicAuthTenantDetailsService;
|
|
||||||
this.toApiJsonSerializer = toApiJsonSerializer;
|
|
||||||
this.configurationDomainService = configurationDomainService;
|
|
||||||
this.cacheWritePlatformService = cacheWritePlatformService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
|
public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
@@ -120,15 +117,16 @@ public class TenantAwareTenantIdentifierFilter extends GenericFilterBean {
|
|||||||
isReportRequest = true;
|
isReportRequest = true;
|
||||||
}
|
}
|
||||||
final FineractPlatformTenant tenant = this.basicAuthTenantDetailsService.loadTenantById(tenantIdentifier, isReportRequest);
|
final FineractPlatformTenant tenant = this.basicAuthTenantDetailsService.loadTenantById(tenantIdentifier, isReportRequest);
|
||||||
|
|
||||||
ThreadLocalContextUtil.setTenant(tenant);
|
ThreadLocalContextUtil.setTenant(tenant);
|
||||||
|
HashMap<BusinessDateType, LocalDate> businessDates = this.businessDateReadPlatformService.getBusinessDates();
|
||||||
|
ThreadLocalContextUtil.setBusinessDates(businessDates);
|
||||||
String authToken = request.getHeader("Authorization");
|
String authToken = request.getHeader("Authorization");
|
||||||
|
|
||||||
if (authToken != null && authToken.startsWith("bearer ")) {
|
if (authToken != null && authToken.startsWith("bearer ")) {
|
||||||
ThreadLocalContextUtil.setAuthToken(authToken.replaceFirst("bearer ", ""));
|
ThreadLocalContextUtil.setAuthToken(authToken.replaceFirst("bearer ", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!firstRequestProcessed) {
|
if (!firstRequestProcessed.get()) {
|
||||||
final String baseUrl = request.getRequestURL().toString().replace(request.getRequestURI(),
|
final String baseUrl = request.getRequestURL().toString().replace(request.getRequestURI(),
|
||||||
request.getContextPath() + apiUri);
|
request.getContextPath() + apiUri);
|
||||||
System.setProperty("baseUrl", baseUrl);
|
System.setProperty("baseUrl", baseUrl);
|
||||||
@@ -139,7 +137,7 @@ public class TenantAwareTenantIdentifierFilter extends GenericFilterBean {
|
|||||||
} else {
|
} else {
|
||||||
this.cacheWritePlatformService.switchToCache(CacheType.NO_CACHE);
|
this.cacheWritePlatformService.switchToCache(CacheType.NO_CACHE);
|
||||||
}
|
}
|
||||||
TenantAwareTenantIdentifierFilter.firstRequestProcessed = true;
|
firstRequestProcessed.set(true);
|
||||||
}
|
}
|
||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
@@ -151,8 +149,8 @@ public class TenantAwareTenantIdentifierFilter extends GenericFilterBean {
|
|||||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
|
response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
task.stop();
|
task.stop();
|
||||||
final PlatformRequestLog log = PlatformRequestLog.from(task, request);
|
final PlatformRequestLog logRequest = PlatformRequestLog.from(task, request);
|
||||||
LOG.info("{}", this.toApiJsonSerializer.serialize(log));
|
log.info("{}", this.toApiJsonSerializer.serialize(logRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-4
@@ -18,8 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.sms.domain;
|
package org.apache.fineract.infrastructure.sms.domain;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -122,8 +120,7 @@ public class SmsMessage extends AbstractPersistableCustom {
|
|||||||
this.mobileNo = mobileNo;
|
this.mobileNo = mobileNo;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.smsCampaign = smsCampaign;
|
this.smsCampaign = smsCampaign;
|
||||||
this.submittedOnDate = Date
|
this.submittedOnDate = DateUtils.getBusinessDate();
|
||||||
.from(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()).atStartOfDay(ZoneId.systemDefault()).toInstant());
|
|
||||||
this.isNotification = isNotification;
|
this.isNotification = isNotification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+45
-45
@@ -28,11 +28,12 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.fineract.infrastructure.campaigns.helper.SmsConfigUtils;
|
import org.apache.fineract.infrastructure.campaigns.helper.SmsConfigUtils;
|
||||||
import org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignConstants;
|
import org.apache.fineract.infrastructure.campaigns.sms.constants.SmsCampaignConstants;
|
||||||
import org.apache.fineract.infrastructure.campaigns.sms.domain.SmsCampaign;
|
import org.apache.fineract.infrastructure.campaigns.sms.domain.SmsCampaign;
|
||||||
import org.apache.fineract.infrastructure.campaigns.sms.exception.ConnectionFailureException;
|
import org.apache.fineract.infrastructure.campaigns.sms.exception.ConnectionFailureException;
|
||||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
import org.apache.fineract.infrastructure.core.domain.FineractContext;
|
||||||
import org.apache.fineract.infrastructure.core.service.Page;
|
import org.apache.fineract.infrastructure.core.service.Page;
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.apache.fineract.infrastructure.gcm.service.NotificationSenderService;
|
import org.apache.fineract.infrastructure.gcm.service.NotificationSenderService;
|
||||||
@@ -44,8 +45,6 @@ import org.apache.fineract.infrastructure.sms.domain.SmsMessage;
|
|||||||
import org.apache.fineract.infrastructure.sms.domain.SmsMessageRepository;
|
import org.apache.fineract.infrastructure.sms.domain.SmsMessageRepository;
|
||||||
import org.apache.fineract.infrastructure.sms.domain.SmsMessageStatusType;
|
import org.apache.fineract.infrastructure.sms.domain.SmsMessageStatusType;
|
||||||
import org.apache.fineract.infrastructure.sms.service.SmsReadPlatformService;
|
import org.apache.fineract.infrastructure.sms.service.SmsReadPlatformService;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.context.event.ContextClosedEvent;
|
import org.springframework.context.event.ContextClosedEvent;
|
||||||
@@ -63,16 +62,16 @@ import org.springframework.web.client.RestTemplate;
|
|||||||
* Scheduled job services that send SMS messages and get delivery reports for the sent SMS messages
|
* Scheduled job services that send SMS messages and get delivery reports for the sent SMS messages
|
||||||
**/
|
**/
|
||||||
@Service
|
@Service
|
||||||
|
@Slf4j
|
||||||
public class SmsMessageScheduledJobServiceImpl implements SmsMessageScheduledJobService {
|
public class SmsMessageScheduledJobServiceImpl implements SmsMessageScheduledJobService {
|
||||||
|
|
||||||
private final SmsMessageRepository smsMessageRepository;
|
private final SmsMessageRepository smsMessageRepository;
|
||||||
private final SmsReadPlatformService smsReadPlatformService;
|
private final SmsReadPlatformService smsReadPlatformService;
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(SmsMessageScheduledJobServiceImpl.class);
|
|
||||||
private final RestTemplate restTemplate = new RestTemplate();
|
private final RestTemplate restTemplate = new RestTemplate();
|
||||||
private ExecutorService genericExecutorService;
|
|
||||||
private ExecutorService triggeredExecutorService;
|
|
||||||
private final SmsConfigUtils smsConfigUtils;
|
private final SmsConfigUtils smsConfigUtils;
|
||||||
private final NotificationSenderService notificationSenderService;
|
private final NotificationSenderService notificationSenderService;
|
||||||
|
private ExecutorService genericExecutorService;
|
||||||
|
private ExecutorService triggeredExecutorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SmsMessageScheduledJobServiceImpl constructor
|
* SmsMessageScheduledJobServiceImpl constructor
|
||||||
@@ -131,7 +130,7 @@ public class SmsMessageScheduledJobServiceImpl implements SmsMessageScheduledJob
|
|||||||
if (toSaveMessages.size() > 0) {
|
if (toSaveMessages.size() > 0) {
|
||||||
this.smsMessageRepository.saveAll(toSaveMessages);
|
this.smsMessageRepository.saveAll(toSaveMessages);
|
||||||
this.smsMessageRepository.flush();
|
this.smsMessageRepository.flush();
|
||||||
this.genericExecutorService.execute(new SmsTask(ThreadLocalContextUtil.getTenant(), apiQueueResourceDatas));
|
this.genericExecutorService.execute(new SmsTask(apiQueueResourceDatas, ThreadLocalContextUtil.getContext()));
|
||||||
}
|
}
|
||||||
if (!toSendNotificationMessages.isEmpty()) {
|
if (!toSendNotificationMessages.isEmpty()) {
|
||||||
this.notificationSenderService.sendNotification(toSendNotificationMessages);
|
this.notificationSenderService.sendNotification(toSendNotificationMessages);
|
||||||
@@ -147,40 +146,18 @@ public class SmsMessageScheduledJobServiceImpl implements SmsMessageScheduledJob
|
|||||||
} while (page < totalRecords);
|
} while (page < totalRecords);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SmsTask implements Runnable, ApplicationListener<ContextClosedEvent> {
|
|
||||||
|
|
||||||
private final FineractPlatformTenant tenant;
|
|
||||||
private final Collection<SmsMessageApiQueueResourceData> apiQueueResourceDatas;
|
|
||||||
|
|
||||||
SmsTask(final FineractPlatformTenant tenant, final Collection<SmsMessageApiQueueResourceData> apiQueueResourceDatas) {
|
|
||||||
this.tenant = tenant;
|
|
||||||
this.apiQueueResourceDatas = apiQueueResourceDatas;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
ThreadLocalContextUtil.setTenant(tenant);
|
|
||||||
connectAndSendToIntermediateServer(apiQueueResourceDatas);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onApplicationEvent(ContextClosedEvent event) {
|
|
||||||
genericExecutorService.shutdown();
|
|
||||||
LOG.info("Shutting down the ExecutorService");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void connectAndSendToIntermediateServer(Collection<SmsMessageApiQueueResourceData> apiQueueResourceDatas) {
|
private void connectAndSendToIntermediateServer(Collection<SmsMessageApiQueueResourceData> apiQueueResourceDatas) {
|
||||||
Map<String, Object> hostConfig = this.smsConfigUtils.getMessageGateWayRequestURI("sms",
|
Map<String, Object> hostConfig = this.smsConfigUtils.getMessageGateWayRequestURI("sms",
|
||||||
SmsMessageApiQueueResourceData.toJsonString(apiQueueResourceDatas));
|
SmsMessageApiQueueResourceData.toJsonString(apiQueueResourceDatas));
|
||||||
URI uri = (URI) hostConfig.get("uri");
|
URI uri = (URI) hostConfig.get("uri");
|
||||||
HttpEntity<?> entity = (HttpEntity<?>) hostConfig.get("entity");
|
HttpEntity<?> entity = (HttpEntity<?>) hostConfig.get("entity");
|
||||||
ResponseEntity<String> responseOne = restTemplate.exchange(uri, HttpMethod.POST, entity,
|
ResponseEntity<String> responseOne = restTemplate.exchange(uri, HttpMethod.POST, entity, new ParameterizedTypeReference<String>() {
|
||||||
new ParameterizedTypeReference<String>() {});
|
|
||||||
|
});
|
||||||
if (responseOne != null) {
|
if (responseOne != null) {
|
||||||
// String smsResponse = responseOne.getBody();
|
// String smsResponse = responseOne.getBody();
|
||||||
if (!responseOne.getStatusCode().equals(HttpStatus.ACCEPTED)) {
|
if (!responseOne.getStatusCode().equals(HttpStatus.ACCEPTED)) {
|
||||||
LOG.debug("{}", responseOne.getStatusCode().name());
|
log.debug("{}", responseOne.getStatusCode().name());
|
||||||
throw new ConnectionFailureException(SmsCampaignConstants.SMS);
|
throw new ConnectionFailureException(SmsCampaignConstants.SMS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,7 +190,7 @@ public class SmsMessageScheduledJobServiceImpl implements SmsMessageScheduledJob
|
|||||||
if (toSaveMessages.size() > 0) {
|
if (toSaveMessages.size() > 0) {
|
||||||
this.smsMessageRepository.saveAll(toSaveMessages);
|
this.smsMessageRepository.saveAll(toSaveMessages);
|
||||||
this.smsMessageRepository.flush();
|
this.smsMessageRepository.flush();
|
||||||
this.triggeredExecutorService.execute(new SmsTask(ThreadLocalContextUtil.getTenant(), apiQueueResourceDatas));
|
this.triggeredExecutorService.execute(new SmsTask(apiQueueResourceDatas, ThreadLocalContextUtil.getContext()));
|
||||||
}
|
}
|
||||||
if (!toSendNotificationMessages.isEmpty()) {
|
if (!toSendNotificationMessages.isEmpty()) {
|
||||||
this.notificationSenderService.sendNotification(toSendNotificationMessages);
|
this.notificationSenderService.sendNotification(toSendNotificationMessages);
|
||||||
@@ -222,7 +199,7 @@ public class SmsMessageScheduledJobServiceImpl implements SmsMessageScheduledJob
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Error occured.", e);
|
log.error("Error occured.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,10 +216,10 @@ public class SmsMessageScheduledJobServiceImpl implements SmsMessageScheduledJob
|
|||||||
}
|
}
|
||||||
this.smsMessageRepository.saveAll(smsMessages);
|
this.smsMessageRepository.saveAll(smsMessages);
|
||||||
request.append(SmsMessageApiQueueResourceData.toJsonString(apiQueueResourceDatas));
|
request.append(SmsMessageApiQueueResourceData.toJsonString(apiQueueResourceDatas));
|
||||||
LOG.info("Sending triggered SMS to specific provider with request - {}", request);
|
log.info("Sending triggered SMS to specific provider with request - {}", request);
|
||||||
this.triggeredExecutorService.execute(new SmsTask(ThreadLocalContextUtil.getTenant(), apiQueueResourceDatas));
|
this.triggeredExecutorService.execute(new SmsTask(apiQueueResourceDatas, ThreadLocalContextUtil.getContext()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Error occured.", e);
|
log.error("Error occured.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +245,9 @@ public class SmsMessageScheduledJobServiceImpl implements SmsMessageScheduledJob
|
|||||||
URI uri = (URI) hostConfig.get("uri");
|
URI uri = (URI) hostConfig.get("uri");
|
||||||
HttpEntity<?> entity = (HttpEntity<?>) hostConfig.get("entity");
|
HttpEntity<?> entity = (HttpEntity<?>) hostConfig.get("entity");
|
||||||
ResponseEntity<Collection<SmsMessageDeliveryReportData>> responseOne = restTemplate.exchange(uri, HttpMethod.POST,
|
ResponseEntity<Collection<SmsMessageDeliveryReportData>> responseOne = restTemplate.exchange(uri, HttpMethod.POST,
|
||||||
entity, new ParameterizedTypeReference<Collection<SmsMessageDeliveryReportData>>() {});
|
entity, new ParameterizedTypeReference<Collection<SmsMessageDeliveryReportData>>() {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
Collection<SmsMessageDeliveryReportData> smsMessageDeliveryReportDatas = responseOne.getBody();
|
Collection<SmsMessageDeliveryReportData> smsMessageDeliveryReportDatas = responseOne.getBody();
|
||||||
Iterator<SmsMessageDeliveryReportData> responseReportIterator = smsMessageDeliveryReportDatas.iterator();
|
Iterator<SmsMessageDeliveryReportData> responseReportIterator = smsMessageDeliveryReportDatas.iterator();
|
||||||
@@ -315,23 +294,44 @@ public class SmsMessageScheduledJobServiceImpl implements SmsMessageScheduledJob
|
|||||||
this.smsMessageRepository.save(smsMessage);
|
this.smsMessageRepository.save(smsMessage);
|
||||||
|
|
||||||
if (statusChanged) {
|
if (statusChanged) {
|
||||||
LOG.info("Status of SMS message id: {} successfully changed to {}", smsMessage.getId(), statusType);
|
log.info("Status of SMS message id: {} successfully changed to {}", smsMessage.getId(), statusType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smsMessageDeliveryReportDatas.size() > 0) {
|
if (smsMessageDeliveryReportDatas.size() > 0) {
|
||||||
LOG.info("{} delivery report(s) successfully received from the intermediate gateway - sms",
|
log.info("{} delivery report(s) successfully received from the intermediate gateway - sms",
|
||||||
smsMessageDeliveryReportDatas.size());
|
smsMessageDeliveryReportDatas.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
|
log.error("Error occured.", e);
|
||||||
catch (Exception e) {
|
|
||||||
LOG.error("Error occured.", e);
|
|
||||||
}
|
}
|
||||||
page++;
|
page++;
|
||||||
totalRecords = smsMessageInternalIds.getTotalFilteredRecords();
|
totalRecords = smsMessageInternalIds.getTotalFilteredRecords();
|
||||||
} while (page < totalRecords);
|
} while (page < totalRecords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SmsTask implements Runnable, ApplicationListener<ContextClosedEvent> {
|
||||||
|
|
||||||
|
private final FineractContext context;
|
||||||
|
private final Collection<SmsMessageApiQueueResourceData> apiQueueResourceDatas;
|
||||||
|
|
||||||
|
SmsTask(final Collection<SmsMessageApiQueueResourceData> apiQueueResourceDatas, final FineractContext context) {
|
||||||
|
this.context = context;
|
||||||
|
this.apiQueueResourceDatas = apiQueueResourceDatas;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ThreadLocalContextUtil.init(context);
|
||||||
|
connectAndSendToIntermediateServer(apiQueueResourceDatas);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ContextClosedEvent event) {
|
||||||
|
genericExecutorService.shutdown();
|
||||||
|
log.info("Shutting down the ExecutorService");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-11
@@ -380,7 +380,7 @@ public class InteropServiceImpl implements InteropService {
|
|||||||
public InteropTransferResponseData prepareTransfer(@NotNull JsonCommand command) {
|
public InteropTransferResponseData prepareTransfer(@NotNull JsonCommand command) {
|
||||||
InteropTransferRequestData request = dataValidator.validateAndParseTransferRequest(command);
|
InteropTransferRequestData request = dataValidator.validateAndParseTransferRequest(command);
|
||||||
String transferCode = request.getTransferCode();
|
String transferCode = request.getTransferCode();
|
||||||
LocalDateTime transactionDate = DateUtils.getLocalDateTimeOfTenant();
|
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
// TODO validate request fee/comission and account quote amount
|
// TODO validate request fee/comission and account quote amount
|
||||||
// matching, at CREATE it is debited anyway
|
// matching, at CREATE it is debited anyway
|
||||||
@@ -401,12 +401,11 @@ public class InteropServiceImpl implements InteropService {
|
|||||||
PaymentDetail paymentDetail = instance(findPaymentType(), savingsAccount.getExternalId(), null, getRoutingCode(), transferCode,
|
PaymentDetail paymentDetail = instance(findPaymentType(), savingsAccount.getExternalId(), null, getRoutingCode(), transferCode,
|
||||||
null);
|
null);
|
||||||
SavingsAccountTransaction holdTransaction = SavingsAccountTransaction.holdAmount(savingsAccount, savingsAccount.office(),
|
SavingsAccountTransaction holdTransaction = SavingsAccountTransaction.holdAmount(savingsAccount, savingsAccount.office(),
|
||||||
paymentDetail, transactionDate.toLocalDate(), Money.of(savingsAccount.getCurrency(), total), new Date(), getLoginUser(),
|
paymentDetail, transactionDate, Money.of(savingsAccount.getCurrency(), total), new Date(), getLoginUser(), false);
|
||||||
false);
|
|
||||||
MonetaryCurrency accountCurrency = savingsAccount.getCurrency().copy();
|
MonetaryCurrency accountCurrency = savingsAccount.getCurrency().copy();
|
||||||
holdTransaction.updateRunningBalance(
|
holdTransaction.updateRunningBalance(
|
||||||
Money.of(accountCurrency, savingsAccount.getWithdrawableBalance().subtract(holdTransaction.getAmount())));
|
Money.of(accountCurrency, savingsAccount.getWithdrawableBalance().subtract(holdTransaction.getAmount())));
|
||||||
holdTransaction.updateCumulativeBalanceAndDates(accountCurrency, transactionDate.toLocalDate());
|
holdTransaction.updateCumulativeBalanceAndDates(accountCurrency, transactionDate);
|
||||||
|
|
||||||
savingsAccount.holdAmount(total);
|
savingsAccount.holdAmount(total);
|
||||||
savingsAccount.addTransaction(holdTransaction);
|
savingsAccount.addTransaction(holdTransaction);
|
||||||
@@ -415,7 +414,7 @@ public class InteropServiceImpl implements InteropService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return InteropTransferResponseData.build(command.commandId(), request.getTransactionCode(), InteropActionState.ACCEPTED,
|
return InteropTransferResponseData.build(command.commandId(), request.getTransactionCode(), InteropActionState.ACCEPTED,
|
||||||
request.getExpiration(), request.getExtensionList(), transferCode, transactionDate);
|
request.getExpiration(), request.getExtensionList(), transferCode, DateUtils.getLocalDateTimeOfTenant());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -432,7 +431,7 @@ public class InteropServiceImpl implements InteropService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LocalDateTime transactionDateTime = DateUtils.getLocalDateTimeOfTenant();
|
LocalDateTime transactionDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||||
LocalDate transactionDate = transactionDateTime.toLocalDate();
|
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
DateTimeFormatter fmt = getDateTimeFormatter(command);
|
DateTimeFormatter fmt = getDateTimeFormatter(command);
|
||||||
SavingsAccountTransaction transaction;
|
SavingsAccountTransaction transaction;
|
||||||
final boolean backdatedTxnsAllowedTill = false;
|
final boolean backdatedTxnsAllowedTill = false;
|
||||||
@@ -489,15 +488,15 @@ public class InteropServiceImpl implements InteropService {
|
|||||||
SavingsAccount savingsAccount = validateAndGetSavingAccount(request);
|
SavingsAccount savingsAccount = validateAndGetSavingAccount(request);
|
||||||
|
|
||||||
LocalDateTime transactionDateTime = DateUtils.getLocalDateTimeOfTenant();
|
LocalDateTime transactionDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||||
|
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
SavingsAccountTransaction holdTransaction = findTransaction(savingsAccount, request.getTransferCode(), AMOUNT_HOLD.getValue());
|
SavingsAccountTransaction holdTransaction = findTransaction(savingsAccount, request.getTransferCode(), AMOUNT_HOLD.getValue());
|
||||||
|
|
||||||
if (holdTransaction != null && holdTransaction.getReleaseIdOfHoldAmountTransaction() == null) {
|
if (holdTransaction != null && holdTransaction.getReleaseIdOfHoldAmountTransaction() == null) {
|
||||||
SavingsAccountTransaction releaseTransaction = releaseAmount(holdTransaction, transactionDateTime.toLocalDate(), new Date(),
|
SavingsAccountTransaction releaseTransaction = releaseAmount(holdTransaction, transactionDate, new Date(), getLoginUser());
|
||||||
getLoginUser());
|
|
||||||
MonetaryCurrency accountCurrency = savingsAccount.getCurrency().copy();
|
MonetaryCurrency accountCurrency = savingsAccount.getCurrency().copy();
|
||||||
releaseTransaction.updateRunningBalance(
|
releaseTransaction.updateRunningBalance(
|
||||||
Money.of(accountCurrency, savingsAccount.getWithdrawableBalance().add(holdTransaction.getAmount())));
|
Money.of(accountCurrency, savingsAccount.getWithdrawableBalance().add(holdTransaction.getAmount())));
|
||||||
releaseTransaction.updateCumulativeBalanceAndDates(accountCurrency, transactionDateTime.toLocalDate());
|
releaseTransaction.updateCumulativeBalanceAndDates(accountCurrency, transactionDate);
|
||||||
releaseTransaction = savingsAccountTransactionRepository.saveAndFlush(releaseTransaction);
|
releaseTransaction = savingsAccountTransactionRepository.saveAndFlush(releaseTransaction);
|
||||||
holdTransaction.updateReleaseId(releaseTransaction.getId());
|
holdTransaction.updateReleaseId(releaseTransaction.getId());
|
||||||
|
|
||||||
@@ -536,8 +535,6 @@ public class InteropServiceImpl implements InteropService {
|
|||||||
Loan loan = validateAndGetLoan(accountId);
|
Loan loan = validateAndGetLoan(accountId);
|
||||||
Long loanId = loan.getId();
|
Long loanId = loan.getId();
|
||||||
|
|
||||||
LocalDateTime disbursedOnDate = DateUtils.getLocalDateTimeOfTenant();
|
|
||||||
|
|
||||||
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
|
||||||
|
|
||||||
final CommandWrapper commandRequest = builder.disburseLoanApplication(loanId).build();
|
final CommandWrapper commandRequest = builder.disburseLoanApplication(loanId).build();
|
||||||
|
|||||||
+5
-4
@@ -18,16 +18,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.notification.eventandlistener;
|
package org.apache.fineract.notification.eventandlistener;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractContext;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractEvent;
|
||||||
import org.apache.fineract.notification.data.NotificationData;
|
import org.apache.fineract.notification.data.NotificationData;
|
||||||
import org.springframework.context.ApplicationEvent;
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class SpringEvent extends ApplicationEvent {
|
public class NotificationEvent extends FineractEvent {
|
||||||
|
|
||||||
private NotificationData notificationData;
|
private NotificationData notificationData;
|
||||||
|
|
||||||
public SpringEvent(Object source, NotificationData notificationData) {
|
public NotificationEvent(Object source, NotificationData notificationData, FineractContext context) {
|
||||||
super(source);
|
super(source, context);
|
||||||
this.notificationData = notificationData;
|
this.notificationData = notificationData;
|
||||||
}
|
}
|
||||||
|
|
||||||
-8
@@ -23,9 +23,6 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
|
||||||
import org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetailsService;
|
|
||||||
import org.apache.fineract.notification.data.NotificationData;
|
import org.apache.fineract.notification.data.NotificationData;
|
||||||
import org.apache.fineract.notification.service.NotificationWritePlatformService;
|
import org.apache.fineract.notification.service.NotificationWritePlatformService;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
@@ -36,15 +33,10 @@ import org.springframework.stereotype.Service;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class NotificationEventListener {
|
public class NotificationEventListener {
|
||||||
|
|
||||||
private final BasicAuthTenantDetailsService basicAuthTenantDetailsService;
|
|
||||||
private final NotificationWritePlatformService notificationWritePlatformService;
|
private final NotificationWritePlatformService notificationWritePlatformService;
|
||||||
private final AppUserRepository appUserRepository;
|
private final AppUserRepository appUserRepository;
|
||||||
|
|
||||||
public void receive(NotificationData notificationData) {
|
public void receive(NotificationData notificationData) {
|
||||||
final FineractPlatformTenant tenant = this.basicAuthTenantDetailsService.loadTenantById(notificationData.getTenantIdentifier(),
|
|
||||||
false);
|
|
||||||
ThreadLocalContextUtil.setTenant(tenant);
|
|
||||||
|
|
||||||
Long appUserId = notificationData.getActorId();
|
Long appUserId = notificationData.getActorId();
|
||||||
|
|
||||||
Set<Long> userIds = notificationData.getUserIds();
|
Set<Long> userIds = notificationData.getUserIds();
|
||||||
|
|||||||
+4
-2
@@ -20,6 +20,7 @@ package org.apache.fineract.notification.eventandlistener;
|
|||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.apache.fineract.notification.data.NotificationData;
|
import org.apache.fineract.notification.data.NotificationData;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.context.annotation.Profile;
|
import org.springframework.context.annotation.Profile;
|
||||||
@@ -29,13 +30,14 @@ import org.springframework.stereotype.Component;
|
|||||||
@Profile("!activeMqEnabled")
|
@Profile("!activeMqEnabled")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SpringNotificationEventListener implements ApplicationListener<SpringEvent> {
|
public class SpringNotificationEventListener implements ApplicationListener<NotificationEvent> {
|
||||||
|
|
||||||
private final NotificationEventListener notificationEventListener;
|
private final NotificationEventListener notificationEventListener;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onApplicationEvent(SpringEvent event) {
|
public void onApplicationEvent(NotificationEvent event) {
|
||||||
log.debug("Processing Spring notification event {}", event);
|
log.debug("Processing Spring notification event {}", event);
|
||||||
|
ThreadLocalContextUtil.init(event.getContext());
|
||||||
NotificationData notificationData = event.getNotificationData();
|
NotificationData notificationData = event.getNotificationData();
|
||||||
notificationEventListener.receive(notificationData);
|
notificationEventListener.receive(notificationData);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -20,6 +20,7 @@ package org.apache.fineract.notification.eventandlistener;
|
|||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
import org.apache.fineract.notification.data.NotificationData;
|
import org.apache.fineract.notification.data.NotificationData;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.context.annotation.Profile;
|
import org.springframework.context.annotation.Profile;
|
||||||
@@ -36,7 +37,8 @@ public class SpringNotificationEventPublisher implements NotificationEventPublis
|
|||||||
@Override
|
@Override
|
||||||
public void broadcastNotification(final NotificationData notificationData) {
|
public void broadcastNotification(final NotificationData notificationData) {
|
||||||
log.debug("Sending Spring notification event: {}", notificationData);
|
log.debug("Sending Spring notification event: {}", notificationData);
|
||||||
SpringEvent event = new SpringEvent(this, notificationData);
|
NotificationEvent event = new NotificationEvent(SpringNotificationEventPublisher.class, notificationData,
|
||||||
|
ThreadLocalContextUtil.getContext());
|
||||||
applicationEventPublisher.publishEvent(event);
|
applicationEventPublisher.publishEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -161,7 +161,7 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// defaults
|
// defaults
|
||||||
final LocalDate transferDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate transferDate = DateUtils.getBusinessLocalDate();
|
||||||
Collection<OfficeData> toOfficeOptions = fromOfficeOptions;
|
Collection<OfficeData> toOfficeOptions = fromOfficeOptions;
|
||||||
Collection<ClientData> toClientOptions = null;
|
Collection<ClientData> toClientOptions = null;
|
||||||
|
|
||||||
@@ -516,7 +516,7 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// defaults
|
// defaults
|
||||||
final LocalDate transferDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate transferDate = DateUtils.getBusinessLocalDate();
|
||||||
Collection<OfficeData> toOfficeOptions = fromOfficeOptions;
|
Collection<OfficeData> toOfficeOptions = fromOfficeOptions;
|
||||||
Collection<ClientData> toClientOptions = null;
|
Collection<ClientData> toClientOptions = null;
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -294,10 +294,14 @@ public class PortfolioAccountReadPlatformServiceImpl implements PortfolioAccount
|
|||||||
|
|
||||||
private static final class PortfolioLoanAccountRefundByTransferMapper implements RowMapper<PortfolioAccountData> {
|
private static final class PortfolioLoanAccountRefundByTransferMapper implements RowMapper<PortfolioAccountData> {
|
||||||
|
|
||||||
private final String schemaSql;
|
private String schemaSql;
|
||||||
|
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||||
|
|
||||||
PortfolioLoanAccountRefundByTransferMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
|
PortfolioLoanAccountRefundByTransferMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
|
||||||
|
this.sqlGenerator = sqlGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String schema() {
|
||||||
final StringBuilder amountQueryString = new StringBuilder(400);
|
final StringBuilder amountQueryString = new StringBuilder(400);
|
||||||
amountQueryString.append("(select (SUM(COALESCE(mr.principal_completed_derived, 0)) +");
|
amountQueryString.append("(select (SUM(COALESCE(mr.principal_completed_derived, 0)) +");
|
||||||
amountQueryString.append("SUM(COALESCE(mr.interest_completed_derived, 0)) + ");
|
amountQueryString.append("SUM(COALESCE(mr.interest_completed_derived, 0)) + ");
|
||||||
@@ -305,7 +309,7 @@ public class PortfolioAccountReadPlatformServiceImpl implements PortfolioAccount
|
|||||||
amountQueryString.append(" SUM(COALESCE(mr.penalty_charges_completed_derived, 0))) as total_in_advance_derived");
|
amountQueryString.append(" SUM(COALESCE(mr.penalty_charges_completed_derived, 0))) as total_in_advance_derived");
|
||||||
amountQueryString.append(" from m_loan ml INNER JOIN m_loan_repayment_schedule mr on mr.loan_id = ml.id");
|
amountQueryString.append(" from m_loan ml INNER JOIN m_loan_repayment_schedule mr on mr.loan_id = ml.id");
|
||||||
amountQueryString.append(" where ml.id=? and ml.loan_status_id = 300");
|
amountQueryString.append(" where ml.id=? and ml.loan_status_id = 300");
|
||||||
amountQueryString.append(" and mr.duedate >= " + sqlGenerator.currentDate() + " group by ml.id having");
|
amountQueryString.append(" and mr.duedate >= " + sqlGenerator.currentBusinessDate() + " group by ml.id having");
|
||||||
amountQueryString.append(" (SUM(COALESCE(mr.principal_completed_derived, 0)) + ");
|
amountQueryString.append(" (SUM(COALESCE(mr.principal_completed_derived, 0)) + ");
|
||||||
amountQueryString.append(" SUM(COALESCE(mr.interest_completed_derived, 0)) + ");
|
amountQueryString.append(" SUM(COALESCE(mr.interest_completed_derived, 0)) + ");
|
||||||
amountQueryString.append("SUM(COALESCE(mr.fee_charges_completed_derived, 0)) + ");
|
amountQueryString.append("SUM(COALESCE(mr.fee_charges_completed_derived, 0)) + ");
|
||||||
@@ -331,9 +335,7 @@ public class PortfolioAccountReadPlatformServiceImpl implements PortfolioAccount
|
|||||||
sqlBuilder.append("left join m_staff s ON s.id = la.loan_officer_id ");
|
sqlBuilder.append("left join m_staff s ON s.id = la.loan_officer_id ");
|
||||||
|
|
||||||
this.schemaSql = sqlBuilder.toString();
|
this.schemaSql = sqlBuilder.toString();
|
||||||
}
|
|
||||||
|
|
||||||
public String schema() {
|
|
||||||
return this.schemaSql;
|
return this.schemaSql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -186,7 +186,7 @@ public class StandingInstructionReadPlatformServiceImpl implements StandingInstr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// defaults
|
// defaults
|
||||||
final LocalDate transferDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate transferDate = DateUtils.getBusinessLocalDate();
|
||||||
Collection<OfficeData> toOfficeOptions = fromOfficeOptions;
|
Collection<OfficeData> toOfficeOptions = fromOfficeOptions;
|
||||||
Collection<ClientData> toClientOptions = null;
|
Collection<ClientData> toClientOptions = null;
|
||||||
|
|
||||||
@@ -334,12 +334,13 @@ public class StandingInstructionReadPlatformServiceImpl implements StandingInstr
|
|||||||
@Override
|
@Override
|
||||||
public Collection<StandingInstructionData> retrieveAll(final Integer status) {
|
public Collection<StandingInstructionData> retrieveAll(final Integer status) {
|
||||||
final StringBuilder sqlBuilder = new StringBuilder(200);
|
final StringBuilder sqlBuilder = new StringBuilder(200);
|
||||||
|
String businessDate = sqlGenerator.currentBusinessDate();
|
||||||
sqlBuilder.append("select ");
|
sqlBuilder.append("select ");
|
||||||
sqlBuilder.append(this.standingInstructionMapper.schema());
|
sqlBuilder.append(this.standingInstructionMapper.schema());
|
||||||
sqlBuilder
|
sqlBuilder
|
||||||
.append(" where atsi.status=? and " + sqlGenerator.currentDate() + " >= atsi.valid_from and (atsi.valid_till IS NULL or "
|
.append(" where atsi.status=? and " + businessDate + " >= atsi.valid_from and (atsi.valid_till IS NULL or " + businessDate
|
||||||
+ sqlGenerator.currentDate() + " < atsi.valid_till) ")
|
+ " < atsi.valid_till) ")
|
||||||
.append(" and (atsi.last_run_date <> " + sqlGenerator.currentDate() + " or atsi.last_run_date IS NULL)")
|
.append(" and (atsi.last_run_date <> " + businessDate + " or atsi.last_run_date IS NULL)")
|
||||||
.append(" ORDER BY atsi.priority DESC");
|
.append(" ORDER BY atsi.priority DESC");
|
||||||
return this.jdbcTemplate.query(sqlBuilder.toString(), this.standingInstructionMapper, status);
|
return this.jdbcTemplate.query(sqlBuilder.toString(), this.standingInstructionMapper, status);
|
||||||
}
|
}
|
||||||
@@ -359,7 +360,7 @@ public class StandingInstructionReadPlatformServiceImpl implements StandingInstr
|
|||||||
@Override
|
@Override
|
||||||
public StandingInstructionDuesData retriveLoanDuesData(final Long loanId) {
|
public StandingInstructionDuesData retriveLoanDuesData(final Long loanId) {
|
||||||
final StandingInstructionLoanDuesMapper rm = new StandingInstructionLoanDuesMapper();
|
final StandingInstructionLoanDuesMapper rm = new StandingInstructionLoanDuesMapper();
|
||||||
final String sql = "select " + rm.schema() + " where ml.id= ? and ls.duedate <= " + sqlGenerator.currentDate()
|
final String sql = "select " + rm.schema() + " where ml.id= ? and ls.duedate <= " + sqlGenerator.currentBusinessDate()
|
||||||
+ " and ls.completed_derived <> 1";
|
+ " and ls.completed_derived <> 1";
|
||||||
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { loanId }); // NOSONAR
|
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { loanId }); // NOSONAR
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -199,7 +199,7 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
|
|||||||
Collection<StandingInstructionData> instructionDatas = this.standingInstructionReadPlatformService
|
Collection<StandingInstructionData> instructionDatas = this.standingInstructionReadPlatformService
|
||||||
.retrieveAll(StandingInstructionStatus.ACTIVE.getValue());
|
.retrieveAll(StandingInstructionStatus.ACTIVE.getValue());
|
||||||
List<Throwable> errors = new ArrayList<>();
|
List<Throwable> errors = new ArrayList<>();
|
||||||
LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
for (StandingInstructionData data : instructionDatas) {
|
for (StandingInstructionData data : instructionDatas) {
|
||||||
boolean isDueForTransfer = false;
|
boolean isDueForTransfer = false;
|
||||||
AccountTransferRecurrenceType recurrenceType = data.recurrenceType();
|
AccountTransferRecurrenceType recurrenceType = data.recurrenceType();
|
||||||
@@ -232,7 +232,7 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
|
|||||||
transactionAmount = standingInstructionDuesData.totalDueAmount();
|
transactionAmount = standingInstructionDuesData.totalDueAmount();
|
||||||
}
|
}
|
||||||
if (recurrenceType.isDuesRecurrence()) {
|
if (recurrenceType.isDuesRecurrence()) {
|
||||||
isDueForTransfer = LocalDate.now(DateUtils.getDateTimeZoneOfTenant()).equals(standingInstructionDuesData.dueDate());
|
isDueForTransfer = DateUtils.getBusinessLocalDate().equals(standingInstructionDuesData.dueDate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +265,7 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
|
|||||||
StringBuilder errorLog = new StringBuilder();
|
StringBuilder errorLog = new StringBuilder();
|
||||||
StringBuilder updateQuery = new StringBuilder(
|
StringBuilder updateQuery = new StringBuilder(
|
||||||
"INSERT INTO m_account_transfer_standing_instructions_history (standing_instruction_id, " + sqlGenerator.escape("status")
|
"INSERT INTO m_account_transfer_standing_instructions_history (standing_instruction_id, " + sqlGenerator.escape("status")
|
||||||
+ ", amount,execution_time, error_log) VALUES (");
|
+ ", amount, execution_time, error_log) VALUES (");
|
||||||
try {
|
try {
|
||||||
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
|
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
|
||||||
} catch (final PlatformApiDataValidationException e) {
|
} catch (final PlatformApiDataValidationException e) {
|
||||||
@@ -294,8 +294,8 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
|
|||||||
updateQuery.append("'success'").append(",");
|
updateQuery.append("'success'").append(",");
|
||||||
}
|
}
|
||||||
updateQuery.append(accountTransferDTO.getTransactionAmount().doubleValue());
|
updateQuery.append(accountTransferDTO.getTransactionAmount().doubleValue());
|
||||||
updateQuery.append(", now(),");
|
updateQuery.append(", ").append(sqlGenerator.currentTenantDateTime()).append(" ");
|
||||||
updateQuery.append("'").append(errorLog.toString()).append("')");
|
updateQuery.append(", '").append(errorLog).append("')");
|
||||||
this.jdbcTemplate.update(updateQuery.toString());
|
this.jdbcTemplate.update(updateQuery.toString());
|
||||||
return transferCompleted;
|
return transferCompleted;
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -190,7 +190,7 @@ public final class ClientDataValidator {
|
|||||||
if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.dateOfBirthParamName, element)) {
|
if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.dateOfBirthParamName, element)) {
|
||||||
final LocalDate dateOfBirth = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.dateOfBirthParamName, element);
|
final LocalDate dateOfBirth = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.dateOfBirthParamName, element);
|
||||||
baseDataValidator.reset().parameter(ClientApiConstants.dateOfBirthParamName).value(dateOfBirth).notNull()
|
baseDataValidator.reset().parameter(ClientApiConstants.dateOfBirthParamName).value(dateOfBirth).notNull()
|
||||||
.validateDateBefore(DateUtils.getLocalDateOfTenant()).validateDateBefore(submittedOnDate);
|
.validateDateBefore(DateUtils.getBusinessLocalDate()).validateDateBefore(submittedOnDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.genderIdParamName, element)) {
|
if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.genderIdParamName, element)) {
|
||||||
@@ -497,7 +497,7 @@ public final class ClientDataValidator {
|
|||||||
atLeastOneParameterPassedForUpdate = true;
|
atLeastOneParameterPassedForUpdate = true;
|
||||||
final LocalDate dateOfBirth = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.dateOfBirthParamName, element);
|
final LocalDate dateOfBirth = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.dateOfBirthParamName, element);
|
||||||
baseDataValidator.reset().parameter(ClientApiConstants.dateOfBirthParamName).value(dateOfBirth).notNull()
|
baseDataValidator.reset().parameter(ClientApiConstants.dateOfBirthParamName).value(dateOfBirth).notNull()
|
||||||
.validateDateBefore(DateUtils.getLocalDateOfTenant()).validateDateBefore(submittedDate);
|
.validateDateBefore(DateUtils.getBusinessLocalDate()).validateDateBefore(submittedDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.legalFormIdParamName, element)) {
|
if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.legalFormIdParamName, element)) {
|
||||||
@@ -824,7 +824,7 @@ public final class ClientDataValidator {
|
|||||||
|
|
||||||
final LocalDate undoRejectionDate = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.reopenedDateParamName, element);
|
final LocalDate undoRejectionDate = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.reopenedDateParamName, element);
|
||||||
baseDataValidator.reset().parameter(ClientApiConstants.reopenedDateParamName).value(undoRejectionDate).notNull()
|
baseDataValidator.reset().parameter(ClientApiConstants.reopenedDateParamName).value(undoRejectionDate).notNull()
|
||||||
.validateDateBeforeOrEqual(DateUtils.getLocalDateOfTenant());
|
.validateDateBeforeOrEqual(DateUtils.getBusinessLocalDate());
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
|
|
||||||
@@ -850,7 +850,7 @@ public final class ClientDataValidator {
|
|||||||
|
|
||||||
final LocalDate undoWithdrawnDate = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.reopenedDateParamName, element);
|
final LocalDate undoWithdrawnDate = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.reopenedDateParamName, element);
|
||||||
baseDataValidator.reset().parameter(ClientApiConstants.reopenedDateParamName).value(undoWithdrawnDate).notNull()
|
baseDataValidator.reset().parameter(ClientApiConstants.reopenedDateParamName).value(undoWithdrawnDate).notNull()
|
||||||
.validateDateBeforeOrEqual(DateUtils.getLocalDateOfTenant());
|
.validateDateBeforeOrEqual(DateUtils.getBusinessLocalDate());
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -273,7 +273,7 @@ public final class Client extends AbstractPersistableCustom {
|
|||||||
officeJoiningDate = activationDate;
|
officeJoiningDate = activationDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDate submittedOnDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
|
||||||
if (active && submittedOnDate.isAfter(activationDate)) {
|
if (active && submittedOnDate.isAfter(activationDate)) {
|
||||||
submittedOnDate = activationDate;
|
submittedOnDate = activationDate;
|
||||||
}
|
}
|
||||||
@@ -486,7 +486,7 @@ public final class Client extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDateInTheFuture(final LocalDate localDate) {
|
private boolean isDateInTheFuture(final LocalDate localDate) {
|
||||||
return localDate.isAfter(DateUtils.getLocalDateOfTenant());
|
return localDate.isAfter(DateUtils.getBusinessLocalDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRejected() {
|
public boolean isRejected() {
|
||||||
|
|||||||
+2
-5
@@ -24,7 +24,6 @@ import com.google.gson.JsonElement;
|
|||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -162,7 +161,7 @@ public final class ClientFamilyMemberCommandFromApiJsonDeserializer {
|
|||||||
if (this.fromApiJsonHelper.extractLocalDateNamed("dateOfBirth", element) != null) {
|
if (this.fromApiJsonHelper.extractLocalDateNamed("dateOfBirth", element) != null) {
|
||||||
final LocalDate dateOfBirth = this.fromApiJsonHelper.extractLocalDateNamed("dateOfBirth", element);
|
final LocalDate dateOfBirth = this.fromApiJsonHelper.extractLocalDateNamed("dateOfBirth", element);
|
||||||
baseDataValidator.reset().parameter("dateOfBirth").value(dateOfBirth).value(dateOfBirth).notNull()
|
baseDataValidator.reset().parameter("dateOfBirth").value(dateOfBirth).value(dateOfBirth).notNull()
|
||||||
.validateDateBefore(DateUtils.getLocalDateOfTenant());
|
.validateDateBefore(DateUtils.getBusinessLocalDate());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,10 +228,8 @@ public final class ClientFamilyMemberCommandFromApiJsonDeserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.fromApiJsonHelper.extractLocalDateNamed("dateOfBirth", element) != null) {
|
if (this.fromApiJsonHelper.extractLocalDateNamed("dateOfBirth", element) != null) {
|
||||||
LocalDateTime currentDate = LocalDateTime.now(DateUtils.getDateTimeZoneOfTenant());
|
|
||||||
|
|
||||||
final LocalDate dateOfBirth = this.fromApiJsonHelper.extractLocalDateNamed("dateOfBirth", element);
|
final LocalDate dateOfBirth = this.fromApiJsonHelper.extractLocalDateNamed("dateOfBirth", element);
|
||||||
baseDataValidator.reset().parameter("dateOfBirth").value(dateOfBirth).validateDateBefore(currentDate.toLocalDate());
|
baseDataValidator.reset().parameter("dateOfBirth").value(dateOfBirth).validateDateBefore(DateUtils.getBusinessLocalDate());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -207,7 +207,7 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client
|
|||||||
try {
|
try {
|
||||||
final Client client = this.clientRepository.getActiveClientInUserScope(clientId);
|
final Client client = this.clientRepository.getActiveClientInUserScope(clientId);
|
||||||
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
|
final ClientCharge clientCharge = this.clientChargeRepository.findOneWithNotFoundDetection(clientChargeId);
|
||||||
final LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
// Validate business rules for payment
|
// Validate business rules for payment
|
||||||
validateWaiverTransaction(client, clientCharge);
|
validateWaiverTransaction(client, clientCharge);
|
||||||
|
|||||||
+1
-1
@@ -134,7 +134,7 @@ public class CollectionSheetTransactionDataValidator {
|
|||||||
final LocalDate transactionDate = this.fromApiJsonHelper.extractLocalDateNamed(CollectionSheetConstants.transactionDateParamName,
|
final LocalDate transactionDate = this.fromApiJsonHelper.extractLocalDateNamed(CollectionSheetConstants.transactionDateParamName,
|
||||||
element);
|
element);
|
||||||
baseDataValidator.reset().parameter(CollectionSheetConstants.transactionDateParamName).value(transactionDate).notNull()
|
baseDataValidator.reset().parameter(CollectionSheetConstants.transactionDateParamName).value(transactionDate).notNull()
|
||||||
.validateDateBeforeOrEqual(DateUtils.getLocalDateOfTenant());
|
.validateDateBeforeOrEqual(DateUtils.getBusinessLocalDate());
|
||||||
|
|
||||||
final String note = this.fromApiJsonHelper.extractStringNamed(CollectionSheetConstants.noteParamName, element);
|
final String note = this.fromApiJsonHelper.extractStringNamed(CollectionSheetConstants.noteParamName, element);
|
||||||
if (StringUtils.isNotBlank(note)) {
|
if (StringUtils.isNotBlank(note)) {
|
||||||
|
|||||||
+5
-6
@@ -49,6 +49,7 @@ import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO;
|
|||||||
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
|
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
|
|
||||||
|
//TODO: refactor to use AbstractAuditableCustom!
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "m_floating_rates", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "unq_name") })
|
@Table(name = "m_floating_rates", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "unq_name") })
|
||||||
public class FloatingRate extends AbstractPersistableCustom {
|
public class FloatingRate extends AbstractPersistableCustom {
|
||||||
@@ -109,11 +110,9 @@ public class FloatingRate extends AbstractPersistableCustom {
|
|||||||
: false;
|
: false;
|
||||||
final boolean isActive = command.parameterExists("isActive") ? command.booleanPrimitiveValueOfParameterNamed("isActive") : true;
|
final boolean isActive = command.parameterExists("isActive") ? command.booleanPrimitiveValueOfParameterNamed("isActive") : true;
|
||||||
final List<FloatingRatePeriod> floatingRatePeriods = getRatePeriods(currentUser, command);
|
final List<FloatingRatePeriod> floatingRatePeriods = getRatePeriods(currentUser, command);
|
||||||
final LocalDate currentDate = DateUtils.getLocalDateOfTenant();
|
final Date currentDate = DateUtils.getBusinessDate();
|
||||||
|
|
||||||
return new FloatingRate(name, isBaseLendingRate, isActive, floatingRatePeriods, currentUser, currentUser,
|
return new FloatingRate(name, isBaseLendingRate, isActive, floatingRatePeriods, currentUser, currentUser, currentDate, currentDate);
|
||||||
Date.from(currentDate.atStartOfDay(ZoneId.systemDefault()).toInstant()),
|
|
||||||
Date.from(currentDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<FloatingRatePeriod> getRatePeriods(final AppUser currentUser, final JsonCommand command) {
|
private static List<FloatingRatePeriod> getRatePeriods(final AppUser currentUser, final JsonCommand command) {
|
||||||
@@ -132,7 +131,7 @@ public class FloatingRate extends AbstractPersistableCustom {
|
|||||||
? ratePeriodObject.get("isDifferentialToBaseLendingRate").getAsBoolean()
|
? ratePeriodObject.get("isDifferentialToBaseLendingRate").getAsBoolean()
|
||||||
: false;
|
: false;
|
||||||
final boolean isActive = true;
|
final boolean isActive = true;
|
||||||
final Date currentDate = DateUtils.getDateOfTenant();
|
final Date currentDate = DateUtils.getBusinessDate();
|
||||||
ratePeriods.add(new FloatingRatePeriod(fromDate, interestRate, isDifferentialToBaseLendingRate, isActive, currentUser,
|
ratePeriods.add(new FloatingRatePeriod(fromDate, interestRate, isDifferentialToBaseLendingRate, isActive, currentUser,
|
||||||
currentUser, currentDate, currentDate));
|
currentUser, currentDate, currentDate));
|
||||||
}
|
}
|
||||||
@@ -204,7 +203,7 @@ public class FloatingRate extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateRatePeriods(final List<FloatingRatePeriod> newRatePeriods, final AppUser appUser) {
|
private void updateRatePeriods(final List<FloatingRatePeriod> newRatePeriods, final AppUser appUser) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||||
if (this.floatingRatePeriods != null) {
|
if (this.floatingRatePeriods != null) {
|
||||||
for (FloatingRatePeriod ratePeriod : this.floatingRatePeriods) {
|
for (FloatingRatePeriod ratePeriod : this.floatingRatePeriods) {
|
||||||
LocalDate fromDate = LocalDate.ofInstant(ratePeriod.getFromDate().toInstant(), DateUtils.getDateTimeZoneOfTenant());
|
LocalDate fromDate = LocalDate.ofInstant(ratePeriod.getFromDate().toInstant(), DateUtils.getDateTimeZoneOfTenant());
|
||||||
|
|||||||
+1
@@ -34,6 +34,7 @@ import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO;
|
|||||||
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
|
import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
|
|
||||||
|
//TODO: refactor to use AbstractAuditableCustom!
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "m_floating_rates_periods")
|
@Table(name = "m_floating_rates_periods")
|
||||||
public class FloatingRatePeriod extends AbstractPersistableCustom {
|
public class FloatingRatePeriod extends AbstractPersistableCustom {
|
||||||
|
|||||||
+1
-1
@@ -117,7 +117,7 @@ public class FloatingRateDataValidator {
|
|||||||
|
|
||||||
final LocalDate fromDate = this.fromApiJsonHelper.extractLocalDateNamed("fromDate", ratePeriod);
|
final LocalDate fromDate = this.fromApiJsonHelper.extractLocalDateNamed("fromDate", ratePeriod);
|
||||||
baseDataValidator.reset().parameter("fromDate").parameterAtIndexArray("fromDate", i + 1).value(fromDate).notBlank()
|
baseDataValidator.reset().parameter("fromDate").parameterAtIndexArray("fromDate", i + 1).value(fromDate).notBlank()
|
||||||
.validateDateAfter(DateUtils.getLocalDateOfTenant().plusDays(1));
|
.validateDateAfter(DateUtils.getBusinessLocalDate().plusDays(1));
|
||||||
if (fromDate != null) {
|
if (fromDate != null) {
|
||||||
fromDates.add(fromDate);
|
fromDates.add(fromDate);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -283,7 +283,7 @@ public final class Group extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDateInTheFuture(final LocalDate localDate) {
|
private boolean isDateInTheFuture(final LocalDate localDate) {
|
||||||
return localDate.isAfter(DateUtils.getLocalDateOfTenant());
|
return localDate.isAfter(DateUtils.getBusinessLocalDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isNotPending() {
|
public boolean isNotPending() {
|
||||||
@@ -446,7 +446,7 @@ public final class Group extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
public void updateStaff(final Staff staff) {
|
public void updateStaff(final Staff staff) {
|
||||||
if (this.isCenter() && this.isActive()) {
|
if (this.isCenter() && this.isActive()) {
|
||||||
LocalDate updatedDate = DateUtils.getLocalDateOfTenant();
|
LocalDate updatedDate = DateUtils.getBusinessLocalDate();
|
||||||
reassignStaff(staff, updatedDate);
|
reassignStaff(staff, updatedDate);
|
||||||
}
|
}
|
||||||
this.staff = staff;
|
this.staff = staff;
|
||||||
@@ -454,7 +454,7 @@ public final class Group extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
public void unassignStaff() {
|
public void unassignStaff() {
|
||||||
if (this.isCenter() && this.isActive()) {
|
if (this.isCenter() && this.isActive()) {
|
||||||
LocalDate dateOfStaffUnassigned = DateUtils.getLocalDateOfTenant();
|
LocalDate dateOfStaffUnassigned = DateUtils.getBusinessLocalDate();
|
||||||
removeStaff(dateOfStaffUnassigned);
|
removeStaff(dateOfStaffUnassigned);
|
||||||
}
|
}
|
||||||
this.staff = null;
|
this.staff = null;
|
||||||
|
|||||||
+2
-2
@@ -154,7 +154,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
|||||||
final Set<Group> groupMembers = assembleSetOfChildGroups(officeId, command);
|
final Set<Group> groupMembers = assembleSetOfChildGroups(officeId, command);
|
||||||
|
|
||||||
final boolean active = command.booleanPrimitiveValueOfParameterNamed(GroupingTypesApiConstants.activeParamName);
|
final boolean active = command.booleanPrimitiveValueOfParameterNamed(GroupingTypesApiConstants.activeParamName);
|
||||||
LocalDate submittedOnDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
LocalDate submittedOnDate = DateUtils.getBusinessLocalDate();
|
||||||
if (active && submittedOnDate.isAfter(activationDate)) {
|
if (active && submittedOnDate.isAfter(activationDate)) {
|
||||||
submittedOnDate = activationDate;
|
submittedOnDate = activationDate;
|
||||||
}
|
}
|
||||||
@@ -509,7 +509,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
|||||||
groupForUpdate.updateStaff(staff);
|
groupForUpdate.updateStaff(staff);
|
||||||
|
|
||||||
if (inheritStaffForClientAccounts) {
|
if (inheritStaffForClientAccounts) {
|
||||||
LocalDate loanOfficerReassignmentDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
LocalDate loanOfficerReassignmentDate = DateUtils.getBusinessLocalDate();
|
||||||
/*
|
/*
|
||||||
* update loan officer for client and update loan officer for clients loans and savings
|
* update loan officer for client and update loan officer for clients loans and savings
|
||||||
*/
|
*/
|
||||||
|
|||||||
+3
-3
@@ -154,10 +154,10 @@ public class InterestRateChartFields {
|
|||||||
public boolean isOverlapping(InterestRateChartFields that) {
|
public boolean isOverlapping(InterestRateChartFields that) {
|
||||||
final LocalDate thisFromDate = this.getFromDateAsLocalDate();
|
final LocalDate thisFromDate = this.getFromDateAsLocalDate();
|
||||||
LocalDate thisEndDate = this.getEndDateAsLocalDate();
|
LocalDate thisEndDate = this.getEndDateAsLocalDate();
|
||||||
thisEndDate = thisEndDate == null ? DateUtils.getLocalDateOfTenant() : thisEndDate;
|
thisEndDate = thisEndDate == null ? DateUtils.getBusinessLocalDate() : thisEndDate;
|
||||||
final LocalDate thatFromDate = that.getFromDateAsLocalDate();
|
final LocalDate thatFromDate = that.getFromDateAsLocalDate();
|
||||||
LocalDate thatEndDate = that.getEndDateAsLocalDate();
|
LocalDate thatEndDate = that.getEndDateAsLocalDate();
|
||||||
thatEndDate = thatEndDate == null ? DateUtils.getLocalDateOfTenant() : thatEndDate;
|
thatEndDate = thatEndDate == null ? DateUtils.getBusinessLocalDate() : thatEndDate;
|
||||||
|
|
||||||
final LocalDateInterval thisInterval = LocalDateInterval.create(thisFromDate, thisEndDate);
|
final LocalDateInterval thisInterval = LocalDateInterval.create(thisFromDate, thisEndDate);
|
||||||
final LocalDateInterval thatInterval = LocalDateInterval.create(thatFromDate, thatEndDate);
|
final LocalDateInterval thatInterval = LocalDateInterval.create(thatFromDate, thatEndDate);
|
||||||
@@ -169,7 +169,7 @@ public class InterestRateChartFields {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isApplicableChartFor(final LocalDate target) {
|
public boolean isApplicableChartFor(final LocalDate target) {
|
||||||
final LocalDate endDate = this.endDate == null ? DateUtils.getLocalDateOfTenant() : this.getEndDateAsLocalDate();
|
final LocalDate endDate = this.endDate == null ? DateUtils.getBusinessLocalDate() : this.getEndDateAsLocalDate();
|
||||||
final LocalDateInterval interval = LocalDateInterval.create(getFromDateAsLocalDate(), endDate);
|
final LocalDateInterval interval = LocalDateInterval.create(getFromDateAsLocalDate(), endDate);
|
||||||
return interval.contains(target);
|
return interval.contains(target);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -42,12 +42,11 @@ public class ClientAttributeIncentiveCalculation extends AttributeIncentiveCalcu
|
|||||||
break;
|
break;
|
||||||
case AGE:
|
case AGE:
|
||||||
if (client.dateOfBirth() != null) {
|
if (client.dateOfBirth() != null) {
|
||||||
final LocalDate dobLacalDate = LocalDate.ofInstant(client.dateOfBirth().toInstant(),
|
final LocalDate dobLocalDate = LocalDate.ofInstant(client.dateOfBirth().toInstant(),
|
||||||
DateUtils.getDateTimeZoneOfTenant());
|
DateUtils.getDateTimeZoneOfTenant());
|
||||||
final int age = Math
|
final int age = Math.toIntExact(ChronoUnit.YEARS.between(dobLocalDate, DateUtils.getBusinessLocalDate()));
|
||||||
.toIntExact(ChronoUnit.YEARS.between(dobLacalDate, LocalDate.now(DateUtils.getDateTimeZoneOfTenant())));
|
|
||||||
applyIncentive = applyIncentive(incentivesFields.conditionType(), Long.valueOf(incentivesFields.attributeValue()),
|
applyIncentive = applyIncentive(incentivesFields.conditionType(), Long.valueOf(incentivesFields.attributeValue()),
|
||||||
Long.valueOf(age));
|
(long) age);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLIENT_TYPE:
|
case CLIENT_TYPE:
|
||||||
|
|||||||
+5
-5
@@ -135,15 +135,15 @@ public class LoanTransactionsApiResource {
|
|||||||
if (is(commandParam, "repayment")) {
|
if (is(commandParam, "repayment")) {
|
||||||
transactionData = this.loanReadPlatformService.retrieveLoanTransactionTemplate(loanId);
|
transactionData = this.loanReadPlatformService.retrieveLoanTransactionTemplate(loanId);
|
||||||
} else if (is(commandParam, "merchantIssuedRefund")) {
|
} else if (is(commandParam, "merchantIssuedRefund")) {
|
||||||
LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
transactionData = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(LoanTransactionType.MERCHANT_ISSUED_REFUND,
|
transactionData = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(LoanTransactionType.MERCHANT_ISSUED_REFUND,
|
||||||
loanId, transactionDate);
|
loanId, transactionDate);
|
||||||
} else if (is(commandParam, "payoutRefund")) {
|
} else if (is(commandParam, "payoutRefund")) {
|
||||||
LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
transactionData = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(LoanTransactionType.PAYOUT_REFUND, loanId,
|
transactionData = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(LoanTransactionType.PAYOUT_REFUND, loanId,
|
||||||
transactionDate);
|
transactionDate);
|
||||||
} else if (is(commandParam, "goodwillCredit")) {
|
} else if (is(commandParam, "goodwillCredit")) {
|
||||||
LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
transactionData = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(LoanTransactionType.GOODWILL_CREDIT, loanId,
|
transactionData = this.loanReadPlatformService.retrieveLoanPrePaymentTemplate(LoanTransactionType.GOODWILL_CREDIT, loanId,
|
||||||
transactionDate);
|
transactionDate);
|
||||||
} else if (is(commandParam, "waiveinterest")) {
|
} else if (is(commandParam, "waiveinterest")) {
|
||||||
@@ -167,7 +167,7 @@ public class LoanTransactionsApiResource {
|
|||||||
} else if (is(commandParam, "prepayLoan")) {
|
} else if (is(commandParam, "prepayLoan")) {
|
||||||
LocalDate transactionDate = null;
|
LocalDate transactionDate = null;
|
||||||
if (transactionDateParam == null) {
|
if (transactionDateParam == null) {
|
||||||
transactionDate = DateUtils.getLocalDateOfTenant();
|
transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
} else {
|
} else {
|
||||||
transactionDate = LocalDate.ofInstant(transactionDateParam.getDate("transactionDate", dateFormat, locale).toInstant(),
|
transactionDate = LocalDate.ofInstant(transactionDateParam.getDate("transactionDate", dateFormat, locale).toInstant(),
|
||||||
DateUtils.getDateTimeZoneOfTenant());
|
DateUtils.getDateTimeZoneOfTenant());
|
||||||
@@ -181,7 +181,7 @@ public class LoanTransactionsApiResource {
|
|||||||
} else if (is(commandParam, "foreclosure")) {
|
} else if (is(commandParam, "foreclosure")) {
|
||||||
LocalDate transactionDate = null;
|
LocalDate transactionDate = null;
|
||||||
if (transactionDateParam == null) {
|
if (transactionDateParam == null) {
|
||||||
transactionDate = DateUtils.getLocalDateOfTenant();
|
transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
} else {
|
} else {
|
||||||
transactionDate = LocalDate.ofInstant(transactionDateParam.getDate("transactionDate", dateFormat, locale).toInstant(),
|
transactionDate = LocalDate.ofInstant(transactionDateParam.getDate("transactionDate", dateFormat, locale).toInstant(),
|
||||||
DateUtils.getDateTimeZoneOfTenant());
|
DateUtils.getDateTimeZoneOfTenant());
|
||||||
|
|||||||
+40
-40
@@ -704,7 +704,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
transactionDate = suppliedTransactionDate;
|
transactionDate = suppliedTransactionDate;
|
||||||
} else {
|
} else {
|
||||||
transactionDate = loanCharge.getDueLocalDate();
|
transactionDate = loanCharge.getDueLocalDate();
|
||||||
final LocalDate currentDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate currentDate = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
// if loan charge is to be applied on a future date, the loan
|
// if loan charge is to be applied on a future date, the loan
|
||||||
// transaction would show todays date as applied date
|
// transaction would show todays date as applied date
|
||||||
@@ -1045,8 +1045,8 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
LocalDate transactionDate = getDisbursementDate();
|
LocalDate transactionDate = getDisbursementDate();
|
||||||
if (loanCharge.isDueDateCharge()) {
|
if (loanCharge.isDueDateCharge()) {
|
||||||
if (loanCharge.getDueLocalDate().isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (loanCharge.getDueLocalDate().isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
transactionDate = DateUtils.getLocalDateOfTenant();
|
transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
} else {
|
} else {
|
||||||
transactionDate = loanCharge.getDueLocalDate();
|
transactionDate = loanCharge.getDueLocalDate();
|
||||||
}
|
}
|
||||||
@@ -1067,8 +1067,8 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
waiveLoanChargeTransaction.getAmount(getCurrency()).getAmount(), loanInstallmentNumber);
|
waiveLoanChargeTransaction.getAmount(getCurrency()).getAmount(), loanInstallmentNumber);
|
||||||
waiveLoanChargeTransaction.getLoanChargesPaid().add(loanChargePaidBy);
|
waiveLoanChargeTransaction.getLoanChargesPaid().add(loanChargePaidBy);
|
||||||
addLoanTransaction(waiveLoanChargeTransaction);
|
addLoanTransaction(waiveLoanChargeTransaction);
|
||||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled() && (loanCharge.getDueLocalDate() == null
|
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()
|
||||||
|| LocalDate.now(DateUtils.getDateTimeZoneOfTenant()).isAfter(loanCharge.getDueLocalDate()))) {
|
&& (loanCharge.getDueLocalDate() == null || DateUtils.getBusinessLocalDate().isAfter(loanCharge.getDueLocalDate()))) {
|
||||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
||||||
}
|
}
|
||||||
// Waive of charges whose due date falls after latest 'repayment'
|
// Waive of charges whose due date falls after latest 'repayment'
|
||||||
@@ -1562,9 +1562,9 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the comparison should be done with the tenant date
|
// the comparison should be done with the tenant date
|
||||||
// (DateUtils.getLocalDateOfTenant()) and not the server date (new
|
// (DateUtils.getBusinessDate()) and not the server date (new
|
||||||
// LocalDate())
|
// LocalDate())
|
||||||
if (getSubmittedOnDate().isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (getSubmittedOnDate().isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "The date on which a loan is submitted cannot be in the future.";
|
final String errorMessage = "The date on which a loan is submitted cannot be in the future.";
|
||||||
throw new InvalidLoanStateTransitionException("submittal", "cannot.be.a.future.date", errorMessage, getSubmittedOnDate());
|
throw new InvalidLoanStateTransitionException("submittal", "cannot.be.a.future.date", errorMessage, getSubmittedOnDate());
|
||||||
}
|
}
|
||||||
@@ -1774,7 +1774,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
private BigDecimal calculateOverdueAmountPercentageAppliedTo(final LoanCharge loanCharge, final int penaltyWaitPeriod) {
|
private BigDecimal calculateOverdueAmountPercentageAppliedTo(final LoanCharge loanCharge, final int penaltyWaitPeriod) {
|
||||||
LoanRepaymentScheduleInstallment installment = loanCharge.getOverdueInstallmentCharge().getInstallment();
|
LoanRepaymentScheduleInstallment installment = loanCharge.getOverdueInstallmentCharge().getInstallment();
|
||||||
LocalDate graceDate = DateUtils.getLocalDateOfTenant().minusDays(penaltyWaitPeriod);
|
LocalDate graceDate = DateUtils.getBusinessLocalDate().minusDays(penaltyWaitPeriod);
|
||||||
Money amount = Money.zero(getCurrency());
|
Money amount = Money.zero(getCurrency());
|
||||||
if (graceDate.isAfter(installment.getDueDate())) {
|
if (graceDate.isAfter(installment.getDueDate())) {
|
||||||
amount = calculateOverdueAmountPercentageAppliedTo(installment, loanCharge.getChargeCalculation());
|
amount = calculateOverdueAmountPercentageAppliedTo(installment, loanCharge.getChargeCalculation());
|
||||||
@@ -2090,7 +2090,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
updateLoanScheduleDependentDerivedFields();
|
updateLoanScheduleDependentDerivedFields();
|
||||||
|
|
||||||
if (submittedOn.isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (submittedOn.isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "The date on which a loan is submitted cannot be in the future.";
|
final String errorMessage = "The date on which a loan is submitted cannot be in the future.";
|
||||||
throw new InvalidLoanStateTransitionException("submittal", "cannot.be.a.future.date", errorMessage, submittedOn);
|
throw new InvalidLoanStateTransitionException("submittal", "cannot.be.a.future.date", errorMessage, submittedOn);
|
||||||
}
|
}
|
||||||
@@ -2190,7 +2190,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_REJECTED, rejectedOn);
|
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_REJECTED, rejectedOn);
|
||||||
|
|
||||||
if (rejectedOn.isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (rejectedOn.isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "The date on which a loan is rejected cannot be in the future.";
|
final String errorMessage = "The date on which a loan is rejected cannot be in the future.";
|
||||||
throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, rejectedOn);
|
throw new InvalidLoanStateTransitionException("reject", "cannot.be.a.future.date", errorMessage, rejectedOn);
|
||||||
}
|
}
|
||||||
@@ -2239,7 +2239,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_WITHDRAWN, withdrawnOn);
|
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_WITHDRAWN, withdrawnOn);
|
||||||
|
|
||||||
if (withdrawnOn.isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (withdrawnOn.isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "The date on which a loan is withdrawn cannot be in the future.";
|
final String errorMessage = "The date on which a loan is withdrawn cannot be in the future.";
|
||||||
throw new InvalidLoanStateTransitionException("withdraw", "cannot.be.a.future.date", errorMessage, command);
|
throw new InvalidLoanStateTransitionException("withdraw", "cannot.be.a.future.date", errorMessage, command);
|
||||||
}
|
}
|
||||||
@@ -2355,7 +2355,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_APPROVED, approvedOn);
|
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_APPROVED, approvedOn);
|
||||||
|
|
||||||
if (approvedOn.isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (approvedOn.isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "The date on which a loan is approved cannot be in the future.";
|
final String errorMessage = "The date on which a loan is approved cannot be in the future.";
|
||||||
throw new InvalidLoanStateTransitionException("approval", "cannot.be.a.future.date", errorMessage, getApprovedOnDate());
|
throw new InvalidLoanStateTransitionException("approval", "cannot.be.a.future.date", errorMessage, getApprovedOnDate());
|
||||||
}
|
}
|
||||||
@@ -2513,7 +2513,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
LocalDate firstInstallmentDueDate = fetchRepaymentScheduleInstallment(1).getDueDate();
|
LocalDate firstInstallmentDueDate = fetchRepaymentScheduleInstallment(1).getDueDate();
|
||||||
if (interestRecalculationEnabledParam
|
if (interestRecalculationEnabledParam
|
||||||
&& (firstInstallmentDueDate.isBefore(LocalDate.now(DateUtils.getDateTimeZoneOfTenant())) || disbursementMissedParam)) {
|
&& (firstInstallmentDueDate.isBefore(DateUtils.getBusinessLocalDate()) || disbursementMissedParam)) {
|
||||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2729,8 +2729,8 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
private boolean isDisbursementMissed() {
|
private boolean isDisbursementMissed() {
|
||||||
boolean isDisbursementMissed = false;
|
boolean isDisbursementMissed = false;
|
||||||
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||||
if (disbursementDetail.actualDisbursementDate() == null && LocalDate.now(DateUtils.getDateTimeZoneOfTenant())
|
if (disbursementDetail.actualDisbursementDate() == null
|
||||||
.isAfter(disbursementDetail.expectedDisbursementDateAsLocalDate())) {
|
&& DateUtils.getBusinessLocalDate().isAfter(disbursementDetail.expectedDisbursementDateAsLocalDate())) {
|
||||||
isDisbursementMissed = true;
|
isDisbursementMissed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2840,7 +2840,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
if (loanProduct.isLinkedToFloatingInterestRate()) {
|
if (loanProduct.isLinkedToFloatingInterestRate()) {
|
||||||
floatingRateDTO.resetInterestRateDiff();
|
floatingRateDTO.resetInterestRateDiff();
|
||||||
Collection<FloatingRatePeriodData> applicableRates = loanProduct.fetchInterestRates(floatingRateDTO);
|
Collection<FloatingRatePeriodData> applicableRates = loanProduct.fetchInterestRates(floatingRateDTO);
|
||||||
LocalDate interestRateStartDate = DateUtils.getLocalDateOfTenant();
|
LocalDate interestRateStartDate = DateUtils.getBusinessLocalDate();
|
||||||
for (FloatingRatePeriodData periodData : applicableRates) {
|
for (FloatingRatePeriodData periodData : applicableRates) {
|
||||||
LoanTermVariationsData loanTermVariation = new LoanTermVariationsData(
|
LoanTermVariationsData loanTermVariation = new LoanTermVariationsData(
|
||||||
LoanEnumerations.loanvariationType(LoanTermVariationType.INTEREST_RATE), periodData.getFromDateAsLocalDate(),
|
LoanEnumerations.loanvariationType(LoanTermVariationType.INTEREST_RATE), periodData.getFromDateAsLocalDate(),
|
||||||
@@ -2932,7 +2932,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_DISBURSED, disbursedOn);
|
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_DISBURSED, disbursedOn);
|
||||||
|
|
||||||
if (disbursedOn.isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (disbursedOn.isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "The date on which a loan with identifier : " + this.accountNumber
|
final String errorMessage = "The date on which a loan with identifier : " + this.accountNumber
|
||||||
+ " is disbursed cannot be in the future.";
|
+ " is disbursed cannot be in the future.";
|
||||||
throw new InvalidLoanStateTransitionException("disbursal", "cannot.be.a.future.date", errorMessage, disbursedOn);
|
throw new InvalidLoanStateTransitionException("disbursal", "cannot.be.a.future.date", errorMessage, disbursedOn);
|
||||||
@@ -3132,7 +3132,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
validateRepaymentDateIsOnNonWorkingDay(paymentTransaction.getTransactionDate(), holidayDetailDTO.getWorkingDays(),
|
validateRepaymentDateIsOnNonWorkingDay(paymentTransaction.getTransactionDate(), holidayDetailDTO.getWorkingDays(),
|
||||||
holidayDetailDTO.isAllowTransactionsOnNonWorkingDay());
|
holidayDetailDTO.isAllowTransactionsOnNonWorkingDay());
|
||||||
|
|
||||||
if (paymentTransaction.getTransactionDate().isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (paymentTransaction.getTransactionDate().isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "The date on which a loan charge paid cannot be in the future.";
|
final String errorMessage = "The date on which a loan charge paid cannot be in the future.";
|
||||||
throw new InvalidLoanStateTransitionException("charge.payment", "cannot.be.a.future.date", errorMessage,
|
throw new InvalidLoanStateTransitionException("charge.payment", "cannot.be.a.future.date", errorMessage,
|
||||||
paymentTransaction.getTransactionDate());
|
paymentTransaction.getTransactionDate());
|
||||||
@@ -3231,7 +3231,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
loanTransactionDate, getDisbursementDate());
|
loanTransactionDate, getDisbursementDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loanTransactionDate.isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (loanTransactionDate.isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "The transaction date cannot be in the future.";
|
final String errorMessage = "The transaction date cannot be in the future.";
|
||||||
throw new InvalidLoanStateTransitionException("transaction", "cannot.be.a.future.date", errorMessage, loanTransactionDate);
|
throw new InvalidLoanStateTransitionException("transaction", "cannot.be.a.future.date", errorMessage, loanTransactionDate);
|
||||||
}
|
}
|
||||||
@@ -3265,7 +3265,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
boolean reprocess = true;
|
boolean reprocess = true;
|
||||||
|
|
||||||
if (!isForeclosure() && isTransactionChronologicallyLatest && adjustedTransaction == null
|
if (!isForeclosure() && isTransactionChronologicallyLatest && adjustedTransaction == null
|
||||||
&& loanTransaction.getTransactionDate().isEqual(DateUtils.getLocalDateOfTenant()) && currentInstallment != null
|
&& loanTransaction.getTransactionDate().isEqual(DateUtils.getBusinessLocalDate()) && currentInstallment != null
|
||||||
&& currentInstallment.getTotalOutstanding(getCurrency()).isEqualTo(loanTransaction.getAmount(getCurrency()))) {
|
&& currentInstallment.getTotalOutstanding(getCurrency()).isEqualTo(loanTransaction.getAmount(getCurrency()))) {
|
||||||
reprocess = false;
|
reprocess = false;
|
||||||
}
|
}
|
||||||
@@ -3570,7 +3570,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate possibleNextRepaymentDate() {
|
public LocalDate possibleNextRepaymentDate() {
|
||||||
LocalDate earliestUnpaidInstallmentDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
LocalDate earliestUnpaidInstallmentDate = DateUtils.getBusinessLocalDate();
|
||||||
List<LoanRepaymentScheduleInstallment> installments = getRepaymentScheduleInstallments();
|
List<LoanRepaymentScheduleInstallment> installments = getRepaymentScheduleInstallments();
|
||||||
for (final LoanRepaymentScheduleInstallment installment : installments) {
|
for (final LoanRepaymentScheduleInstallment installment : installments) {
|
||||||
if (installment.isNotFullyPaidOff()) {
|
if (installment.isNotFullyPaidOff()) {
|
||||||
@@ -3611,7 +3611,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
final Money totalInterestOutstanding = getTotalInterestOutstandingOnLoan();
|
final Money totalInterestOutstanding = getTotalInterestOutstandingOnLoan();
|
||||||
Money possibleInterestToWaive = totalInterestOutstanding.copy();
|
Money possibleInterestToWaive = totalInterestOutstanding.copy();
|
||||||
LocalDate transactionDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
if (totalInterestOutstanding.isGreaterThanZero()) {
|
if (totalInterestOutstanding.isGreaterThanZero()) {
|
||||||
// find earliest known instance of overdue interest and default to
|
// find earliest known instance of overdue interest and default to
|
||||||
@@ -3620,8 +3620,8 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
for (final LoanRepaymentScheduleInstallment scheduledRepayment : installments) {
|
for (final LoanRepaymentScheduleInstallment scheduledRepayment : installments) {
|
||||||
|
|
||||||
final Money outstandingForPeriod = scheduledRepayment.getInterestOutstanding(loanCurrency());
|
final Money outstandingForPeriod = scheduledRepayment.getInterestOutstanding(loanCurrency());
|
||||||
if (scheduledRepayment.isOverdueOn(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()))
|
if (scheduledRepayment.isOverdueOn(DateUtils.getBusinessLocalDate()) && scheduledRepayment.isNotFullyPaidOff()
|
||||||
&& scheduledRepayment.isNotFullyPaidOff() && outstandingForPeriod.isGreaterThanZero()) {
|
&& outstandingForPeriod.isGreaterThanZero()) {
|
||||||
transactionDate = scheduledRepayment.getDueDate();
|
transactionDate = scheduledRepayment.getDueDate();
|
||||||
possibleInterestToWaive = outstandingForPeriod;
|
possibleInterestToWaive = outstandingForPeriod;
|
||||||
break;
|
break;
|
||||||
@@ -3799,7 +3799,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.WRITE_OFF_OUTSTANDING, writtenOffOnLocalDate);
|
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.WRITE_OFF_OUTSTANDING, writtenOffOnLocalDate);
|
||||||
|
|
||||||
if (writtenOffOnLocalDate.isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (writtenOffOnLocalDate.isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "The date on which a loan is written off cannot be in the future.";
|
final String errorMessage = "The date on which a loan is written off cannot be in the future.";
|
||||||
throw new InvalidLoanStateTransitionException("writeoff", "cannot.be.a.future.date", errorMessage, writtenOffOnLocalDate);
|
throw new InvalidLoanStateTransitionException("writeoff", "cannot.be.a.future.date", errorMessage, writtenOffOnLocalDate);
|
||||||
}
|
}
|
||||||
@@ -3883,7 +3883,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
getDisbursementDate());
|
getDisbursementDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closureDate.isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (closureDate.isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "The date on which a loan is closed cannot be in the future.";
|
final String errorMessage = "The date on which a loan is closed cannot be in the future.";
|
||||||
throw new InvalidLoanStateTransitionException("close", "cannot.be.a.future.date", errorMessage, closureDate);
|
throw new InvalidLoanStateTransitionException("close", "cannot.be.a.future.date", errorMessage, closureDate);
|
||||||
}
|
}
|
||||||
@@ -3980,7 +3980,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
rescheduledOnLocalDate, getDisbursementDate());
|
rescheduledOnLocalDate, getDisbursementDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rescheduledOnLocalDate.isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (rescheduledOnLocalDate.isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "The date on which a loan is rescheduled cannot be in the future.";
|
final String errorMessage = "The date on which a loan is rescheduled cannot be in the future.";
|
||||||
throw new InvalidLoanStateTransitionException("close.reschedule", "cannot.be.a.future.date", errorMessage,
|
throw new InvalidLoanStateTransitionException("close.reschedule", "cannot.be.a.future.date", errorMessage,
|
||||||
rescheduledOnLocalDate);
|
rescheduledOnLocalDate);
|
||||||
@@ -4214,7 +4214,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
for (final LoanRepaymentScheduleInstallment scheduledRepayment : installments) {
|
for (final LoanRepaymentScheduleInstallment scheduledRepayment : installments) {
|
||||||
|
|
||||||
final Money interestOutstandingForPeriod = scheduledRepayment.getInterestOutstanding(loanCurrency());
|
final Money interestOutstandingForPeriod = scheduledRepayment.getInterestOutstanding(loanCurrency());
|
||||||
if (scheduledRepayment.isOverdueOn(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()))) {
|
if (scheduledRepayment.isOverdueOn(DateUtils.getBusinessLocalDate())) {
|
||||||
cumulativeInterestOverdue = cumulativeInterestOverdue.plus(interestOutstandingForPeriod);
|
cumulativeInterestOverdue = cumulativeInterestOverdue.plus(interestOutstandingForPeriod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4288,7 +4288,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
throw new LoanOfficerAssignmentDateException("cannot.be.before.previous.unassignement.date", errorMessage, assignmentDate,
|
throw new LoanOfficerAssignmentDateException("cannot.be.before.previous.unassignement.date", errorMessage, assignmentDate,
|
||||||
lastAssignmentRecord.getEndDate());
|
lastAssignmentRecord.getEndDate());
|
||||||
|
|
||||||
} else if (DateUtils.getLocalDateOfTenant().isBefore(assignmentDate)) {
|
} else if (DateUtils.getBusinessLocalDate().isBefore(assignmentDate)) {
|
||||||
|
|
||||||
final String errorMessage = "The Loan Officer assignment date (" + assignmentDate + ") cannot be in the future.";
|
final String errorMessage = "The Loan Officer assignment date (" + assignmentDate + ") cannot be in the future.";
|
||||||
|
|
||||||
@@ -4332,7 +4332,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
private void validateUnassignDate(final LoanOfficerAssignmentHistory latestHistoryRecord, final LocalDate unassignDate) {
|
private void validateUnassignDate(final LoanOfficerAssignmentHistory latestHistoryRecord, final LocalDate unassignDate) {
|
||||||
|
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
if (latestHistoryRecord.getStartDate().isAfter(unassignDate)) {
|
if (latestHistoryRecord.getStartDate().isAfter(unassignDate)) {
|
||||||
|
|
||||||
@@ -4616,7 +4616,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
// FIXME: AA this won't update repayment dates before current date.
|
// FIXME: AA this won't update repayment dates before current date.
|
||||||
|
|
||||||
if (oldDueDate.isAfter(seedDate) && oldDueDate.isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (oldDueDate.isAfter(seedDate) && oldDueDate.isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
|
|
||||||
newRepaymentDate = CalendarUtils.getNewRepaymentMeetingDate(recuringRule, seedDate, oldDueDate, loanRepaymentInterval,
|
newRepaymentDate = CalendarUtils.getNewRepaymentMeetingDate(recuringRule, seedDate, oldDueDate, loanRepaymentInterval,
|
||||||
frequency, workingDays, isSkipRepaymentonfirstdayofmonth, numberofDays);
|
frequency, workingDays, isSkipRepaymentonfirstdayofmonth, numberofDays);
|
||||||
@@ -5421,7 +5421,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateLoanSchedule(loanSchedule.getInstallments(), currentUser);
|
updateLoanSchedule(loanSchedule.getInstallments(), currentUser);
|
||||||
this.interestRecalculatedOn = DateUtils.getDateOfTenant();
|
this.interestRecalculatedOn = DateUtils.getBusinessDate();
|
||||||
LocalDate lastRepaymentDate = this.getLastRepaymentPeriodDueDate(true);
|
LocalDate lastRepaymentDate = this.getLastRepaymentPeriodDueDate(true);
|
||||||
Set<LoanCharge> charges = this.charges();
|
Set<LoanCharge> charges = this.charges();
|
||||||
for (final LoanCharge loanCharge : charges) {
|
for (final LoanCharge loanCharge : charges) {
|
||||||
@@ -5475,7 +5475,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
List<LoanTransaction> incomeTransactions = retreiveListOfIncomePostingTransactions();
|
List<LoanTransaction> incomeTransactions = retreiveListOfIncomePostingTransactions();
|
||||||
List<LoanTransaction> accrualTransactions = retreiveListOfAccrualTransactions();
|
List<LoanTransaction> accrualTransactions = retreiveListOfAccrualTransactions();
|
||||||
for (LoanInterestRecalcualtionAdditionalDetails compoundingDetail : compoundingDetails) {
|
for (LoanInterestRecalcualtionAdditionalDetails compoundingDetail : compoundingDetails) {
|
||||||
if (!compoundingDetail.getEffectiveDate().isBefore(DateUtils.getLocalDateOfTenant())) {
|
if (!compoundingDetail.getEffectiveDate().isBefore(DateUtils.getBusinessLocalDate())) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LoanTransaction incomeTransaction = getTransactionForDate(incomeTransactions, compoundingDetail.getEffectiveDate());
|
LoanTransaction incomeTransaction = getTransactionForDate(incomeTransactions, compoundingDetail.getEffectiveDate());
|
||||||
@@ -5775,9 +5775,9 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
feeCharges = feeCharges.plus(scheduledRepayment.getFeeChargesOutstanding(loanCurrency()));
|
feeCharges = feeCharges.plus(scheduledRepayment.getFeeChargesOutstanding(loanCurrency()));
|
||||||
penaltyCharges = penaltyCharges.plus(scheduledRepayment.getPenaltyChargesOutstanding(loanCurrency()));
|
penaltyCharges = penaltyCharges.plus(scheduledRepayment.getPenaltyChargesOutstanding(loanCurrency()));
|
||||||
}
|
}
|
||||||
return new LoanRepaymentScheduleInstallment(null, 0, LocalDate.now(DateUtils.getDateTimeZoneOfTenant()),
|
LocalDate businessDate = DateUtils.getBusinessLocalDate();
|
||||||
LocalDate.now(DateUtils.getDateTimeZoneOfTenant()), totalPrincipal.getAmount(), totalInterest.getAmount(),
|
return new LoanRepaymentScheduleInstallment(null, 0, businessDate, businessDate, totalPrincipal.getAmount(),
|
||||||
feeCharges.getAmount(), penaltyCharges.getAmount(), false, compoundingDetails);
|
totalInterest.getAmount(), feeCharges.getAmount(), penaltyCharges.getAmount(), false, compoundingDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getAccruedTill() {
|
public LocalDate getAccruedTill() {
|
||||||
@@ -6217,7 +6217,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
loanTransactionDate, getDisbursementDate());
|
loanTransactionDate, getDisbursementDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loanTransactionDate.isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (loanTransactionDate.isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "The transaction date cannot be in the future.";
|
final String errorMessage = "The transaction date cannot be in the future.";
|
||||||
throw new InvalidLoanStateTransitionException("transaction", "cannot.be.a.future.date", errorMessage, loanTransactionDate);
|
throw new InvalidLoanStateTransitionException("transaction", "cannot.be.a.future.date", errorMessage, loanTransactionDate);
|
||||||
}
|
}
|
||||||
@@ -6257,7 +6257,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
public LocalDate possibleNextRefundDate() {
|
public LocalDate possibleNextRefundDate() {
|
||||||
|
|
||||||
final LocalDate now = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
final LocalDate now = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
LocalDate lastTransactionDate = null;
|
LocalDate lastTransactionDate = null;
|
||||||
for (final LoanTransaction transaction : this.loanTransactions) {
|
for (final LoanTransaction transaction : this.loanTransactions) {
|
||||||
@@ -6435,7 +6435,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
*/
|
*/
|
||||||
public LocalDate getNextPossibleRepaymentDateForRescheduling() {
|
public LocalDate getNextPossibleRepaymentDateForRescheduling() {
|
||||||
List<LoanDisbursementDetails> loanDisbursementDetails = this.disbursementDetails;
|
List<LoanDisbursementDetails> loanDisbursementDetails = this.disbursementDetails;
|
||||||
LocalDate nextRepaymentDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
LocalDate nextRepaymentDate = DateUtils.getBusinessLocalDate();
|
||||||
for (LoanDisbursementDetails loanDisbursementDetail : loanDisbursementDetails) {
|
for (LoanDisbursementDetails loanDisbursementDetail : loanDisbursementDetails) {
|
||||||
if (loanDisbursementDetail.actualDisbursementDate() == null) {
|
if (loanDisbursementDetail.actualDisbursementDate() == null) {
|
||||||
List<LoanRepaymentScheduleInstallment> installments = getRepaymentScheduleInstallments();
|
List<LoanRepaymentScheduleInstallment> installments = getRepaymentScheduleInstallments();
|
||||||
@@ -6500,7 +6500,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
Money totalPrincipal = Money.of(getCurrency(), this.getSummary().getTotalPrincipalOutstanding());
|
Money totalPrincipal = Money.of(getCurrency(), this.getSummary().getTotalPrincipalOutstanding());
|
||||||
totalPrincipal = totalPrincipal.minus(receivables[3]);
|
totalPrincipal = totalPrincipal.minus(receivables[3]);
|
||||||
final Set<LoanInterestRecalcualtionAdditionalDetails> compoundingDetails = null;
|
final Set<LoanInterestRecalcualtionAdditionalDetails> compoundingDetails = null;
|
||||||
final LocalDate currentDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate currentDate = DateUtils.getBusinessLocalDate();
|
||||||
return new LoanRepaymentScheduleInstallment(null, 0, currentDate, currentDate, totalPrincipal.getAmount(),
|
return new LoanRepaymentScheduleInstallment(null, 0, currentDate, currentDate, totalPrincipal.getAmount(),
|
||||||
receivables[0].getAmount(), receivables[1].getAmount(), receivables[2].getAmount(), false, compoundingDetails);
|
receivables[0].getAmount(), receivables[1].getAmount(), receivables[2].getAmount(), false, compoundingDetails);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -546,7 +546,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean isOrganisationDateEnabled = this.configurationDomainService.isOrganisationstartDateEnabled();
|
boolean isOrganisationDateEnabled = this.configurationDomainService.isOrganisationstartDateEnabled();
|
||||||
Date organisationStartDate = new Date();
|
Date organisationStartDate = DateUtils.getBusinessDate();
|
||||||
if (isOrganisationDateEnabled) {
|
if (isOrganisationDateEnabled) {
|
||||||
organisationStartDate = this.configurationDomainService.retrieveOrganisationStartDate();
|
organisationStartDate = this.configurationDomainService.retrieveOrganisationStartDate();
|
||||||
}
|
}
|
||||||
@@ -566,7 +566,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
|
|
||||||
for (LoanRepaymentScheduleInstallment installment : installments) {
|
for (LoanRepaymentScheduleInstallment installment : installments) {
|
||||||
if (installment.getDueDate().isAfter(loan.getMaturityDate())) {
|
if (installment.getDueDate().isAfter(loan.getMaturityDate())) {
|
||||||
accruedTill = DateUtils.getLocalDateOfTenant();
|
accruedTill = DateUtils.getBusinessLocalDate();
|
||||||
}
|
}
|
||||||
if (!isOrganisationDateEnabled || LocalDate.ofInstant(organisationStartDate.toInstant(), DateUtils.getDateTimeZoneOfTenant())
|
if (!isOrganisationDateEnabled || LocalDate.ofInstant(organisationStartDate.toInstant(), DateUtils.getDateTimeZoneOfTenant())
|
||||||
.isBefore(installment.getDueDate())) {
|
.isBefore(installment.getDueDate())) {
|
||||||
|
|||||||
+3
-3
@@ -348,7 +348,7 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
this.paymentDetail = paymentDetail;
|
this.paymentDetail = paymentDetail;
|
||||||
this.office = office;
|
this.office = office;
|
||||||
this.externalId = externalId;
|
this.externalId = externalId;
|
||||||
this.submittedOnDate = DateUtils.getDateOfTenant();
|
this.submittedOnDate = DateUtils.getBusinessDate();
|
||||||
this.createdDate = Date.from(createdDate.atZone(DateUtils.getDateTimeZoneOfTenant()).toInstant());
|
this.createdDate = Date.from(createdDate.atZone(DateUtils.getDateTimeZoneOfTenant()).toInstant());
|
||||||
this.appUser = appUser;
|
this.appUser = appUser;
|
||||||
}
|
}
|
||||||
@@ -376,7 +376,7 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
this.dateOf = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
this.dateOf = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||||
this.externalId = externalId;
|
this.externalId = externalId;
|
||||||
this.office = office;
|
this.office = office;
|
||||||
this.submittedOnDate = DateUtils.getDateOfTenant();
|
this.submittedOnDate = DateUtils.getBusinessDate();
|
||||||
this.createdDate = Date.from(createdDate.atZone(DateUtils.getDateTimeZoneOfTenant()).toInstant());
|
this.createdDate = Date.from(createdDate.atZone(DateUtils.getDateTimeZoneOfTenant()).toInstant());
|
||||||
this.appUser = appUser;
|
this.appUser = appUser;
|
||||||
}
|
}
|
||||||
@@ -391,7 +391,7 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
this.dateOf = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
this.dateOf = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||||
this.externalId = externalId;
|
this.externalId = externalId;
|
||||||
this.office = office;
|
this.office = office;
|
||||||
this.submittedOnDate = DateUtils.getDateOfTenant();
|
this.submittedOnDate = DateUtils.getBusinessDate();
|
||||||
this.createdDate = Date.from(createdDate.atZone(DateUtils.getDateTimeZoneOfTenant()).toInstant());
|
this.createdDate = Date.from(createdDate.atZone(DateUtils.getDateTimeZoneOfTenant()).toInstant());
|
||||||
this.appUser = appUser;
|
this.appUser = appUser;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -211,7 +211,7 @@ public class GuarantorDomainServiceImpl implements GuarantorDomainService {
|
|||||||
final List<Guarantor> existGuarantorList = this.guarantorRepository.findByLoan(loan);
|
final List<Guarantor> existGuarantorList = this.guarantorRepository.findByLoan(loan);
|
||||||
final boolean isRegularTransaction = true;
|
final boolean isRegularTransaction = true;
|
||||||
final boolean isExceptionForBalanceCheck = true;
|
final boolean isExceptionForBalanceCheck = true;
|
||||||
LocalDate transactionDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
PortfolioAccountType fromAccountType = PortfolioAccountType.SAVINGS;
|
PortfolioAccountType fromAccountType = PortfolioAccountType.SAVINGS;
|
||||||
PortfolioAccountType toAccountType = PortfolioAccountType.LOAN;
|
PortfolioAccountType toAccountType = PortfolioAccountType.LOAN;
|
||||||
final Long toAccountId = loan.getId();
|
final Long toAccountId = loan.getId();
|
||||||
|
|||||||
+2
-3
@@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.portfolio.loanaccount.guarantor.service;
|
package org.apache.fineract.portfolio.loanaccount.guarantor.service;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -125,7 +124,7 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
|
|||||||
guarantorFundingDetails.add(fundingDetails);
|
guarantorFundingDetails.add(fundingDetails);
|
||||||
if (loan.isDisbursed()
|
if (loan.isDisbursed()
|
||||||
|| (loan.isApproved() && (loan.getGuaranteeAmount() != null || loan.loanProduct().isHoldGuaranteeFundsEnabled()))) {
|
|| (loan.isApproved() && (loan.getGuaranteeAmount() != null || loan.loanProduct().isHoldGuaranteeFundsEnabled()))) {
|
||||||
this.guarantorDomainService.assignGuarantor(fundingDetails, LocalDate.now(DateUtils.getDateTimeZoneOfTenant()));
|
this.guarantorDomainService.assignGuarantor(fundingDetails, DateUtils.getBusinessLocalDate());
|
||||||
loan.updateGuaranteeAmount(fundingDetails.getAmount());
|
loan.updateGuaranteeAmount(fundingDetails.getAmount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -312,7 +311,7 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
|
|||||||
GuarantorFundStatusType fundStatusType = GuarantorFundStatusType.DELETED;
|
GuarantorFundStatusType fundStatusType = GuarantorFundStatusType.DELETED;
|
||||||
if (guarantorForDelete.getLoan().isDisbursed() || guarantorForDelete.getLoan().isApproved()) {
|
if (guarantorForDelete.getLoan().isDisbursed() || guarantorForDelete.getLoan().isApproved()) {
|
||||||
fundStatusType = GuarantorFundStatusType.WITHDRAWN;
|
fundStatusType = GuarantorFundStatusType.WITHDRAWN;
|
||||||
this.guarantorDomainService.releaseGuarantor(guarantorFundingDetails, LocalDate.now(DateUtils.getDateTimeZoneOfTenant()));
|
this.guarantorDomainService.releaseGuarantor(guarantorFundingDetails, DateUtils.getBusinessLocalDate());
|
||||||
}
|
}
|
||||||
guarantorForDelete.updateStatus(guarantorFundingDetails, fundStatusType);
|
guarantorForDelete.updateStatus(guarantorFundingDetails, fundStatusType);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -193,7 +193,7 @@ public final class LoanSchedulePeriodData {
|
|||||||
this.totalOutstandingForPeriod = this.feeChargesOutstanding;
|
this.totalOutstandingForPeriod = this.feeChargesOutstanding;
|
||||||
this.totalActualCostOfLoanForPeriod = this.feeChargesDue;
|
this.totalActualCostOfLoanForPeriod = this.feeChargesDue;
|
||||||
this.totalInstallmentAmountForPeriod = null;
|
this.totalInstallmentAmountForPeriod = null;
|
||||||
if (dueDate.isBefore(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()))) {
|
if (dueDate.isBefore(DateUtils.getBusinessLocalDate())) {
|
||||||
this.totalOverdue = this.totalOutstandingForPeriod;
|
this.totalOverdue = this.totalOutstandingForPeriod;
|
||||||
} else {
|
} else {
|
||||||
this.totalOverdue = null;
|
this.totalOverdue = null;
|
||||||
@@ -255,7 +255,7 @@ public final class LoanSchedulePeriodData {
|
|||||||
this.totalActualCostOfLoanForPeriod = interestDueOnPrincipalOutstanding.add(feeChargesDueForPeriod);
|
this.totalActualCostOfLoanForPeriod = interestDueOnPrincipalOutstanding.add(feeChargesDueForPeriod);
|
||||||
this.totalInstallmentAmountForPeriod = totalInstallmentAmountForPeriod;
|
this.totalInstallmentAmountForPeriod = totalInstallmentAmountForPeriod;
|
||||||
|
|
||||||
if (dueDate.isBefore(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()))) {
|
if (dueDate.isBefore(DateUtils.getBusinessLocalDate())) {
|
||||||
this.totalOverdue = this.totalOutstandingForPeriod;
|
this.totalOverdue = this.totalOutstandingForPeriod;
|
||||||
} else {
|
} else {
|
||||||
this.totalOverdue = null;
|
this.totalOverdue = null;
|
||||||
@@ -326,7 +326,7 @@ public final class LoanSchedulePeriodData {
|
|||||||
this.totalActualCostOfLoanForPeriod = totalActualCostOfLoanForPeriod;
|
this.totalActualCostOfLoanForPeriod = totalActualCostOfLoanForPeriod;
|
||||||
this.totalInstallmentAmountForPeriod = totalInstallmentAmountForPeriod;
|
this.totalInstallmentAmountForPeriod = totalInstallmentAmountForPeriod;
|
||||||
|
|
||||||
if (dueDate.isBefore(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()))) {
|
if (dueDate.isBefore(DateUtils.getBusinessLocalDate())) {
|
||||||
this.totalOverdue = this.totalOutstandingForPeriod;
|
this.totalOverdue = this.totalOutstandingForPeriod;
|
||||||
} else {
|
} else {
|
||||||
this.totalOverdue = null;
|
this.totalOverdue = null;
|
||||||
|
|||||||
+7
-7
@@ -146,7 +146,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
// set and handled separately after all installments generated
|
// set and handled separately after all installments generated
|
||||||
final Set<LoanCharge> nonCompoundingCharges = seperateTotalCompoundingPercentageCharges(loanCharges);
|
final Set<LoanCharge> nonCompoundingCharges = seperateTotalCompoundingPercentageCharges(loanCharges);
|
||||||
|
|
||||||
LocalDate currentDate = DateUtils.getLocalDateOfTenant();
|
LocalDate currentDate = DateUtils.getBusinessLocalDate();
|
||||||
LocalDate lastRestDate = currentDate;
|
LocalDate lastRestDate = currentDate;
|
||||||
if (loanApplicationTerms.getRestCalendarInstance() != null) {
|
if (loanApplicationTerms.getRestCalendarInstance() != null) {
|
||||||
lastRestDate = getNextRestScheduleDate(currentDate.minusDays(1), loanApplicationTerms, holidayDetailDTO);
|
lastRestDate = getNextRestScheduleDate(currentDate.minusDays(1), loanApplicationTerms, holidayDetailDTO);
|
||||||
@@ -1596,7 +1596,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
final MonetaryCurrency currency, final Map<LocalDate, Money> latePaymentMap, final LocalDate scheduledDueDate,
|
final MonetaryCurrency currency, final Map<LocalDate, Money> latePaymentMap, final LocalDate scheduledDueDate,
|
||||||
List<LoanRepaymentScheduleInstallment> installments, boolean applyRestFrequencyForPrincipal, final LocalDate lastRestDate) {
|
List<LoanRepaymentScheduleInstallment> installments, boolean applyRestFrequencyForPrincipal, final LocalDate lastRestDate) {
|
||||||
latePaymentMap.clear();
|
latePaymentMap.clear();
|
||||||
LocalDate currentDate = DateUtils.getLocalDateOfTenant();
|
LocalDate currentDate = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
Money totalCompoundingAmount = Money.zero(currency);
|
Money totalCompoundingAmount = Money.zero(currency);
|
||||||
for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : installments) {
|
for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : installments) {
|
||||||
@@ -1632,10 +1632,10 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : params.getInstallments()) {
|
for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : params.getInstallments()) {
|
||||||
if (params.getCompoundingDateVariations().containsKey(loanRepaymentScheduleInstallment.getFromDate())) {
|
if (params.getCompoundingDateVariations().containsKey(loanRepaymentScheduleInstallment.getFromDate())) {
|
||||||
lastInstallmentIsPastDate = params.applyInterestRecalculation()
|
lastInstallmentIsPastDate = params.applyInterestRecalculation()
|
||||||
&& loanRepaymentScheduleInstallment.getDueDate().isBefore(DateUtils.getLocalDateOfTenant());
|
&& loanRepaymentScheduleInstallment.getDueDate().isBefore(DateUtils.getBusinessLocalDate());
|
||||||
} else {
|
} else {
|
||||||
final boolean isPastDate = params.applyInterestRecalculation()
|
final boolean isPastDate = params.applyInterestRecalculation()
|
||||||
&& loanRepaymentScheduleInstallment.getDueDate().isBefore(DateUtils.getLocalDateOfTenant());
|
&& loanRepaymentScheduleInstallment.getDueDate().isBefore(DateUtils.getBusinessLocalDate());
|
||||||
boolean periodHasCompoundingDate = false;
|
boolean periodHasCompoundingDate = false;
|
||||||
Money amountCharged = Money.zero(currency);
|
Money amountCharged = Money.zero(currency);
|
||||||
if (loanApplicationTerms.getInterestRecalculationCompoundingMethod() != null) {
|
if (loanApplicationTerms.getInterestRecalculationCompoundingMethod() != null) {
|
||||||
@@ -1915,7 +1915,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
periods.add(disbursementPeriod);
|
periods.add(disbursementPeriod);
|
||||||
principal = principal.add(disbursementData.amount());
|
principal = principal.add(disbursementData.amount());
|
||||||
} else if (!excludePastUndisbursed || disbursementData.isDisbursed()
|
} else if (!excludePastUndisbursed || disbursementData.isDisbursed()
|
||||||
|| !disbursementData.disbursementDate().isBefore(DateUtils.getLocalDateOfTenant())) {
|
|| !disbursementData.disbursementDate().isBefore(DateUtils.getBusinessLocalDate())) {
|
||||||
/*
|
/*
|
||||||
* JW: sums up amounts by disbursal date in case of side-effect issues. Original assumed that there were
|
* JW: sums up amounts by disbursal date in case of side-effect issues. Original assumed that there were
|
||||||
* no duplicate disbursal dates and 'put' each amount into the map keyed by date
|
* no duplicate disbursal dates and 'put' each amount into the map keyed by date
|
||||||
@@ -2124,7 +2124,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
// interest calculation
|
// interest calculation
|
||||||
final TreeMap<LocalDate, Money> compoundingMap = new TreeMap<>();
|
final TreeMap<LocalDate, Money> compoundingMap = new TreeMap<>();
|
||||||
final Map<LocalDate, Map<LocalDate, Money>> compoundingDateVariations = new HashMap<>();
|
final Map<LocalDate, Map<LocalDate, Money>> compoundingDateVariations = new HashMap<>();
|
||||||
LocalDate currentDate = DateUtils.getLocalDateOfTenant();
|
LocalDate currentDate = DateUtils.getBusinessLocalDate();
|
||||||
LocalDate lastRestDate = currentDate;
|
LocalDate lastRestDate = currentDate;
|
||||||
if (loanApplicationTerms.isInterestRecalculationEnabled()) {
|
if (loanApplicationTerms.isInterestRecalculationEnabled()) {
|
||||||
lastRestDate = getNextRestScheduleDate(currentDate.minusDays(1), loanApplicationTerms, holidayDetailDTO);
|
lastRestDate = getNextRestScheduleDate(currentDate.minusDays(1), loanApplicationTerms, holidayDetailDTO);
|
||||||
@@ -2494,7 +2494,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
}
|
}
|
||||||
compoundingDateVariations.put(installment.getFromDate(), compoundingMap);
|
compoundingDateVariations.put(installment.getFromDate(), compoundingMap);
|
||||||
if (totalCompounded.isGreaterThanZero()) {
|
if (totalCompounded.isGreaterThanZero()) {
|
||||||
final boolean isPastDate = installment.getDueDate().isBefore(DateUtils.getLocalDateOfTenant());
|
final boolean isPastDate = installment.getDueDate().isBefore(DateUtils.getBusinessLocalDate());
|
||||||
final LocalDate restDate = getNextRestScheduleDate(installment.getDueDate().minusDays(1), loanApplicationTerms,
|
final LocalDate restDate = getNextRestScheduleDate(installment.getDueDate().minusDays(1), loanApplicationTerms,
|
||||||
holidayDetailDTO);
|
holidayDetailDTO);
|
||||||
if (isPastDate) {
|
if (isPastDate) {
|
||||||
|
|||||||
+1
-1
@@ -418,7 +418,7 @@ public class LoanScheduleAssembler {
|
|||||||
baseLendingRatePeriods);
|
baseLendingRatePeriods);
|
||||||
Collection<FloatingRatePeriodData> applicableRates = loanProduct.fetchInterestRates(floatingRateDTO);
|
Collection<FloatingRatePeriodData> applicableRates = loanProduct.fetchInterestRates(floatingRateDTO);
|
||||||
|
|
||||||
LocalDate interestRateStartDate = DateUtils.getLocalDateOfTenant();
|
LocalDate interestRateStartDate = DateUtils.getBusinessLocalDate();
|
||||||
final LocalDate dateValue = null;
|
final LocalDate dateValue = null;
|
||||||
final boolean isSpecificToInstallment = false;
|
final boolean isSpecificToInstallment = false;
|
||||||
for (FloatingRatePeriodData periodData : applicableRates) {
|
for (FloatingRatePeriodData periodData : applicableRates) {
|
||||||
|
|||||||
+1
-1
@@ -144,7 +144,7 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
|
|||||||
|
|
||||||
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||||
|
|
||||||
LocalDate today = DateUtils.getLocalDateOfTenant();
|
LocalDate today = DateUtils.getBusinessLocalDate();
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = loanRepaymentScheduleTransactionProcessorFactory
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = loanRepaymentScheduleTransactionProcessorFactory
|
||||||
.determineProcessor(loan.transactionProcessingStrategy());
|
.determineProcessor(loan.transactionProcessingStrategy());
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -496,7 +496,7 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
|||||||
}
|
}
|
||||||
|
|
||||||
loan.updateRescheduledByUser(appUser);
|
loan.updateRescheduledByUser(appUser);
|
||||||
loan.updateRescheduledOnDate(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()));
|
loan.updateRescheduledOnDate(DateUtils.getBusinessLocalDate());
|
||||||
|
|
||||||
// update the status of the request
|
// update the status of the request
|
||||||
loanRescheduleRequest.approve(appUser, approvedOnDate);
|
loanRescheduleRequest.approve(appUser, approvedOnDate);
|
||||||
|
|||||||
+1
-1
@@ -83,7 +83,7 @@ public class LoanAccrualPlatformServiceImpl implements LoanAccrualPlatformServic
|
|||||||
@CronTarget(jobName = JobName.ADD_PERIODIC_ACCRUAL_ENTRIES)
|
@CronTarget(jobName = JobName.ADD_PERIODIC_ACCRUAL_ENTRIES)
|
||||||
public void addPeriodicAccruals() throws JobExecutionException {
|
public void addPeriodicAccruals() throws JobExecutionException {
|
||||||
try {
|
try {
|
||||||
addPeriodicAccruals(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()));
|
addPeriodicAccruals(DateUtils.getBusinessLocalDate());
|
||||||
} catch (MultiException e) {
|
} catch (MultiException e) {
|
||||||
throw new JobExecutionException(e);
|
throw new JobExecutionException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -272,7 +272,7 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
+ "fee_charges_portion_derived,penalty_charges_portion_derived, submitted_on_date) VALUES (?, ?, false, ?, ?, ?, ?, ?, ?, ?)";
|
+ "fee_charges_portion_derived,penalty_charges_portion_derived, submitted_on_date) VALUES (?, ?, false, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
this.jdbcTemplate.update(transactionSql, scheduleAccrualData.getLoanId(), scheduleAccrualData.getOfficeId(),
|
this.jdbcTemplate.update(transactionSql, scheduleAccrualData.getLoanId(), scheduleAccrualData.getOfficeId(),
|
||||||
LoanTransactionType.ACCRUAL.getValue(), Date.from(accruedTill.atStartOfDay(ZoneId.systemDefault()).toInstant()), amount,
|
LoanTransactionType.ACCRUAL.getValue(), Date.from(accruedTill.atStartOfDay(ZoneId.systemDefault()).toInstant()), amount,
|
||||||
interestportion, feeportion, penaltyportion, DateUtils.getDateOfTenant());
|
interestportion, feeportion, penaltyportion, DateUtils.getBusinessDate());
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
final Long transactonId = this.jdbcTemplate.queryForObject("SELECT " + sqlGenerator.lastInsertId(), Long.class); // NOSONAR
|
final Long transactonId = this.jdbcTemplate.queryForObject("SELECT " + sqlGenerator.lastInsertId(), Long.class); // NOSONAR
|
||||||
|
|
||||||
|
|||||||
+8
-6
@@ -124,7 +124,8 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
|
|||||||
updateSqlBuilder.append(" WHERE ml.loan_status_id = 300 "); // active
|
updateSqlBuilder.append(" WHERE ml.loan_status_id = 300 "); // active
|
||||||
updateSqlBuilder.append(" and mr.completed_derived is false ");
|
updateSqlBuilder.append(" and mr.completed_derived is false ");
|
||||||
updateSqlBuilder.append(" and mr.duedate < ")
|
updateSqlBuilder.append(" and mr.duedate < ")
|
||||||
.append(sqlGenerator.subDate(sqlGenerator.currentDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day")).append(" ");
|
.append(sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day"))
|
||||||
|
.append(" ");
|
||||||
updateSqlBuilder.append(" and (prd.arrears_based_on_original_schedule = false or prd.arrears_based_on_original_schedule is null) ");
|
updateSqlBuilder.append(" and (prd.arrears_based_on_original_schedule = false or prd.arrears_based_on_original_schedule is null) ");
|
||||||
updateSqlBuilder.append(" GROUP BY ml.id");
|
updateSqlBuilder.append(" GROUP BY ml.id");
|
||||||
|
|
||||||
@@ -180,9 +181,10 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
|
|||||||
BigDecimal interestOverdue = BigDecimal.ZERO;
|
BigDecimal interestOverdue = BigDecimal.ZERO;
|
||||||
BigDecimal feeOverdue = BigDecimal.ZERO;
|
BigDecimal feeOverdue = BigDecimal.ZERO;
|
||||||
BigDecimal penaltyOverdue = BigDecimal.ZERO;
|
BigDecimal penaltyOverdue = BigDecimal.ZERO;
|
||||||
LocalDate overDueSince = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
LocalDate businessDate = DateUtils.getBusinessLocalDate();
|
||||||
|
LocalDate overDueSince = businessDate;
|
||||||
for (LoanRepaymentScheduleInstallment installment : installments) {
|
for (LoanRepaymentScheduleInstallment installment : installments) {
|
||||||
if (installment.getDueDate().isBefore(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()))) {
|
if (installment.getDueDate().isBefore(businessDate)) {
|
||||||
principalOverdue = principalOverdue.add(installment.getPrincipalOutstanding(loan.getCurrency()).getAmount());
|
principalOverdue = principalOverdue.add(installment.getPrincipalOutstanding(loan.getCurrency()).getAmount());
|
||||||
interestOverdue = interestOverdue.add(installment.getInterestOutstanding(loan.getCurrency()).getAmount());
|
interestOverdue = interestOverdue.add(installment.getInterestOutstanding(loan.getCurrency()).getAmount());
|
||||||
feeOverdue = feeOverdue.add(installment.getFeeChargesOutstanding(loan.getCurrency()).getAmount());
|
feeOverdue = feeOverdue.add(installment.getFeeChargesOutstanding(loan.getCurrency()).getAmount());
|
||||||
@@ -215,7 +217,7 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
|
|||||||
loanIdentifier.append(
|
loanIdentifier.append(
|
||||||
"inner join m_product_loan_recalculation_details prd on prd.product_id = ml.product_id and prd.arrears_based_on_original_schedule = true ");
|
"inner join m_product_loan_recalculation_details prd on prd.product_id = ml.product_id and prd.arrears_based_on_original_schedule = true ");
|
||||||
loanIdentifier.append("WHERE ml.loan_status_id = 300 and mr.completed_derived is false and mr.duedate < ")
|
loanIdentifier.append("WHERE ml.loan_status_id = 300 and mr.completed_derived is false and mr.duedate < ")
|
||||||
.append(sqlGenerator.subDate(sqlGenerator.currentDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day"))
|
.append(sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day"))
|
||||||
.append(" group by ml.id");
|
.append(" group by ml.id");
|
||||||
List<Long> loanIds = this.jdbcTemplate.queryForList(loanIdentifier.toString(), Long.class);
|
List<Long> loanIds = this.jdbcTemplate.queryForList(loanIdentifier.toString(), Long.class);
|
||||||
if (!loanIds.isEmpty()) {
|
if (!loanIds.isEmpty()) {
|
||||||
@@ -276,7 +278,7 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
|
|||||||
BigDecimal interestOverdue = BigDecimal.ZERO;
|
BigDecimal interestOverdue = BigDecimal.ZERO;
|
||||||
BigDecimal feeOverdue = BigDecimal.ZERO;
|
BigDecimal feeOverdue = BigDecimal.ZERO;
|
||||||
BigDecimal penaltyOverdue = BigDecimal.ZERO;
|
BigDecimal penaltyOverdue = BigDecimal.ZERO;
|
||||||
LocalDate overDueSince = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
LocalDate overDueSince = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
for (LoanSchedulePeriodData loanSchedulePeriodData : entry.getValue()) {
|
for (LoanSchedulePeriodData loanSchedulePeriodData : entry.getValue()) {
|
||||||
if (!loanSchedulePeriodData.getComplete()) {
|
if (!loanSchedulePeriodData.getComplete()) {
|
||||||
@@ -437,7 +439,7 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
|
|||||||
"mr.interest_amount as interestAmount, mr.fee_charges_amount as feeAmount, mr.penalty_charges_amount as penaltyAmount ");
|
"mr.interest_amount as interestAmount, mr.fee_charges_amount as feeAmount, mr.penalty_charges_amount as penaltyAmount ");
|
||||||
scheduleDetail.append("from m_loan ml INNER JOIN m_loan_repayment_schedule_history mr on mr.loan_id = ml.id ");
|
scheduleDetail.append("from m_loan ml INNER JOIN m_loan_repayment_schedule_history mr on mr.loan_id = ml.id ");
|
||||||
scheduleDetail.append("where mr.duedate < "
|
scheduleDetail.append("where mr.duedate < "
|
||||||
+ sqlGenerator.subDate(sqlGenerator.currentDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day") + " and ");
|
+ sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day") + " and ");
|
||||||
scheduleDetail.append("ml.id IN(").append(loanIdsAsString).append(") and mr.version = (");
|
scheduleDetail.append("ml.id IN(").append(loanIdsAsString).append(") and mr.version = (");
|
||||||
scheduleDetail.append("select max(lrs.version) from m_loan_repayment_schedule_history lrs where mr.loan_id = lrs.loan_id");
|
scheduleDetail.append("select max(lrs.version) from m_loan_repayment_schedule_history lrs where mr.loan_id = lrs.loan_id");
|
||||||
scheduleDetail.append(") order by ml.id,mr.duedate");
|
scheduleDetail.append(") order by ml.id,mr.duedate");
|
||||||
|
|||||||
+48
-51
@@ -25,7 +25,6 @@ import java.sql.ResultSet;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
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.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -152,7 +151,6 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
private final PaginationHelper paginationHelper;
|
private final PaginationHelper paginationHelper;
|
||||||
private final LoanMapper loaanLoanMapper;
|
private final LoanMapper loaanLoanMapper;
|
||||||
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
||||||
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
||||||
private final PaymentTypeReadPlatformService paymentTypeReadPlatformService;
|
private final PaymentTypeReadPlatformService paymentTypeReadPlatformService;
|
||||||
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
|
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
|
||||||
private final FloatingRatesReadPlatformService floatingRatesReadPlatformService;
|
private final FloatingRatesReadPlatformService floatingRatesReadPlatformService;
|
||||||
@@ -374,7 +372,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
final ClientData clientAccount = this.clientReadPlatformService.retrieveOne(clientId);
|
final ClientData clientAccount = this.clientReadPlatformService.retrieveOne(clientId);
|
||||||
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate expectedDisbursementDate = DateUtils.getBusinessLocalDate();
|
||||||
LoanAccountData loanTemplateDetails = LoanAccountData.clientDefaults(clientAccount.id(), clientAccount.accountNo(),
|
LoanAccountData loanTemplateDetails = LoanAccountData.clientDefaults(clientAccount.id(), clientAccount.accountNo(),
|
||||||
clientAccount.displayName(), clientAccount.officeId(), expectedDisbursementDate);
|
clientAccount.displayName(), clientAccount.officeId(), expectedDisbursementDate);
|
||||||
|
|
||||||
@@ -392,7 +390,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
final GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId);
|
final GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId);
|
||||||
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate expectedDisbursementDate = DateUtils.getBusinessLocalDate();
|
||||||
LoanAccountData loanDetails = LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate);
|
LoanAccountData loanDetails = LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate);
|
||||||
|
|
||||||
if (productId != null) {
|
if (productId != null) {
|
||||||
@@ -420,7 +418,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
collectionMeetingCalendar);
|
collectionMeetingCalendar);
|
||||||
}
|
}
|
||||||
|
|
||||||
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate expectedDisbursementDate = DateUtils.getBusinessLocalDate();
|
||||||
LoanAccountData loanDetails = LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate);
|
LoanAccountData loanDetails = LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate);
|
||||||
|
|
||||||
if (productId != null) {
|
if (productId != null) {
|
||||||
@@ -459,7 +457,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
|
|
||||||
final CurrencyData currencyData = applicationCurrency.toData();
|
final CurrencyData currencyData = applicationCurrency.toData();
|
||||||
|
|
||||||
final LocalDate earliestUnpaidInstallmentDate = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
final LocalDate earliestUnpaidInstallmentDate = DateUtils.getBusinessLocalDate();
|
||||||
final LocalDate recalculateFrom = null;
|
final LocalDate recalculateFrom = null;
|
||||||
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = loan.fetchPrepaymentDetail(scheduleGeneratorDTO, onDate);
|
final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = loan.fetchPrepaymentDetail(scheduleGeneratorDTO, onDate);
|
||||||
@@ -525,7 +523,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
final BigDecimal outstandingLoanBalance = null;
|
final BigDecimal outstandingLoanBalance = null;
|
||||||
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.WRITEOFF);
|
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.WRITEOFF);
|
||||||
final BigDecimal unrecognizedIncomePortion = null;
|
final BigDecimal unrecognizedIncomePortion = null;
|
||||||
return new LoanTransactionData(null, null, null, transactionType, null, null, DateUtils.getLocalDateOfTenant(), null, null, null,
|
return new LoanTransactionData(null, null, null, transactionType, null, null, DateUtils.getBusinessLocalDate(), null, null, null,
|
||||||
null, null, null, null, null, null, null, outstandingLoanBalance, unrecognizedIncomePortion, false);
|
null, null, null, null, null, null, null, outstandingLoanBalance, unrecognizedIncomePortion, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -533,7 +531,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
@Override
|
@Override
|
||||||
public LoanApprovalData retrieveApprovalTemplate(final Long loanId) {
|
public LoanApprovalData retrieveApprovalTemplate(final Long loanId) {
|
||||||
final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId, true);
|
final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId, true);
|
||||||
return new LoanApprovalData(loan.getProposedPrincipal(), DateUtils.getLocalDateOfTenant(), loan.getNetDisbursalAmount());
|
return new LoanApprovalData(loan.getProposedPrincipal(), DateUtils.getBusinessLocalDate(), loan.getNetDisbursalAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1173,8 +1171,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
}
|
}
|
||||||
this.outstandingLoanPrincipalBalance = this.outstandingLoanPrincipalBalance.add(data.amount());
|
this.outstandingLoanPrincipalBalance = this.outstandingLoanPrincipalBalance.add(data.amount());
|
||||||
} else if (data.isDueForDisbursement(fromDate, dueDate)) {
|
} else if (data.isDueForDisbursement(fromDate, dueDate)) {
|
||||||
if (!excludePastUndisbursed || (excludePastUndisbursed && (data.isDisbursed()
|
if (!excludePastUndisbursed || (excludePastUndisbursed
|
||||||
|| !data.disbursementDate().isBefore(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()))))) {
|
&& (data.isDisbursed() || !data.disbursementDate().isBefore(DateUtils.getBusinessLocalDate())))) {
|
||||||
principal = principal.add(data.amount());
|
principal = principal.add(data.amount());
|
||||||
LoanSchedulePeriodData periodData = null;
|
LoanSchedulePeriodData periodData = null;
|
||||||
if (data.getChargeAmount() == null) {
|
if (data.getChargeAmount() == null) {
|
||||||
@@ -1472,7 +1470,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
final ClientData clientAccount = this.clientReadPlatformService.retrieveOne(clientId);
|
final ClientData clientAccount = this.clientReadPlatformService.retrieveOne(clientId);
|
||||||
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate expectedDisbursementDate = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
return LoanAccountData.clientDefaults(clientAccount.id(), clientAccount.accountNo(), clientAccount.displayName(),
|
return LoanAccountData.clientDefaults(clientAccount.id(), clientAccount.accountNo(), clientAccount.displayName(),
|
||||||
clientAccount.officeId(), expectedDisbursementDate);
|
clientAccount.officeId(), expectedDisbursementDate);
|
||||||
@@ -1482,14 +1480,14 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
public LoanAccountData retrieveGroupDetailsTemplate(final Long groupId) {
|
public LoanAccountData retrieveGroupDetailsTemplate(final Long groupId) {
|
||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
final GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId);
|
final GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId);
|
||||||
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate expectedDisbursementDate = DateUtils.getBusinessLocalDate();
|
||||||
return LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate);
|
return LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoanAccountData retrieveGroupAndMembersDetailsTemplate(final Long groupId) {
|
public LoanAccountData retrieveGroupAndMembersDetailsTemplate(final Long groupId) {
|
||||||
GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId);
|
GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId);
|
||||||
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate expectedDisbursementDate = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
// get group associations
|
// get group associations
|
||||||
final Collection<ClientData> membersOfGroup = this.clientReadPlatformService.retrieveActiveClientMembersOfGroup(groupId);
|
final Collection<ClientData> membersOfGroup = this.clientReadPlatformService.retrieveActiveClientMembersOfGroup(groupId);
|
||||||
@@ -1546,7 +1544,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
|
|
||||||
final StringBuilder sqlBuilder = new StringBuilder(400);
|
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||||
sqlBuilder.append("select ").append(rm.schema())
|
sqlBuilder.append("select ").append(rm.schema())
|
||||||
.append(" where " + sqlGenerator.subDate(sqlGenerator.currentDate(), "?", "day") + " > ls.duedate ")
|
.append(" where " + sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "?", "day") + " > ls.duedate ")
|
||||||
.append(" and ls.completed_derived <> true and mc.charge_applies_to_enum =1 ")
|
.append(" and ls.completed_derived <> true and mc.charge_applies_to_enum =1 ")
|
||||||
.append(" and ls.recalculated_interest_component <> true ")
|
.append(" and ls.recalculated_interest_component <> true ")
|
||||||
.append(" and mc.charge_time_enum = 9 and ml.loan_status_id = 300 ");
|
.append(" and mc.charge_time_enum = 9 and ml.loan_status_id = 300 ");
|
||||||
@@ -1556,7 +1554,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
}
|
}
|
||||||
// Only apply for duedate = yesterday (so that we don't apply
|
// Only apply for duedate = yesterday (so that we don't apply
|
||||||
// penalties on the duedate itself)
|
// penalties on the duedate itself)
|
||||||
sqlBuilder.append(" and ls.duedate >= " + sqlGenerator.subDate(sqlGenerator.currentDate(), "(? + 1)", "day"));
|
sqlBuilder.append(" and ls.duedate >= " + sqlGenerator.subDate(sqlGenerator.currentBusinessDate(), "(? + 1)", "day"));
|
||||||
|
|
||||||
return this.jdbcTemplate.query(sqlBuilder.toString(), rm, new Object[] { penaltyWaitPeriod, penaltyWaitPeriod });
|
return this.jdbcTemplate.query(sqlBuilder.toString(), rm, new Object[] { penaltyWaitPeriod, penaltyWaitPeriod });
|
||||||
}
|
}
|
||||||
@@ -1666,18 +1664,17 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
.append(" and (((ls.fee_charges_amount <> COALESCE(ls.accrual_fee_charges_derived, 0))")
|
.append(" and (((ls.fee_charges_amount <> COALESCE(ls.accrual_fee_charges_derived, 0))")
|
||||||
.append(" or ( ls.penalty_charges_amount <> COALESCE(ls.accrual_penalty_charges_derived, 0))")
|
.append(" or ( ls.penalty_charges_amount <> COALESCE(ls.accrual_penalty_charges_derived, 0))")
|
||||||
.append(" or ( ls.interest_amount <> COALESCE(ls.accrual_interest_derived, 0)))")
|
.append(" or ( ls.interest_amount <> COALESCE(ls.accrual_interest_derived, 0)))")
|
||||||
.append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and loan.is_npa=false and ls.duedate <= "
|
.append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and loan.is_npa=false and ls.duedate <= :currentDate) ");
|
||||||
+ sqlGenerator.currentDate() + ") ");
|
|
||||||
if (organisationStartDate != null) {
|
if (organisationStartDate != null) {
|
||||||
sqlBuilder.append(" and ls.duedate > :organisationstartdate ");
|
sqlBuilder.append(" and ls.duedate > :organisationStartDate ");
|
||||||
}
|
}
|
||||||
sqlBuilder.append(" order by loan.id,ls.duedate ");
|
sqlBuilder.append(" order by loan.id,ls.duedate ");
|
||||||
Map<String, Object> paramMap = new HashMap<>(3);
|
Map<String, Object> paramMap = new HashMap<>(3);
|
||||||
paramMap.put("active", LoanStatus.ACTIVE.getValue());
|
paramMap.put("active", LoanStatus.ACTIVE.getValue());
|
||||||
paramMap.put("type", AccountingRuleType.ACCRUAL_PERIODIC.getValue());
|
paramMap.put("type", AccountingRuleType.ACCRUAL_PERIODIC.getValue());
|
||||||
paramMap.put("organisationstartdate",
|
paramMap.put("organisationStartDate", (organisationStartDate == null) ? DateUtils.getBusinessLocalDate()
|
||||||
(organisationStartDate == null) ? formatter.format(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()))
|
: LocalDate.ofInstant(organisationStartDate.toInstant(), DateUtils.getDateTimeZoneOfTenant()));
|
||||||
: formatter.format(LocalDate.ofInstant(organisationStartDate.toInstant(), DateUtils.getDateTimeZoneOfTenant())));
|
paramMap.put("currentDate", DateUtils.getBusinessLocalDate());
|
||||||
|
|
||||||
return this.namedParameterJdbcTemplate.query(sqlBuilder.toString(), paramMap, mapper);
|
return this.namedParameterJdbcTemplate.query(sqlBuilder.toString(), paramMap, mapper);
|
||||||
}
|
}
|
||||||
@@ -1687,26 +1684,24 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
|
|
||||||
LoanSchedulePeriodicAccrualMapper mapper = new LoanSchedulePeriodicAccrualMapper();
|
LoanSchedulePeriodicAccrualMapper mapper = new LoanSchedulePeriodicAccrualMapper();
|
||||||
Date organisationStartDate = this.configurationDomainService.retrieveOrganisationStartDate();
|
Date organisationStartDate = this.configurationDomainService.retrieveOrganisationStartDate();
|
||||||
String formattedTillDate = formatter.format(tillDate);
|
|
||||||
final StringBuilder sqlBuilder = new StringBuilder(400);
|
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||||
sqlBuilder.append("select ").append(mapper.schema()).append(
|
sqlBuilder.append("select ").append(mapper.schema()).append(
|
||||||
" where (recaldet.is_compounding_to_be_posted_as_transaction is null or recaldet.is_compounding_to_be_posted_as_transaction = false) ")
|
" where (recaldet.is_compounding_to_be_posted_as_transaction is null or recaldet.is_compounding_to_be_posted_as_transaction = false) ")
|
||||||
.append(" and (((ls.fee_charges_amount <> COALESCE(ls.accrual_fee_charges_derived, 0))")
|
.append(" and (((ls.fee_charges_amount <> COALESCE(ls.accrual_fee_charges_derived, 0))")
|
||||||
.append(" or (ls.penalty_charges_amount <> COALESCE(ls.accrual_penalty_charges_derived, 0))")
|
.append(" or (ls.penalty_charges_amount <> COALESCE(ls.accrual_penalty_charges_derived, 0))")
|
||||||
.append(" or (ls.interest_amount <> COALESCE(ls.accrual_interest_derived, 0)))")
|
.append(" or (ls.interest_amount <> COALESCE(ls.accrual_interest_derived, 0)))")
|
||||||
.append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and (loan.closedon_date <= '" + formattedTillDate
|
.append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and (loan.closedon_date <= :tillDate or loan.closedon_date is null)")
|
||||||
+ "' or loan.closedon_date is null)")
|
.append(" and loan.is_npa=false and (ls.duedate <= :tillDate or (ls.duedate > :tillDate and ls.fromdate < :tillDate))) ");
|
||||||
.append(" and loan.is_npa=false and (ls.duedate <= '" + formattedTillDate + "' or (ls.duedate > '" + formattedTillDate
|
Map<String, Object> paramMap = new HashMap<>(4);
|
||||||
+ "' and ls.fromdate < '" + formattedTillDate + "'))) ");
|
|
||||||
if (organisationStartDate != null) {
|
if (organisationStartDate != null) {
|
||||||
String formattedOrganizationStartDate = formatter
|
sqlBuilder.append(" and ls.duedate > :organisationStartDate ");
|
||||||
.format(LocalDate.ofInstant(organisationStartDate.toInstant(), DateUtils.getDateTimeZoneOfTenant()));
|
paramMap.put("organisationStartDate",
|
||||||
sqlBuilder.append(" and ls.duedate > '" + formattedOrganizationStartDate + "' ");
|
LocalDate.ofInstant(organisationStartDate.toInstant(), DateUtils.getDateTimeZoneOfTenant()));
|
||||||
}
|
}
|
||||||
sqlBuilder.append(" order by loan.id,ls.duedate ");
|
sqlBuilder.append(" order by loan.id,ls.duedate ");
|
||||||
Map<String, Object> paramMap = new HashMap<>(4);
|
|
||||||
paramMap.put("active", LoanStatus.ACTIVE.getValue());
|
paramMap.put("active", LoanStatus.ACTIVE.getValue());
|
||||||
paramMap.put("type", AccountingRuleType.ACCRUAL_PERIODIC.getValue());
|
paramMap.put("type", AccountingRuleType.ACCRUAL_PERIODIC.getValue());
|
||||||
|
paramMap.put("tillDate", tillDate);
|
||||||
|
|
||||||
return this.namedParameterJdbcTemplate.query(sqlBuilder.toString(), paramMap, mapper);
|
return this.namedParameterJdbcTemplate.query(sqlBuilder.toString(), paramMap, mapper);
|
||||||
}
|
}
|
||||||
@@ -1852,7 +1847,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
final List<CodeValueData> writeOffReasonOptions = new ArrayList<>(
|
final List<CodeValueData> writeOffReasonOptions = new ArrayList<>(
|
||||||
this.codeValueReadPlatformService.retrieveCodeValuesByCode(LoanApiConstants.WRITEOFFREASONS));
|
this.codeValueReadPlatformService.retrieveCodeValuesByCode(LoanApiConstants.WRITEOFFREASONS));
|
||||||
LoanTransactionData loanTransactionData = new LoanTransactionData(null, null, null, transactionType, null, loan.currency(),
|
LoanTransactionData loanTransactionData = new LoanTransactionData(null, null, null, transactionType, null, loan.currency(),
|
||||||
DateUtils.getLocalDateOfTenant(), loan.getTotalOutstandingAmount(), loan.getNetDisbursalAmount(), null, null, null, null,
|
DateUtils.getBusinessLocalDate(), loan.getTotalOutstandingAmount(), loan.getNetDisbursalAmount(), null, null, null, null,
|
||||||
null, null, null, null, outstandingLoanBalance, unrecognizedIncomePortion, false);
|
null, null, null, null, outstandingLoanBalance, unrecognizedIncomePortion, false);
|
||||||
loanTransactionData.setWriteOffReasonOptions(writeOffReasonOptions);
|
loanTransactionData.setWriteOffReasonOptions(writeOffReasonOptions);
|
||||||
return loanTransactionData;
|
return loanTransactionData;
|
||||||
@@ -1891,9 +1886,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
sqlBuilder.append(" ))");
|
sqlBuilder.append(" ))");
|
||||||
sqlBuilder.append(" group by ml.id");
|
sqlBuilder.append(" group by ml.id");
|
||||||
try {
|
try {
|
||||||
String currentdate = formatter.format(DateUtils.getLocalDateOfTenant());
|
LocalDate currentdate = DateUtils.getBusinessLocalDate();
|
||||||
// will look only for yesterday modified rates
|
// will look only for yesterday modified rates
|
||||||
String yesterday = formatter.format(DateUtils.getLocalDateOfTenant().minusDays(1));
|
LocalDate yesterday = DateUtils.getBusinessLocalDate().minusDays(1);
|
||||||
return this.jdbcTemplate.queryForList(sqlBuilder.toString(), Long.class,
|
return this.jdbcTemplate.queryForList(sqlBuilder.toString(), Long.class,
|
||||||
new Object[] { yesterday, LoanStatus.ACTIVE.getValue(), currentdate, currentdate, currentdate, yesterday });
|
new Object[] { yesterday, LoanStatus.ACTIVE.getValue(), currentdate, currentdate, currentdate, yesterday });
|
||||||
} catch (final EmptyResultDataAccessException e) {
|
} catch (final EmptyResultDataAccessException e) {
|
||||||
@@ -1903,9 +1898,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Long> fetchLoansForInterestRecalculation(Integer pageSize, Long maxLoanIdInList, String officeHierarchy) {
|
public List<Long> fetchLoansForInterestRecalculation(Integer pageSize, Long maxLoanIdInList, String officeHierarchy) {
|
||||||
String currentdate = formatter.format(DateUtils.getLocalDateOfTenant());
|
LocalDate currentdate = DateUtils.getBusinessLocalDate();
|
||||||
// will look only for yesterday modified rates
|
// will look only for yesterday modified rates
|
||||||
String yesterday = formatter.format(DateUtils.getLocalDateOfTenant().minusDays(1));
|
LocalDate yesterday = DateUtils.getBusinessLocalDate().minusDays(1);
|
||||||
StringBuilder sqlBuilder = new StringBuilder();
|
StringBuilder sqlBuilder = new StringBuilder();
|
||||||
sqlBuilder.append("SELECT ml.id FROM m_loan ml ");
|
sqlBuilder.append("SELECT ml.id FROM m_loan ml ");
|
||||||
sqlBuilder.append(" left join m_client mc on mc.id = ml.client_id ");
|
sqlBuilder.append(" left join m_client mc on mc.id = ml.client_id ");
|
||||||
@@ -1920,20 +1915,19 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
sqlBuilder.append(" left join m_loan_reschedule_request lrr on lrr.loan_id = ml.id");
|
sqlBuilder.append(" left join m_loan_reschedule_request lrr on lrr.loan_id = ml.id");
|
||||||
// this is to identify the applicable rates when base rate is changed
|
// this is to identify the applicable rates when base rate is changed
|
||||||
sqlBuilder.append(" left join m_floating_rates bfr on bfr.is_base_lending_rate = true");
|
sqlBuilder.append(" left join m_floating_rates bfr on bfr.is_base_lending_rate = true");
|
||||||
sqlBuilder.append(" left join m_floating_rates_periods bfrp on bfr.id = bfrp.floating_rates_id and bfrp.created_date >= '"
|
sqlBuilder.append(" left join m_floating_rates_periods bfrp on bfr.id = bfrp.floating_rates_id and bfrp.created_date >= ?");
|
||||||
+ yesterday + "'");
|
|
||||||
sqlBuilder.append(" WHERE ml.loan_status_id = ? ");
|
sqlBuilder.append(" WHERE ml.loan_status_id = ? ");
|
||||||
sqlBuilder.append(" and ml.is_npa = false ");
|
sqlBuilder.append(" and ml.is_npa = false ");
|
||||||
sqlBuilder.append(" and ((");
|
sqlBuilder.append(" and ((");
|
||||||
sqlBuilder.append("ml.interest_recalculation_enabled = true ");
|
sqlBuilder.append("ml.interest_recalculation_enabled = true ");
|
||||||
sqlBuilder.append(" and (ml.interest_recalcualated_on is null or ml.interest_recalcualated_on <> '" + currentdate + "')");
|
sqlBuilder.append(" and (ml.interest_recalcualated_on is null or ml.interest_recalcualated_on <> ? )");
|
||||||
sqlBuilder.append(" and ((");
|
sqlBuilder.append(" and ((");
|
||||||
sqlBuilder.append(" mr.completed_derived is false ");
|
sqlBuilder.append(" mr.completed_derived is false ");
|
||||||
sqlBuilder.append(" and mr.duedate < '" + currentdate + "' )");
|
sqlBuilder.append(" and mr.duedate < ? )");
|
||||||
sqlBuilder.append(" or dd.expected_disburse_date < '" + currentdate + "' )) ");
|
sqlBuilder.append(" or dd.expected_disburse_date < ? )) ");
|
||||||
sqlBuilder.append(" or (");
|
sqlBuilder.append(" or (");
|
||||||
sqlBuilder.append(" fr.is_active = true and frp.is_active = true");
|
sqlBuilder.append(" fr.is_active = true and frp.is_active = true");
|
||||||
sqlBuilder.append(" and (frp.created_date >= '" + yesterday + "' or ");
|
sqlBuilder.append(" and (frp.created_date >= ? or ");
|
||||||
sqlBuilder
|
sqlBuilder
|
||||||
.append("(bfrp.id is not null and frp.is_differential_to_base_lending_rate = true and frp.from_date >= bfrp.from_date)) ");
|
.append("(bfrp.id is not null and frp.is_differential_to_base_lending_rate = true and frp.from_date >= bfrp.from_date)) ");
|
||||||
sqlBuilder.append("and lrr.loan_id is null");
|
sqlBuilder.append("and lrr.loan_id is null");
|
||||||
@@ -1943,7 +1937,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
sqlBuilder.append(" limit ? ");
|
sqlBuilder.append(" limit ? ");
|
||||||
try {
|
try {
|
||||||
return Collections.synchronizedList(this.jdbcTemplate.queryForList(sqlBuilder.toString(), Long.class,
|
return Collections.synchronizedList(this.jdbcTemplate.queryForList(sqlBuilder.toString(), Long.class,
|
||||||
new Object[] { LoanStatus.ACTIVE.getValue(), maxLoanIdInList, officeHierarchy, pageSize }));
|
new Object[] { yesterday, LoanStatus.ACTIVE.getValue(), currentdate, currentdate, currentdate, yesterday,
|
||||||
|
maxLoanIdInList, officeHierarchy, pageSize }));
|
||||||
} catch (final EmptyResultDataAccessException e) {
|
} catch (final EmptyResultDataAccessException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -2105,7 +2100,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
+ " + SUM(COALESCE(mr.interest_completed_derived, 0)) " + " + SUM(COALESCE(mr.fee_charges_completed_derived, 0)) "
|
+ " + SUM(COALESCE(mr.interest_completed_derived, 0)) " + " + SUM(COALESCE(mr.fee_charges_completed_derived, 0)) "
|
||||||
+ " + SUM(COALESCE(mr.penalty_charges_completed_derived, 0))) as total_in_advance_derived "
|
+ " + SUM(COALESCE(mr.penalty_charges_completed_derived, 0))) as total_in_advance_derived "
|
||||||
+ " from m_loan ml INNER JOIN m_loan_repayment_schedule mr on mr.loan_id = ml.id "
|
+ " from m_loan ml INNER JOIN m_loan_repayment_schedule mr on mr.loan_id = ml.id "
|
||||||
+ " where ml.id=? and mr.duedate >= " + sqlGenerator.currentDate() + " group by ml.id having "
|
+ " where ml.id=? and mr.duedate >= " + sqlGenerator.currentBusinessDate() + " group by ml.id having "
|
||||||
+ " (SUM(COALESCE(mr.principal_completed_derived, 0)) " + " + SUM(COALESCE(mr.interest_completed_derived, 0)) "
|
+ " (SUM(COALESCE(mr.principal_completed_derived, 0)) " + " + SUM(COALESCE(mr.interest_completed_derived, 0)) "
|
||||||
+ " + SUM(COALESCE(mr.fee_charges_completed_derived, 0)) "
|
+ " + SUM(COALESCE(mr.fee_charges_completed_derived, 0)) "
|
||||||
+ "+ SUM(COALESCE(mr.penalty_charges_completed_derived, 0))) > 0";
|
+ "+ SUM(COALESCE(mr.penalty_charges_completed_derived, 0))) > 0";
|
||||||
@@ -2200,7 +2195,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Long> retrieveLoanIdsWithPendingIncomePostingTransactions() {
|
public Collection<Long> retrieveLoanIdsWithPendingIncomePostingTransactions() {
|
||||||
String currentdate = formatter.format(DateUtils.getLocalDateOfTenant());
|
LocalDate currentdate = DateUtils.getBusinessLocalDate();
|
||||||
StringBuilder sqlBuilder = new StringBuilder().append(" select distinct loan.id ").append(" from m_loan as loan ").append(
|
StringBuilder sqlBuilder = new StringBuilder().append(" select distinct loan.id ").append(" from m_loan as loan ").append(
|
||||||
" inner join m_loan_recalculation_details as recdet on (recdet.loan_id = loan.id and recdet.is_compounding_to_be_posted_as_transaction is not null and recdet.is_compounding_to_be_posted_as_transaction = true) ")
|
" inner join m_loan_recalculation_details as recdet on (recdet.loan_id = loan.id and recdet.is_compounding_to_be_posted_as_transaction is not null and recdet.is_compounding_to_be_posted_as_transaction = true) ")
|
||||||
.append(" inner join m_loan_repayment_schedule as repsch on repsch.loan_id = loan.id ")
|
.append(" inner join m_loan_repayment_schedule as repsch on repsch.loan_id = loan.id ")
|
||||||
@@ -2208,9 +2203,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
.append(" left join m_loan_transaction as trans on (trans.is_reversed <> true and trans.transaction_type_enum = 19 and trans.loan_id = loan.id and trans.transaction_date = adddet.effective_date) ")
|
.append(" left join m_loan_transaction as trans on (trans.is_reversed <> true and trans.transaction_type_enum = 19 and trans.loan_id = loan.id and trans.transaction_date = adddet.effective_date) ")
|
||||||
.append(" where loan.loan_status_id = 300 ").append(" and loan.is_npa = false ")
|
.append(" where loan.loan_status_id = 300 ").append(" and loan.is_npa = false ")
|
||||||
.append(" and adddet.effective_date is not null ").append(" and trans.transaction_date is null ")
|
.append(" and adddet.effective_date is not null ").append(" and trans.transaction_date is null ")
|
||||||
.append(" and adddet.effective_date < '" + currentdate + "' ");
|
.append(" and adddet.effective_date < ? ");
|
||||||
try {
|
try {
|
||||||
return this.jdbcTemplate.queryForList(sqlBuilder.toString(), Long.class);
|
return this.jdbcTemplate.queryForList(sqlBuilder.toString(), new Object[] { currentdate }, Long.class);
|
||||||
} catch (final EmptyResultDataAccessException e) {
|
} catch (final EmptyResultDataAccessException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -2227,7 +2222,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
|
|
||||||
final CurrencyData currencyData = applicationCurrency.toData();
|
final CurrencyData currencyData = applicationCurrency.toData();
|
||||||
|
|
||||||
final LocalDate earliestUnpaidInstallmentDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate earliestUnpaidInstallmentDate = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = loan.fetchLoanForeclosureDetail(transactionDate);
|
final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = loan.fetchLoanForeclosureDetail(transactionDate);
|
||||||
BigDecimal unrecognizedIncomePortion = null;
|
BigDecimal unrecognizedIncomePortion = null;
|
||||||
@@ -2377,13 +2372,15 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
|
|
||||||
sqlBuilder.append(
|
sqlBuilder.append(
|
||||||
"l.id as loanId, coalesce((l.approved_principal - l.principal_disbursed_derived), 0) as availableDisbursementAmount, ");
|
"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(
|
||||||
|
sqlGenerator.dateDiff(sqlGenerator.currentBusinessDate(), "laa.overdue_since_date_derived") + " as pastDueDays, ");
|
||||||
sqlBuilder.append(
|
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 >= "
|
"(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, ");
|
+ sqlGenerator.currentBusinessDate() + ") as nextPaymentDueDate, ");
|
||||||
sqlBuilder.append(sqlGenerator.dateDiff(sqlGenerator.currentDate(), "laa.overdue_since_date_derived") + " as delinquentDays, ");
|
|
||||||
sqlBuilder.append(
|
sqlBuilder.append(
|
||||||
sqlGenerator.currentDate() + " as delinquentDate, coalesce(laa.total_overdue_derived, 0) as delinquentAmount, ");
|
sqlGenerator.dateDiff(sqlGenerator.currentBusinessDate(), "laa.overdue_since_date_derived") + " as delinquentDays, ");
|
||||||
|
sqlBuilder.append(sqlGenerator.currentBusinessDate()
|
||||||
|
+ " as delinquentDate, coalesce(laa.total_overdue_derived, 0) as delinquentAmount, ");
|
||||||
sqlBuilder.append("lre.transactionDate as lastPaymentDate, coalesce(lre.amount, 0) as lastPaymentAmount ");
|
sqlBuilder.append("lre.transactionDate as lastPaymentDate, coalesce(lre.amount, 0) as lastPaymentAmount ");
|
||||||
sqlBuilder.append("from m_loan l left join m_loan_arrears_aging laa on laa.loan_id = l.id ");
|
sqlBuilder.append("from m_loan l left join m_loan_arrears_aging laa on laa.loan_id = l.id ");
|
||||||
sqlBuilder.append(
|
sqlBuilder.append(
|
||||||
|
|||||||
+11
-12
@@ -587,7 +587,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final Integer instructionType = StandingInstructionType.DUES.getValue();
|
final Integer instructionType = StandingInstructionType.DUES.getValue();
|
||||||
final Integer status = StandingInstructionStatus.ACTIVE.getValue();
|
final Integer status = StandingInstructionStatus.ACTIVE.getValue();
|
||||||
final Integer recurrenceType = AccountTransferRecurrenceType.AS_PER_DUES.getValue();
|
final Integer recurrenceType = AccountTransferRecurrenceType.AS_PER_DUES.getValue();
|
||||||
final LocalDate validFrom = LocalDate.now(DateUtils.getDateTimeZoneOfTenant());
|
final LocalDate validFrom = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
AccountTransferDetails accountTransferDetails = AccountTransferDetails.savingsToLoanTransfer(fromOffice, fromClient,
|
AccountTransferDetails accountTransferDetails = AccountTransferDetails.savingsToLoanTransfer(fromOffice, fromClient,
|
||||||
linkedSavingsAccount, toOffice, toClient, loan, transferType);
|
linkedSavingsAccount, toOffice, toClient, loan, transferType);
|
||||||
@@ -1619,7 +1619,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
this.loanTransactionRepository.saveAndFlush(applyLoanChargeTransaction);
|
this.loanTransactionRepository.saveAndFlush(applyLoanChargeTransaction);
|
||||||
}
|
}
|
||||||
boolean isAppliedOnBackDate = false;
|
boolean isAppliedOnBackDate = false;
|
||||||
if (loanCharge.getDueLocalDate() == null || DateUtils.getLocalDateOfTenant().isAfter(loanCharge.getDueLocalDate())) {
|
if (loanCharge.getDueLocalDate() == null || DateUtils.getBusinessLocalDate().isAfter(loanCharge.getDueLocalDate())) {
|
||||||
isAppliedOnBackDate = true;
|
isAppliedOnBackDate = true;
|
||||||
}
|
}
|
||||||
return isAppliedOnBackDate;
|
return isAppliedOnBackDate;
|
||||||
@@ -2053,29 +2053,28 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
.retrieveInstallmentLoanCharges(chargeData.getId(), true);
|
.retrieveInstallmentLoanCharges(chargeData.getId(), true);
|
||||||
PortfolioAccountData portfolioAccountData = null;
|
PortfolioAccountData portfolioAccountData = null;
|
||||||
for (final LoanInstallmentChargeData installmentChargeData : chargePerInstallments) {
|
for (final LoanInstallmentChargeData installmentChargeData : chargePerInstallments) {
|
||||||
if (!installmentChargeData.getDueDate().isAfter(DateUtils.getLocalDateOfTenant())) {
|
if (!installmentChargeData.getDueDate().isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
if (portfolioAccountData == null) {
|
if (portfolioAccountData == null) {
|
||||||
portfolioAccountData = this.accountAssociationsReadPlatformService
|
portfolioAccountData = this.accountAssociationsReadPlatformService
|
||||||
.retriveLoanLinkedAssociation(chargeData.getLoanId());
|
.retriveLoanLinkedAssociation(chargeData.getLoanId());
|
||||||
}
|
}
|
||||||
final SavingsAccount fromSavingsAccount = null;
|
final SavingsAccount fromSavingsAccount = null;
|
||||||
final boolean isExceptionForBalanceCheck = false;
|
final boolean isExceptionForBalanceCheck = false;
|
||||||
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(
|
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(DateUtils.getBusinessLocalDate(),
|
||||||
LocalDate.now(DateUtils.getDateTimeZoneOfTenant()), installmentChargeData.getAmountOutstanding(),
|
installmentChargeData.getAmountOutstanding(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN,
|
||||||
PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, portfolioAccountData.accountId(),
|
portfolioAccountData.accountId(), chargeData.getLoanId(), "Loan Charge Payment", null, null, null, null,
|
||||||
chargeData.getLoanId(), "Loan Charge Payment", null, null, null, null,
|
|
||||||
LoanTransactionType.CHARGE_PAYMENT.getValue(), chargeData.getId(),
|
LoanTransactionType.CHARGE_PAYMENT.getValue(), chargeData.getId(),
|
||||||
installmentChargeData.getInstallmentNumber(), AccountTransferType.CHARGE_PAYMENT.getValue(), null, null,
|
installmentChargeData.getInstallmentNumber(), AccountTransferType.CHARGE_PAYMENT.getValue(), null, null,
|
||||||
null, null, null, fromSavingsAccount, isRegularTransaction, isExceptionForBalanceCheck);
|
null, null, null, fromSavingsAccount, isRegularTransaction, isExceptionForBalanceCheck);
|
||||||
transferFeeCharge(accountTransferDTO, errors);
|
transferFeeCharge(accountTransferDTO, errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (chargeData.getDueDate() != null && !chargeData.getDueDate().isAfter(DateUtils.getLocalDateOfTenant())) {
|
} else if (chargeData.getDueDate() != null && !chargeData.getDueDate().isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final PortfolioAccountData portfolioAccountData = this.accountAssociationsReadPlatformService
|
final PortfolioAccountData portfolioAccountData = this.accountAssociationsReadPlatformService
|
||||||
.retriveLoanLinkedAssociation(chargeData.getLoanId());
|
.retriveLoanLinkedAssociation(chargeData.getLoanId());
|
||||||
final SavingsAccount fromSavingsAccount = null;
|
final SavingsAccount fromSavingsAccount = null;
|
||||||
final boolean isExceptionForBalanceCheck = false;
|
final boolean isExceptionForBalanceCheck = false;
|
||||||
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()),
|
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(DateUtils.getBusinessLocalDate(),
|
||||||
chargeData.getAmountOutstanding(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN,
|
chargeData.getAmountOutstanding(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN,
|
||||||
portfolioAccountData.accountId(), chargeData.getLoanId(), "Loan Charge Payment", null, null, null, null,
|
portfolioAccountData.accountId(), chargeData.getLoanId(), "Loan Charge Payment", null, null, null, null,
|
||||||
LoanTransactionType.CHARGE_PAYMENT.getValue(), chargeData.getId(), null,
|
LoanTransactionType.CHARGE_PAYMENT.getValue(), chargeData.getId(), null,
|
||||||
@@ -2607,7 +2606,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
boolean runInterestRecalculation = false;
|
boolean runInterestRecalculation = false;
|
||||||
LocalDate recalculateFrom = DateUtils.getLocalDateOfTenant();
|
LocalDate recalculateFrom = DateUtils.getBusinessLocalDate();
|
||||||
LocalDate lastChargeDate = null;
|
LocalDate lastChargeDate = null;
|
||||||
for (final OverdueLoanScheduleData overdueInstallment : overdueLoanScheduleDatas) {
|
for (final OverdueLoanScheduleData overdueInstallment : overdueLoanScheduleDatas) {
|
||||||
|
|
||||||
@@ -2714,7 +2713,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
if (feeFrequency == null) {
|
if (feeFrequency == null) {
|
||||||
scheduleDates.put(frequencyNunber++, startDate.minusDays(diff));
|
scheduleDates.put(frequencyNunber++, startDate.minusDays(diff));
|
||||||
} else {
|
} else {
|
||||||
while (!startDate.isAfter(DateUtils.getLocalDateOfTenant())) {
|
while (!startDate.isAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
scheduleDates.put(frequencyNunber++, startDate.minusDays(diff));
|
scheduleDates.put(frequencyNunber++, startDate.minusDays(diff));
|
||||||
LocalDate scheduleDate = scheduledDateGenerator.getRepaymentPeriodDate(PeriodFrequencyType.fromInt(feeFrequency),
|
LocalDate scheduleDate = scheduledDateGenerator.getRepaymentPeriodDate(PeriodFrequencyType.fromInt(feeFrequency),
|
||||||
chargeDefinition.feeInterval(), startDate);
|
chargeDefinition.feeInterval(), startDate);
|
||||||
@@ -2739,7 +2738,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
installment = loan.fetchRepaymentScheduleInstallment(periodNumber);
|
installment = loan.fetchRepaymentScheduleInstallment(periodNumber);
|
||||||
lastChargeAppliedDate = installment.getDueDate();
|
lastChargeAppliedDate = installment.getDueDate();
|
||||||
}
|
}
|
||||||
LocalDate recalculateFrom = DateUtils.getLocalDateOfTenant();
|
LocalDate recalculateFrom = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
if (loan != null) {
|
if (loan != null) {
|
||||||
businessEventNotifierService.notifyPreBusinessEvent(new LoanApplyOverdueChargeBusinessEvent(loan));
|
businessEventNotifierService.notifyPreBusinessEvent(new LoanApplyOverdueChargeBusinessEvent(loan));
|
||||||
|
|||||||
+2
-2
@@ -335,7 +335,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
final LocalDate startDate = JdbcSupport.getLocalDate(rs, "startDate");
|
final LocalDate startDate = JdbcSupport.getLocalDate(rs, "startDate");
|
||||||
final LocalDate closeDate = JdbcSupport.getLocalDate(rs, "closeDate");
|
final LocalDate closeDate = JdbcSupport.getLocalDate(rs, "closeDate");
|
||||||
String status = "";
|
String status = "";
|
||||||
if (closeDate != null && closeDate.isBefore(DateUtils.getLocalDateOfTenant())) {
|
if (closeDate != null && closeDate.isBefore(DateUtils.getBusinessLocalDate())) {
|
||||||
status = "loanProduct.inActive";
|
status = "loanProduct.inActive";
|
||||||
} else {
|
} else {
|
||||||
status = "loanProduct.active";
|
status = "loanProduct.active";
|
||||||
@@ -499,7 +499,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String activeOnlySchema() {
|
public String activeOnlySchema() {
|
||||||
return schema() + " where (close_date is null or close_date >= " + sqlGenerator.currentDate() + ")";
|
return schema() + " where (close_date is null or close_date >= " + sqlGenerator.currentBusinessDate() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String productMixSchema() {
|
public String productMixSchema() {
|
||||||
|
|||||||
+1
-1
@@ -130,7 +130,7 @@ public class MeetingsApiResource {
|
|||||||
calendarData = this.calendarReadPlatformService.retrieveCalendar(calendarId, entityId, entityTypeId);
|
calendarData = this.calendarReadPlatformService.retrieveCalendar(calendarId, entityId, entityTypeId);
|
||||||
final boolean withHistory = true;
|
final boolean withHistory = true;
|
||||||
final Collection<LocalDate> recurringDates = this.calendarReadPlatformService.generateRecurringDates(calendarData, withHistory,
|
final Collection<LocalDate> recurringDates = this.calendarReadPlatformService.generateRecurringDates(calendarData, withHistory,
|
||||||
DateUtils.getLocalDateOfTenant());
|
DateUtils.getBusinessLocalDate());
|
||||||
final Collection<LocalDate> nextTenRecurringDates = this.calendarReadPlatformService
|
final Collection<LocalDate> nextTenRecurringDates = this.calendarReadPlatformService
|
||||||
.generateNextTenRecurringDates(calendarData);
|
.generateNextTenRecurringDates(calendarData);
|
||||||
final LocalDate recentEligibleMeetingDate = null;
|
final LocalDate recentEligibleMeetingDate = null;
|
||||||
|
|||||||
+1
-1
@@ -89,7 +89,7 @@ public class Meeting extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
public void associateClientsAttendance(final Collection<ClientAttendance> clientsAttendance) {
|
public void associateClientsAttendance(final Collection<ClientAttendance> clientsAttendance) {
|
||||||
// do not allow to capture attendance in advance.
|
// do not allow to capture attendance in advance.
|
||||||
if (isMeetingDateAfter(DateUtils.getLocalDateOfTenant())) {
|
if (isMeetingDateAfter(DateUtils.getBusinessLocalDate())) {
|
||||||
final String errorMessage = "Attendance cannot be in the future.";
|
final String errorMessage = "Attendance cannot be in the future.";
|
||||||
throw new MeetingDateException("cannot.be.a.future.date", errorMessage, getMeetingDateLocalDate());
|
throw new MeetingDateException("cannot.be.a.future.date", errorMessage, getMeetingDateLocalDate());
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -234,7 +234,7 @@ public class SavingsAccountSummaryData implements Serializable {
|
|||||||
public void updateFromInterestPeriodSummaries(final MonetaryCurrency currency, final List<PostingPeriod> allPostingPeriods) {
|
public void updateFromInterestPeriodSummaries(final MonetaryCurrency currency, final List<PostingPeriod> allPostingPeriods) {
|
||||||
|
|
||||||
Money totalEarned = Money.zero(currency);
|
Money totalEarned = Money.zero(currency);
|
||||||
LocalDate interestCalculationDate = DateUtils.getLocalDateOfTenant();
|
LocalDate interestCalculationDate = DateUtils.getBusinessLocalDate();
|
||||||
for (final PostingPeriod period : allPostingPeriods) {
|
for (final PostingPeriod period : allPostingPeriods) {
|
||||||
Money interestEarned = period.interest();
|
Money interestEarned = period.interest();
|
||||||
interestEarned = interestEarned == null ? Money.zero(currency) : interestEarned;
|
interestEarned = interestEarned == null ? Money.zero(currency) : interestEarned;
|
||||||
|
|||||||
+1
-1
@@ -934,7 +934,7 @@ public final class SavingsAccountTransactionData implements Serializable {
|
|||||||
public static SavingsAccountTransactionData withWithDrawalTransactionDetails(
|
public static SavingsAccountTransactionData withWithDrawalTransactionDetails(
|
||||||
final SavingsAccountTransactionData savingsAccountTransactionData) {
|
final SavingsAccountTransactionData savingsAccountTransactionData) {
|
||||||
|
|
||||||
final LocalDate currentDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate currentDate = DateUtils.getBusinessLocalDate();
|
||||||
final SavingsAccountTransactionEnumData transactionType = SavingsEnumerations
|
final SavingsAccountTransactionEnumData transactionType = SavingsEnumerations
|
||||||
.transactionType(SavingsAccountTransactionType.WITHDRAWAL.getValue());
|
.transactionType(SavingsAccountTransactionType.WITHDRAWAL.getValue());
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -324,7 +324,7 @@ public class SavingsAccountTransactionDataValidator {
|
|||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
Date createdDate = new Date();
|
Date createdDate = new Date();
|
||||||
LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
SavingsAccountTransaction transaction = SavingsAccountTransaction.releaseAmount(holdTransaction, transactionDate, createdDate,
|
SavingsAccountTransaction transaction = SavingsAccountTransaction.releaseAmount(holdTransaction, transactionDate, createdDate,
|
||||||
createdUser);
|
createdUser);
|
||||||
return transaction;
|
return transaction;
|
||||||
|
|||||||
+1
-1
@@ -355,7 +355,7 @@ public class DepositAccountAssembler {
|
|||||||
|
|
||||||
if (account != null) {
|
if (account != null) {
|
||||||
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
|
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
|
||||||
account.validateNewApplicationState(DateUtils.getLocalDateOfTenant(), depositAccountType.resourceName());
|
account.validateNewApplicationState(DateUtils.getBusinessLocalDate(), depositAccountType.resourceName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return account;
|
return account;
|
||||||
|
|||||||
+1
-1
@@ -161,7 +161,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
|||||||
account.handleScheduleInstallments(deposit);
|
account.handleScheduleInstallments(deposit);
|
||||||
account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
|
account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||||
financialYearBeginningMonth);
|
financialYearBeginningMonth);
|
||||||
account.updateOverduePayments(DateUtils.getLocalDateOfTenant());
|
account.updateOverduePayments(DateUtils.getBusinessLocalDate());
|
||||||
if (isAnyActivationChargesDue) {
|
if (isAnyActivationChargesDue) {
|
||||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
|
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -127,7 +127,7 @@ public class DepositAccountRecurringDetail extends AbstractPersistableCustom {
|
|||||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
}
|
}
|
||||||
depositAccount.updateScheduleInstallmentsWithNewRecommendedDepositAmount(newMandatoryRecommendedDepositAmount, effectiveDate);
|
depositAccount.updateScheduleInstallmentsWithNewRecommendedDepositAmount(newMandatoryRecommendedDepositAmount, effectiveDate);
|
||||||
depositAccount.updateOverduePayments(DateUtils.getLocalDateOfTenant());
|
depositAccount.updateOverduePayments(DateUtils.getBusinessLocalDate());
|
||||||
MathContext mc = MathContext.DECIMAL64;
|
MathContext mc = MathContext.DECIMAL64;
|
||||||
Boolean isPreMatureClosure = false;
|
Boolean isPreMatureClosure = false;
|
||||||
depositAccount.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
|
depositAccount.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||||
|
|||||||
+3
-3
@@ -231,7 +231,7 @@ public class FixedDepositAccount extends SavingsAccount {
|
|||||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth);
|
||||||
|
|
||||||
// reset end of day balance back to today's date
|
// reset end of day balance back to today's date
|
||||||
this.resetAccountTransactionsEndOfDayBalances(transactions, DateUtils.getLocalDateOfTenant());
|
this.resetAccountTransactionsEndOfDayBalances(transactions, DateUtils.getBusinessLocalDate());
|
||||||
|
|
||||||
Money totalInterestPayable = Money.zero(getCurrency());
|
Money totalInterestPayable = Money.zero(getCurrency());
|
||||||
for (PostingPeriod postingPeriod : postingPeriods) {
|
for (PostingPeriod postingPeriod : postingPeriods) {
|
||||||
@@ -256,7 +256,7 @@ public class FixedDepositAccount extends SavingsAccount {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final LocalDate todayDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate todayDate = DateUtils.getBusinessLocalDate();
|
||||||
if (!this.maturityDate().isAfter(todayDate)) {
|
if (!this.maturityDate().isAfter(todayDate)) {
|
||||||
// update account status
|
// update account status
|
||||||
this.status = SavingsAccountStatusType.MATURED.getValue();
|
this.status = SavingsAccountStatusType.MATURED.getValue();
|
||||||
@@ -763,7 +763,7 @@ public class FixedDepositAccount extends SavingsAccount {
|
|||||||
if (this.chart != null) {
|
if (this.chart != null) {
|
||||||
final LocalDate chartFromDate = this.chart.getFromDateAsLocalDate();
|
final LocalDate chartFromDate = this.chart.getFromDateAsLocalDate();
|
||||||
LocalDate chartEndDate = this.chart.getEndDateAsLocalDate();
|
LocalDate chartEndDate = this.chart.getEndDateAsLocalDate();
|
||||||
chartEndDate = chartEndDate == null ? DateUtils.getLocalDateOfTenant() : chartEndDate;
|
chartEndDate = chartEndDate == null ? DateUtils.getBusinessLocalDate() : chartEndDate;
|
||||||
|
|
||||||
final LocalDateInterval chartInterval = LocalDateInterval.create(chartFromDate, chartEndDate);
|
final LocalDateInterval chartInterval = LocalDateInterval.create(chartFromDate, chartEndDate);
|
||||||
if (!chartInterval.contains(accountSubmittedOrActivationDate())) {
|
if (!chartInterval.contains(accountSubmittedOrActivationDate())) {
|
||||||
|
|||||||
+7
-7
@@ -225,7 +225,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (depositCloseDate == null) {
|
if (depositCloseDate == null) {
|
||||||
depositCloseDate = DateUtils.getLocalDateOfTenant();
|
depositCloseDate = DateUtils.getBusinessLocalDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
final BigDecimal depositAmount = accountTermAndPreClosure.depositAmount();
|
final BigDecimal depositAmount = accountTermAndPreClosure.depositAmount();
|
||||||
@@ -248,7 +248,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
LocalDate interestCalculationUpto = null;
|
LocalDate interestCalculationUpto = null;
|
||||||
List<SavingsAccountTransaction> allTransactions = null;
|
List<SavingsAccountTransaction> allTransactions = null;
|
||||||
if (maturityDate == null) {
|
if (maturityDate == null) {
|
||||||
interestCalculationUpto = DateUtils.getLocalDateOfTenant();
|
interestCalculationUpto = DateUtils.getBusinessLocalDate();
|
||||||
allTransactions = getTransactions(interestCalculationUpto, false);
|
allTransactions = getTransactions(interestCalculationUpto, false);
|
||||||
} else {
|
} else {
|
||||||
interestCalculationUpto = maturityDate.minusDays(1);
|
interestCalculationUpto = maturityDate.minusDays(1);
|
||||||
@@ -285,7 +285,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final LocalDate todayDate = DateUtils.getLocalDateOfTenant();
|
final LocalDate todayDate = DateUtils.getBusinessLocalDate();
|
||||||
if (!this.maturityDate().isAfter(todayDate)) {
|
if (!this.maturityDate().isAfter(todayDate)) {
|
||||||
// update account status
|
// update account status
|
||||||
this.status = SavingsAccountStatusType.MATURED.getValue();
|
this.status = SavingsAccountStatusType.MATURED.getValue();
|
||||||
@@ -549,7 +549,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
|
|
||||||
// update existing transactions so derived balance fields are
|
// update existing transactions so derived balance fields are
|
||||||
// correct.
|
// correct.
|
||||||
recalculateDailyBalances(Money.zero(this.currency), DateUtils.getLocalDateOfTenant(), backdatedTxnsAllowedTill);
|
recalculateDailyBalances(Money.zero(this.currency), DateUtils.getBusinessLocalDate(), backdatedTxnsAllowedTill);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1059,7 +1059,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
if (this.chart != null) {
|
if (this.chart != null) {
|
||||||
final LocalDate chartFromDate = this.chart.getFromDateAsLocalDate();
|
final LocalDate chartFromDate = this.chart.getFromDateAsLocalDate();
|
||||||
LocalDate chartEndDate = this.chart.getEndDateAsLocalDate();
|
LocalDate chartEndDate = this.chart.getEndDateAsLocalDate();
|
||||||
chartEndDate = chartEndDate == null ? DateUtils.getLocalDateOfTenant() : chartEndDate;
|
chartEndDate = chartEndDate == null ? DateUtils.getBusinessLocalDate() : chartEndDate;
|
||||||
|
|
||||||
final LocalDateInterval chartInterval = LocalDateInterval.create(chartFromDate, chartEndDate);
|
final LocalDateInterval chartInterval = LocalDateInterval.create(chartFromDate, chartEndDate);
|
||||||
if (!chartInterval.contains(accountSubmittedOrActivationDate())) {
|
if (!chartInterval.contains(accountSubmittedOrActivationDate())) {
|
||||||
@@ -1067,7 +1067,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (maturityDate == null) {
|
if (maturityDate == null) {
|
||||||
maturityDate = DateUtils.getLocalDateOfTenant();
|
maturityDate = DateUtils.getBusinessLocalDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
final BigDecimal maturityAmount = this.accountTermAndPreClosure.depositAmount();
|
final BigDecimal maturityAmount = this.accountTermAndPreClosure.depositAmount();
|
||||||
@@ -1199,7 +1199,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
private LocalDate calcualteScheduleTillDate(final PeriodFrequencyType frequency, final Integer recurringEvery) {
|
private LocalDate calcualteScheduleTillDate(final PeriodFrequencyType frequency, final Integer recurringEvery) {
|
||||||
LocalDate tillDate = calculateMaturityDate();
|
LocalDate tillDate = calculateMaturityDate();
|
||||||
if (tillDate == null) {
|
if (tillDate == null) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||||
tillDate = DepositAccountUtils.calculateNextDepositDate(today, frequency,
|
tillDate = DepositAccountUtils.calculateNextDepositDate(today, frequency,
|
||||||
recurringEvery * (DepositAccountUtils.GENERATE_MINIMUM_NUMBER_OF_FUTURE_INSTALMENTS + 1));
|
recurringEvery * (DepositAccountUtils.GENERATE_MINIMUM_NUMBER_OF_FUTURE_INSTALMENTS + 1));
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-24
@@ -1309,23 +1309,16 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
Integer restartPeriod = charge.getRestartFrequency();
|
Integer restartPeriod = charge.getRestartFrequency();
|
||||||
if (charge.getRestartFrequencyEnum() == 2) { // calculation for months
|
if (charge.getRestartFrequencyEnum() == 2) { // calculation for months
|
||||||
Date currentDate = new Date();
|
LocalDate localDate = DateUtils.getBusinessLocalDate();
|
||||||
LocalDate localDate = currentDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
||||||
Integer currentMonth = localDate.getMonthValue();
|
|
||||||
|
|
||||||
LocalDate resetLocalDate = null;
|
LocalDate resetLocalDate;
|
||||||
if (resetDate == null) {
|
if (resetDate == null) {
|
||||||
resetLocalDate = this.activatedOnDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
resetLocalDate = this.activatedOnDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||||
} else {
|
} else {
|
||||||
resetLocalDate = resetDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
resetLocalDate = resetDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||||
}
|
}
|
||||||
Integer resetMonth = resetLocalDate.getMonthValue();
|
|
||||||
|
|
||||||
LocalDate gapIntervalMonth = resetLocalDate.plusMonths(restartPeriod);
|
LocalDate gapIntervalMonth = resetLocalDate.plusMonths(restartPeriod);
|
||||||
Integer gapMonth = gapIntervalMonth.getMonthValue();
|
|
||||||
|
|
||||||
Integer resetYear = resetLocalDate.getYear();
|
|
||||||
Integer currentYear = localDate.getYear();
|
|
||||||
|
|
||||||
YearMonth gapYearMonth = YearMonth.from(gapIntervalMonth);
|
YearMonth gapYearMonth = YearMonth.from(gapIntervalMonth);
|
||||||
YearMonth localYearMonth = YearMonth.from(localDate);
|
YearMonth localYearMonth = YearMonth.from(localDate);
|
||||||
@@ -1335,18 +1328,18 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
|||||||
discountCharge(1, charge);
|
discountCharge(1, charge);
|
||||||
}
|
}
|
||||||
} else { // calculation for days
|
} else { // calculation for days
|
||||||
Long completedDays = null;
|
Long completedDays;
|
||||||
Long days = null;
|
Long days;
|
||||||
|
|
||||||
if (resetDate == null) {
|
if (resetDate == null) {
|
||||||
completedDays = DateUtils.getDateOfTenant().getTime() - this.activatedOnDate.getTime();
|
completedDays = DateUtils.getBusinessDate().getTime() - this.activatedOnDate.getTime();
|
||||||
days = TimeUnit.DAYS.convert(completedDays, TimeUnit.MILLISECONDS);
|
days = TimeUnit.DAYS.convert(completedDays, TimeUnit.MILLISECONDS);
|
||||||
} else {
|
} else {
|
||||||
completedDays = DateUtils.getDateOfTenant().getTime() - resetDate.getTime();
|
completedDays = DateUtils.getBusinessDate().getTime() - resetDate.getTime();
|
||||||
days = TimeUnit.DAYS.convert(completedDays, TimeUnit.MILLISECONDS);
|
days = TimeUnit.DAYS.convert(completedDays, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer totalDays = days.intValue();
|
int totalDays = days.intValue();
|
||||||
|
|
||||||
if (totalDays < restartPeriod) {
|
if (totalDays < restartPeriod) {
|
||||||
countValidation(charge, transactionAmount, transactionDate, user, refNo);
|
countValidation(charge, transactionAmount, transactionDate, user, refNo);
|
||||||
@@ -1371,7 +1364,7 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
private void discountCharge(Integer freeWithdrawalCount, SavingsAccountCharge charge) {
|
private void discountCharge(Integer freeWithdrawalCount, SavingsAccountCharge charge) {
|
||||||
charge.setFreeWithdrawalCount(freeWithdrawalCount);
|
charge.setFreeWithdrawalCount(freeWithdrawalCount);
|
||||||
charge.setDiscountDueDate(DateUtils.getDateOfTenant());
|
charge.setDiscountDueDate(DateUtils.getBusinessDate());
|
||||||
charge.updateNoWithdrawalFee();
|
charge.updateNoWithdrawalFee();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1572,7 +1565,7 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDateInTheFuture(final LocalDate transactionDate) {
|
private boolean isDateInTheFuture(final LocalDate transactionDate) {
|
||||||
return transactionDate.isAfter(DateUtils.getLocalDateOfTenant());
|
return transactionDate.isAfter(DateUtils.getBusinessLocalDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigDecimal getAccountBalance() {
|
public BigDecimal getAccountBalance() {
|
||||||
@@ -2067,7 +2060,7 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
|||||||
throw new SavingsOfficerAssignmentDateException("cannot.be.before.previous.unassignement.date", errorMessage, assignmentDate,
|
throw new SavingsOfficerAssignmentDateException("cannot.be.before.previous.unassignement.date", errorMessage, assignmentDate,
|
||||||
lastAssignmentRecord.getEndDate());
|
lastAssignmentRecord.getEndDate());
|
||||||
|
|
||||||
} else if (DateUtils.getLocalDateOfTenant().isBefore(assignmentDate)) {
|
} else if (DateUtils.getBusinessLocalDate().isBefore(assignmentDate)) {
|
||||||
|
|
||||||
final String errorMessage = "The Savings Officer assignment date (" + assignmentDate + ") cannot be in the future.";
|
final String errorMessage = "The Savings Officer assignment date (" + assignmentDate + ") cannot be in the future.";
|
||||||
|
|
||||||
@@ -2164,7 +2157,7 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
private void validateUnassignDate(final SavingsOfficerAssignmentHistory latestHistoryRecord, final LocalDate unassignDate) {
|
private void validateUnassignDate(final SavingsOfficerAssignmentHistory latestHistoryRecord, final LocalDate unassignDate) {
|
||||||
|
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||||
|
|
||||||
if (latestHistoryRecord.getStartDate().isAfter(unassignDate)) {
|
if (latestHistoryRecord.getStartDate().isAfter(unassignDate)) {
|
||||||
|
|
||||||
@@ -2768,12 +2761,12 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
|||||||
boolean isInterestTransfer = false;
|
boolean isInterestTransfer = false;
|
||||||
LocalDate postInterestAsOnDate = null;
|
LocalDate postInterestAsOnDate = null;
|
||||||
if (this.isBeforeLastPostingPeriod(getActivationLocalDate(), backdatedTxnsAllowedTill)) {
|
if (this.isBeforeLastPostingPeriod(getActivationLocalDate(), backdatedTxnsAllowedTill)) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||||
boolean postReversals = false;
|
boolean postReversals = false;
|
||||||
this.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
this.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||||
postInterestAsOnDate, backdatedTxnsAllowedTill, postReversals);
|
postInterestAsOnDate, backdatedTxnsAllowedTill, postReversals);
|
||||||
} else {
|
} else {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||||
this.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
this.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||||
financialYearBeginningMonth, postInterestAsOnDate, backdatedTxnsAllowedTill);
|
financialYearBeginningMonth, postInterestAsOnDate, backdatedTxnsAllowedTill);
|
||||||
}
|
}
|
||||||
@@ -3236,7 +3229,7 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
|||||||
private void handleWaiverChargeTransactions(SavingsAccountCharge savingsAccountCharge, Money transactionAmount, AppUser user,
|
private void handleWaiverChargeTransactions(SavingsAccountCharge savingsAccountCharge, Money transactionAmount, AppUser user,
|
||||||
boolean backdatedTxnsAllowedTill) {
|
boolean backdatedTxnsAllowedTill) {
|
||||||
final SavingsAccountTransaction chargeTransaction = SavingsAccountTransaction.waiver(this, office(),
|
final SavingsAccountTransaction chargeTransaction = SavingsAccountTransaction.waiver(this, office(),
|
||||||
DateUtils.getLocalDateOfTenant(), transactionAmount, user);
|
DateUtils.getBusinessLocalDate(), transactionAmount, user);
|
||||||
handleChargeTransactions(savingsAccountCharge, chargeTransaction, backdatedTxnsAllowedTill);
|
handleChargeTransactions(savingsAccountCharge, chargeTransaction, backdatedTxnsAllowedTill);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3511,7 +3504,7 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
public void setSubStatusInactive(AppUser appUser, final boolean backdatedTxnsAllowedTill) {
|
public void setSubStatusInactive(AppUser appUser, final boolean backdatedTxnsAllowedTill) {
|
||||||
this.sub_status = SavingsAccountSubStatusEnum.INACTIVE.getValue();
|
this.sub_status = SavingsAccountSubStatusEnum.INACTIVE.getValue();
|
||||||
LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
for (SavingsAccountCharge charge : this.charges()) {
|
for (SavingsAccountCharge charge : this.charges()) {
|
||||||
if (charge.isSavingsNoActivity() && charge.isActive()) {
|
if (charge.isSavingsNoActivity() && charge.isActive()) {
|
||||||
charge.updateWithdralFeeAmount(this.getAccountBalance());
|
charge.updateWithdralFeeAmount(this.getAccountBalance());
|
||||||
@@ -3531,10 +3524,10 @@ public class SavingsAccount extends AbstractPersistableCustom {
|
|||||||
public void escheat(AppUser appUser) {
|
public void escheat(AppUser appUser) {
|
||||||
this.status = SavingsAccountStatusType.CLOSED.getValue();
|
this.status = SavingsAccountStatusType.CLOSED.getValue();
|
||||||
this.sub_status = SavingsAccountSubStatusEnum.ESCHEAT.getValue();
|
this.sub_status = SavingsAccountSubStatusEnum.ESCHEAT.getValue();
|
||||||
this.closedOnDate = DateUtils.getDateOfTenant();
|
this.closedOnDate = DateUtils.getBusinessDate();
|
||||||
this.closedBy = appUser;
|
this.closedBy = appUser;
|
||||||
boolean postInterestAsOnDate = false;
|
boolean postInterestAsOnDate = false;
|
||||||
LocalDate transactionDate = DateUtils.getLocalDateOfTenant();
|
LocalDate transactionDate = DateUtils.getBusinessLocalDate();
|
||||||
if (this.getSummary().getAccountBalance(this.getCurrency()).isGreaterThanZero()) {
|
if (this.getSummary().getAccountBalance(this.getCurrency()).isGreaterThanZero()) {
|
||||||
SavingsAccountTransaction transaction = SavingsAccountTransaction.escheat(this, transactionDate, appUser, postInterestAsOnDate);
|
SavingsAccountTransaction transaction = SavingsAccountTransaction.escheat(this, transactionDate, appUser, postInterestAsOnDate);
|
||||||
this.transactions.add(transaction);
|
this.transactions.add(transaction);
|
||||||
|
|||||||
+2
-2
@@ -326,7 +326,7 @@ public class SavingsAccountAssembler {
|
|||||||
nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation, withHoldTax);
|
nominalAnnualInterestRateOverdraft, minOverdraftForInterestCalculation, withHoldTax);
|
||||||
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
|
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
|
||||||
|
|
||||||
account.validateNewApplicationState(DateUtils.getLocalDateOfTenant(), SAVINGS_ACCOUNT_RESOURCE_NAME);
|
account.validateNewApplicationState(DateUtils.getBusinessLocalDate(), SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||||
|
|
||||||
account.validateAccountValuesWithProduct();
|
account.validateAccountValuesWithProduct();
|
||||||
|
|
||||||
@@ -444,7 +444,7 @@ public class SavingsAccountAssembler {
|
|||||||
product.withHoldTax());
|
product.withHoldTax());
|
||||||
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
|
account.setHelpers(this.savingsAccountTransactionSummaryWrapper, this.savingsHelper);
|
||||||
|
|
||||||
account.validateNewApplicationState(DateUtils.getLocalDateOfTenant(), SAVINGS_ACCOUNT_RESOURCE_NAME);
|
account.validateNewApplicationState(DateUtils.getBusinessLocalDate(), SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||||
|
|
||||||
account.validateAccountValuesWithProduct();
|
account.validateAccountValuesWithProduct();
|
||||||
|
|
||||||
|
|||||||
+3
-5
@@ -114,13 +114,12 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
|||||||
backdatedTxnsAllowedTill, refNo.toString());
|
backdatedTxnsAllowedTill, refNo.toString());
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
|
|
||||||
|
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate, backdatedTxnsAllowedTill)) {
|
if (account.isBeforeLastPostingPeriod(transactionDate, backdatedTxnsAllowedTill)) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
|
||||||
boolean postReversals = false;
|
boolean postReversals = false;
|
||||||
account.postInterest(mc, today, transactionBooleanValues.isInterestTransfer(), isSavingsInterestPostingAtCurrentPeriodEnd,
|
account.postInterest(mc, today, transactionBooleanValues.isInterestTransfer(), isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||||
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill, postReversals);
|
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill, postReversals);
|
||||||
} else {
|
} else {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
|
||||||
account.calculateInterestUsing(mc, today, transactionBooleanValues.isInterestTransfer(),
|
account.calculateInterestUsing(mc, today, transactionBooleanValues.isInterestTransfer(),
|
||||||
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill);
|
isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill);
|
||||||
}
|
}
|
||||||
@@ -196,13 +195,12 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
|||||||
final LocalDate postInterestOnDate = null;
|
final LocalDate postInterestOnDate = null;
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
|
|
||||||
|
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate, backdatedTxnsAllowedTill)) {
|
if (account.isBeforeLastPostingPeriod(transactionDate, backdatedTxnsAllowedTill)) {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
|
||||||
boolean postReversals = false;
|
boolean postReversals = false;
|
||||||
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth,
|
||||||
postInterestOnDate, backdatedTxnsAllowedTill, postReversals);
|
postInterestOnDate, backdatedTxnsAllowedTill, postReversals);
|
||||||
} else {
|
} else {
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
|
||||||
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd,
|
||||||
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill);
|
financialYearBeginningMonth, postInterestOnDate, backdatedTxnsAllowedTill);
|
||||||
}
|
}
|
||||||
@@ -315,7 +313,7 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
|||||||
|
|
||||||
boolean isInterestTransfer = false;
|
boolean isInterestTransfer = false;
|
||||||
LocalDate postInterestOnDate = null;
|
LocalDate postInterestOnDate = null;
|
||||||
final LocalDate today = DateUtils.getLocalDateOfTenant();
|
final LocalDate today = DateUtils.getBusinessLocalDate();
|
||||||
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
|
final MathContext mc = new MathContext(15, MoneyHelper.getRoundingMode());
|
||||||
for (SavingsAccountTransaction savingsAccountTransaction : savingsAccountTransactions) {
|
for (SavingsAccountTransaction savingsAccountTransaction : savingsAccountTransactions) {
|
||||||
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
if (savingsAccountTransaction.isPostInterestCalculationRequired()
|
||||||
|
|||||||
+1
-1
@@ -241,7 +241,7 @@ public final class SavingsAccountSummary {
|
|||||||
public void updateFromInterestPeriodSummaries(final MonetaryCurrency currency, final List<PostingPeriod> allPostingPeriods) {
|
public void updateFromInterestPeriodSummaries(final MonetaryCurrency currency, final List<PostingPeriod> allPostingPeriods) {
|
||||||
|
|
||||||
Money totalEarned = Money.zero(currency);
|
Money totalEarned = Money.zero(currency);
|
||||||
LocalDate interestCalculationDate = DateUtils.getLocalDateOfTenant();
|
LocalDate interestCalculationDate = DateUtils.getBusinessLocalDate();
|
||||||
for (final PostingPeriod period : allPostingPeriods) {
|
for (final PostingPeriod period : allPostingPeriods) {
|
||||||
Money interestEarned = period.interest();
|
Money interestEarned = period.interest();
|
||||||
interestEarned = interestEarned == null ? Money.zero(currency) : interestEarned;
|
interestEarned = interestEarned == null ? Money.zero(currency) : interestEarned;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user