FINERACT-2009: Upgrade latest framework libs

This commit is contained in:
Aleksandar Vidakovic
2024-01-06 14:13:33 +01:00
committed by Aleksandar Vidakovic
parent 1f3bb34e13
commit e4944c44d6
193 changed files with 1567 additions and 1390 deletions
@@ -83,7 +83,7 @@ public class JournalEntriesApiResource {
"entityType", "entityId", "createdByUserId", "createdDate", "submittedOnDate", "createdByUserName", "comments", "reversed",
"referenceNumber", "currency", "transactionDetails"));
private final String resourceNameForPermission = "JOURNALENTRY";
private static final String RESOURCE_NAME_FOR_PERMISSION = "JOURNALENTRY";
private final PlatformSecurityContext context;
private final JournalEntryReadPlatformService journalEntryReadPlatformService;
@@ -125,7 +125,7 @@ public class JournalEntriesApiResource {
@QueryParam("runningBalance") @Parameter(description = "runningBalance") final boolean runningBalance,
@QueryParam("transactionDetails") @Parameter(description = "transactionDetails") final boolean transactionDetails) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
final DateFormat dateFormat = StringUtils.isBlank(rawDateFormat) ? null : new DateFormat(rawDateFormat);
@@ -174,7 +174,7 @@ public class JournalEntriesApiResource {
@QueryParam("runningBalance") @Parameter(description = "runningBalance") final boolean runningBalance,
@QueryParam("transactionDetails") @Parameter(description = "transactionDetails") final boolean transactionDetails) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
JournalEntryAssociationParametersData associationParametersData = new JournalEntryAssociationParametersData(transactionDetails,
runningBalance);
final JournalEntryData glJournalEntryData = this.journalEntryReadPlatformService.retrieveGLJournalEntryById(journalEntryId,
@@ -260,7 +260,7 @@ public class JournalEntriesApiResource {
public String retrieveOpeningBalance(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId,
@QueryParam("currencyCode") final String currencyCode) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
final OfficeOpeningBalancesData officeOpeningBalancesData = this.journalEntryReadPlatformService
.retrieveOfficeOpeningBalances(officeId, currencyCode);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
@@ -724,10 +724,6 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
AccrualAccountsForLoan.GOODWILL_CREDIT.getValue(), accountMapForCredit, accountMapForDebit);
} else if (loanTransactionDTO.getTransactionType().isRepayment()) {
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
AccrualAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
} else {
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
AccrualAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
@@ -701,10 +701,6 @@ public class CashBasedAccountingProcessorForLoan implements AccountingProcessorF
} else if (loanTransactionDTO.getTransactionType().isGoodwillCredit()) {
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
CashAccountsForLoan.GOODWILL_CREDIT.getValue(), accountMapForCredit, accountMapForDebit);
} else if (loanTransactionDTO.getTransactionType().isRepayment()) {
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
} else {
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, CashAccountsForLoan.OVERPAYMENT.getValue(),
CashAccountsForLoan.FUND_SOURCE.getValue(), accountMapForCredit, accountMapForDebit);
@@ -27,7 +27,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -401,50 +400,46 @@ public class JournalEntryWritePlatformServiceJpaRepositoryImpl implements Journa
}
}
Set<OfficeCurrencyKey> officeSet = officeMap.keySet();
Map<GLAccount, BigDecimal> liabilityMap = new HashMap<>();
Map<GLAccount, BigDecimal> expenseMap = new HashMap<>();
for (OfficeCurrencyKey key : officeSet) {
for (Map.Entry<OfficeCurrencyKey, List<LoanProductProvisioningEntry>> entry : officeMap.entrySet()) {
liabilityMap.clear();
expenseMap.clear();
List<LoanProductProvisioningEntry> entries = officeMap.get(key);
for (LoanProductProvisioningEntry entry : entries) {
if (liabilityMap.containsKey(entry.getLiabilityAccount())) {
BigDecimal amount = liabilityMap.get(entry.getLiabilityAccount());
amount = amount.add(entry.getReservedAmount());
liabilityMap.put(entry.getLiabilityAccount(), amount);
for (LoanProductProvisioningEntry lppEntry : entry.getValue()) {
if (liabilityMap.containsKey(lppEntry.getLiabilityAccount())) {
BigDecimal amount = liabilityMap.get(lppEntry.getLiabilityAccount());
amount = amount.add(lppEntry.getReservedAmount());
liabilityMap.put(lppEntry.getLiabilityAccount(), amount);
} else {
BigDecimal amount = BigDecimal.ZERO.add(entry.getReservedAmount());
liabilityMap.put(entry.getLiabilityAccount(), amount);
BigDecimal amount = BigDecimal.ZERO.add(lppEntry.getReservedAmount());
liabilityMap.put(lppEntry.getLiabilityAccount(), amount);
}
if (expenseMap.containsKey(entry.getExpenseAccount())) {
BigDecimal amount = expenseMap.get(entry.getExpenseAccount());
amount = amount.add(entry.getReservedAmount());
expenseMap.put(entry.getExpenseAccount(), amount);
if (expenseMap.containsKey(lppEntry.getExpenseAccount())) {
BigDecimal amount = expenseMap.get(lppEntry.getExpenseAccount());
amount = amount.add(lppEntry.getReservedAmount());
expenseMap.put(lppEntry.getExpenseAccount(), amount);
} else {
BigDecimal amount = BigDecimal.ZERO.add(entry.getReservedAmount());
expenseMap.put(entry.getExpenseAccount(), amount);
BigDecimal amount = BigDecimal.ZERO.add(lppEntry.getReservedAmount());
expenseMap.put(lppEntry.getExpenseAccount(), amount);
}
}
createJournalEntry(provisioningEntry.getCreatedDate(), provisioningEntry.getId(), key.office, key.currency, liabilityMap,
expenseMap);
createJournalEntry(provisioningEntry.getCreatedDate(), provisioningEntry.getId(), entry.getKey().office,
entry.getKey().currency, liabilityMap, expenseMap);
}
return "P" + provisioningEntry.getId();
}
private void createJournalEntry(LocalDate transactionDate, Long entryId, Office office, String currencyCode,
Map<GLAccount, BigDecimal> liabilityMap, Map<GLAccount, BigDecimal> expenseMap) {
Set<GLAccount> liabilityAccounts = liabilityMap.keySet();
for (GLAccount account : liabilityAccounts) {
this.helper.createProvisioningCreditJournalEntry(transactionDate, entryId, office, currencyCode, account,
liabilityMap.get(account));
for (Map.Entry<GLAccount, BigDecimal> entry : liabilityMap.entrySet()) {
this.helper.createProvisioningCreditJournalEntry(transactionDate, entryId, office, currencyCode, entry.getKey(),
entry.getValue());
}
Set<GLAccount> expenseAccounts = expenseMap.keySet();
for (GLAccount account : expenseAccounts) {
this.helper.createProvisioningDebitJournalEntry(transactionDate, entryId, office, currencyCode, account,
expenseMap.get(account));
for (Map.Entry<GLAccount, BigDecimal> entry : expenseMap.entrySet()) {
this.helper.createProvisioningDebitJournalEntry(transactionDate, entryId, office, currencyCode, entry.getKey(),
entry.getValue());
}
}
@@ -86,7 +86,7 @@ public class AccountingRuleApiResource {
"allowedCreditTagOptions", "allowedDebitTagOptions", "debitTags", "creditTags", "creditAccounts", "debitAccounts",
"allowMultipleCreditEntries", "allowMultipleDebitEntries", "tag"));
private final String resourceNameForPermission = "ACCOUNTINGRULE";
private static final String RESOURCE_NAME_FOR_PERMISSION = "ACCOUNTINGRULE";
private final AccountingRuleReadPlatformService accountingRuleReadPlatformService;
private final GLAccountReadPlatformService accountReadPlatformService;
@@ -107,7 +107,7 @@ public class AccountingRuleApiResource {
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = AccountingRuleApiResourceSwagger.GetAccountRulesTemplateResponse.class))) })
public String retrieveTemplate(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
AccountingRuleData accountingRuleData = null;
accountingRuleData = handleTemplate(accountingRuleData);
@@ -126,7 +126,7 @@ public class AccountingRuleApiResource {
public String retrieveAllAccountingRules(@Context final UriInfo uriInfo) {
final AppUser currentUser = this.context.authenticatedUser();
currentUser.validateHasReadPermission(this.resourceNameForPermission);
currentUser.validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
final String hierarchy = currentUser.getOffice().getHierarchy();
final String hierarchySearchString = hierarchy + "%";
@@ -159,7 +159,7 @@ public class AccountingRuleApiResource {
@PathParam("accountingRuleId") @Parameter(description = "accountingRuleId") final Long accountingRuleId,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermission);
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSION);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
AccountingRuleData accountingRuleData = this.accountingRuleReadPlatformService.retrieveAccountingRuleById(accountingRuleId);
@@ -23,6 +23,7 @@ import static org.apache.fineract.batch.command.CommandStrategyUtils.relativeUrl
import jakarta.ws.rs.core.UriInfo;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.batch.command.CommandStrategy;
import org.apache.fineract.batch.command.CommandStrategyUtils;
@@ -39,6 +40,7 @@ import org.springframework.stereotype.Component;
* raised by {@link DatatablesApiResource} and map those errors to appropriate status codes in BatchResponse.
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class GetDatatableEntryByQueryCommandStrategy implements CommandStrategy {
@@ -81,6 +83,7 @@ public class GetDatatableEntryByQueryCommandStrategy implements CommandStrategy
case "columnFilter" -> columnFilter = entry.getValue();
case "valueFilter" -> valueFilter = entry.getValue();
case "resultColumns" -> resultColumns = entry.getValue();
default -> log.warn("Query parameter could not be mapped: {}", entry.getKey());
}
}
}
@@ -68,9 +68,12 @@ public abstract class AbstractLoanItemListener {
@OnReadError
public void onReadError(Exception e) {
LoanReadException ee = (LoanReadException) e;
log.warn("Error was triggered during reading of Loan (id={}) due to: {}", ee.getId(), ThrowableSerialization.serialize(e));
updateAccountLockWithError(List.of(ee.getId()), "Loan (id: %d) reading is failed", e);
if (e instanceof LoanReadException ee) {
log.warn("Error was triggered during reading of Loan (id={}) due to: {}", ee.getId(), ThrowableSerialization.serialize(e));
updateAccountLockWithError(List.of(ee.getId()), "Loan (id: %d) reading is failed", e);
} else {
log.error("Could not handle read error", e);
}
}
@OnProcessError
@@ -18,7 +18,6 @@
*/
package org.apache.fineract.cob.service;
import com.google.gson.Gson;
import java.time.LocalDate;
import java.util.List;
import lombok.RequiredArgsConstructor;
@@ -30,11 +29,8 @@ import org.apache.fineract.cob.loan.LoanCOBConstant;
import org.apache.fineract.cob.loan.RetrieveLoanIdService;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.domain.FineractContext;
import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.infrastructure.jobs.domain.CustomJobParameterRepository;
import org.apache.fineract.infrastructure.jobs.domain.JobExecutionRepository;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Service;
@@ -45,12 +41,8 @@ public class LoanCOBCatchUpServiceImpl implements LoanCOBCatchUpService {
private final AsyncLoanCOBExecutorService asyncLoanCOBExecutorService;
private final JobExecutionRepository jobExecutionRepository;
private final JobExplorer jobExplorer;
private final RetrieveLoanIdService retrieveLoanIdService;
private final LoanAccountLockService accountLockService;
private final CustomJobParameterRepository customJobParameterRepository;
protected Gson gson = GoogleGsonSerializerHelper.createSimpleGson();
@Override
public void unlockHardLockedLoans() {
@@ -105,7 +105,7 @@ public class AuditsApiResource {
@QueryParam("orderBy") @Parameter(description = "orderBy") final String orderBy,
@QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder) {
this.context.authenticatedUser().validateHasReadPermission(this.RESOURCE_NAME_FOR_PERMISSIONS);
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
final PaginationParameters parameters = PaginationParameters.instance(paged, offset, limit, orderBy, sortOrder);
final SQLBuilder extraCriteria = getExtraCriteria(actionName, entityName, resourceId, makerId, makerDateTimeFrom, makerDateTimeTo,
checkerId, checkerDateTimeFrom, checkerDateTimeTo, processingResult, officeId, groupId, clientId, loanId, savingsAccountId);
@@ -135,7 +135,7 @@ public class AuditsApiResource {
public String retrieveAuditEntry(@PathParam("auditId") @Parameter(description = "auditId") final Long auditId,
@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(this.RESOURCE_NAME_FOR_PERMISSIONS);
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
final AuditData auditEntry = this.auditReadPlatformService.retrieveAuditEntry(auditId);
@@ -153,7 +153,7 @@ public class AuditsApiResource {
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = MakercheckersApiResourceSwagger.GetMakerCheckersSearchTemplateResponse.class))) })
public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(this.RESOURCE_NAME_FOR_PERMISSIONS);
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
@@ -21,6 +21,8 @@ package org.apache.fineract.infrastructure.bulkimport.importhandler;
import com.google.common.base.Splitter;
import java.time.LocalDate;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
@@ -40,6 +42,7 @@ import org.apache.poi.ss.usermodel.SheetVisibility;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellReference;
@Slf4j
public final class ImportHandlerUtils {
private ImportHandlerUtils() {
@@ -73,20 +76,20 @@ public final class ImportHandlerUtils {
FormulaEvaluator eval = row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
if (c.getCellType() == CellType.FORMULA) {
if (eval != null) {
CellValue val = null;
CellValue value;
try {
val = eval.evaluate(c);
} catch (NullPointerException npe) {
return null;
value = eval.evaluate(c);
return ((Double) value.getNumberValue()).longValue();
} catch (Exception e) {
log.error("Cell evaluation error: ", e);
}
return ((Double) val.getNumberValue()).longValue();
}
return null;
} else if (c.getCellType() == CellType.NUMERIC) {
return ((Double) c.getNumericCellValue()).longValue();
} else {
return Long.parseLong(row.getCell(colIndex).getStringCellValue());
}
return null;
}
public static String readAsString(int colIndex, Row row) {
@@ -98,26 +101,20 @@ public final class ImportHandlerUtils {
FormulaEvaluator eval = row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
if (c.getCellType() == CellType.FORMULA) {
if (eval != null) {
CellValue val = null;
CellValue value;
try {
val = eval.evaluate(c);
} catch (NullPointerException npe) {
return null;
}
value = eval.evaluate(c);
String res = trimEmptyDecimalPortion(val.getStringValue());
if (res != null) {
if (!res.equals("")) {
String res = trimEmptyDecimalPortion(value.getStringValue());
if (!StringUtils.isNotEmpty(res)) {
return res.trim();
} else {
return null;
}
} else {
return null;
} catch (Exception e) {
log.error("Cell evaluation error: ", e);
}
} else {
return null;
}
return null;
} else if (c.getCellType() == CellType.STRING) {
String res = trimEmptyDecimalPortion(c.getStringCellValue().trim());
return res.trim();
@@ -156,13 +153,13 @@ public final class ImportHandlerUtils {
FormulaEvaluator eval = row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
if (c.getCellType() == CellType.FORMULA) {
if (eval != null) {
CellValue val = null;
CellValue value;
try {
val = eval.evaluate(c);
} catch (NullPointerException npe) {
return false;
value = eval.evaluate(c);
return value.getBooleanValue();
} catch (Exception e) {
log.error("Cell evaluation error: ", e);
}
return val.getBooleanValue();
}
return false;
} else if (c.getCellType() == CellType.BOOLEAN) {
@@ -185,13 +182,13 @@ public final class ImportHandlerUtils {
FormulaEvaluator eval = row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
if (c.getCellType() == CellType.FORMULA) {
if (eval != null) {
CellValue val = null;
CellValue value;
try {
val = eval.evaluate(c);
} catch (NullPointerException npe) {
return null;
value = eval.evaluate(c);
return ((Double) value.getNumberValue()).intValue();
} catch (Exception e) {
log.error("Cell evaluation error: ", e);
}
return ((Double) val.getNumberValue()).intValue();
}
return null;
} else if (c.getCellType() == CellType.NUMERIC) {
@@ -209,16 +206,15 @@ public final class ImportHandlerUtils {
FormulaEvaluator eval = row.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
if (c.getCellType() == CellType.FORMULA) {
if (eval != null) {
CellValue val = null;
CellValue value;
try {
val = eval.evaluate(c);
} catch (NullPointerException npe) {
return 0.0;
value = eval.evaluate(c);
return value.getNumberValue();
} catch (Exception e) {
log.error("Cell evaluation error: ", e);
}
return val.getNumberValue();
} else {
return 0.0;
}
return 0.0;
} else if (c.getCellType() == CellType.NUMERIC) {
return row.getCell(colIndex).getNumericCellValue();
} else {
@@ -58,7 +58,7 @@ public class CenterSheetPopulator extends AbstractWorkbookPopulator {
}
private void centerNameToCenterIdMap() {
centerNameToCenterId = new HashMap<String, Long>();
centerNameToCenterId = new HashMap<>();
for (CenterData centerData : allCenters) {
centerNameToCenterId.put(centerData.getName(), centerData.getId());
}
@@ -68,12 +68,12 @@ public class CenterSheetPopulator extends AbstractWorkbookPopulator {
int rowIndex = 1;
int officeIndex = 0;
int startIndex = 1;
officeNameToBeginEndIndexesOfCenters = new HashMap<Integer, Integer[]>();
officeNameToBeginEndIndexesOfCenters = new HashMap<>();
Row row = centerSheet.createRow(rowIndex);
for (OfficeData office : offices) {
startIndex = rowIndex + 1;
writeString(OFFICE_NAME_COL, row, office.getName());
ArrayList<String> centersList = new ArrayList<String>();
ArrayList<String> centersList;
if (officeToCenters.containsKey(office.getName().trim().replaceAll("[ )(]", "_"))) {
centersList = officeToCenters.get(office.getName().trim().replaceAll("[ )(]", "_"));
@@ -19,9 +19,7 @@
package org.apache.fineract.infrastructure.bulkimport.populator;
import java.util.List;
import java.util.Map;
import org.apache.fineract.infrastructure.bulkimport.constants.TemplatePopulateImportConstants;
import org.apache.fineract.portfolio.client.data.ClientData;
import org.apache.fineract.portfolio.savings.data.SavingsAccountData;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
@@ -30,8 +28,6 @@ import org.apache.poi.ss.usermodel.Workbook;
public class SavingsAccountSheetPopulator extends AbstractWorkbookPopulator {
private List<SavingsAccountData> savingsAccountDataList;
private Map<ClientData, List<SavingsAccountData>> clientToSavingsMap;
private static final int SAVINGS_ACCOUNT_ID_COL = 0;
private static final int SAVING_ACCOUNT_NO = 1;
private static final int CURRENCY_COL = 2;
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.infrastructure.bulkimport.populator.comparator;
import java.io.Serializable;
import java.util.Comparator;
import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
@@ -25,7 +26,7 @@ import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
* Sorting the loan values based on loan status giving priority to active loans
*/
public class LoanComparatorByStatusActive implements Comparator<LoanAccountData> {
public class LoanComparatorByStatusActive implements Comparator<LoanAccountData>, Serializable {
@Override
public int compare(LoanAccountData o1, LoanAccountData o2) {
@@ -41,19 +41,20 @@ public enum CampaignType {
}
public static CampaignType fromInt(final Integer typeValue) {
CampaignType type = null;
if (typeValue == null) {
return INVALID;
}
switch (typeValue) {
case 0:
type = INVALID;
break;
return INVALID;
case 1:
type = SMS;
break;
return SMS;
case 2:
type = NOTIFICATION;
break;
return NOTIFICATION;
default:
return INVALID;
}
return type;
}
public static EnumOptionData campaignType(final Integer campaignTypeId) {
@@ -61,28 +62,22 @@ public enum CampaignType {
}
public static EnumOptionData campaignType(final CampaignType campaignType) {
EnumOptionData optionData = new EnumOptionData(CampaignType.INVALID.getValue().longValue(), CampaignType.INVALID.getCode(),
"Invalid");
EnumOptionData optionData = new EnumOptionData(INVALID.getValue().longValue(), INVALID.getCode(), "Invalid");
switch (campaignType) {
case INVALID:
optionData = new EnumOptionData(CampaignType.INVALID.getValue().longValue(), CampaignType.INVALID.getCode(), "Invalid");
optionData = new EnumOptionData(INVALID.getValue().longValue(), INVALID.getCode(), "Invalid");
break;
case SMS:
optionData = new EnumOptionData(CampaignType.SMS.getValue().longValue(), CampaignType.SMS.getCode(), "SMS");
optionData = new EnumOptionData(SMS.getValue().longValue(), SMS.getCode(), "SMS");
break;
case NOTIFICATION:
optionData = new EnumOptionData(CampaignType.NOTIFICATION.getValue().longValue(), CampaignType.NOTIFICATION.getCode(),
"NOTIFICATION");
optionData = new EnumOptionData(NOTIFICATION.getValue().longValue(), NOTIFICATION.getCode(), "NOTIFICATION");
break;
}
return optionData;
}
public boolean isSms() {
return this.value.equals(CampaignType.SMS.getValue());
}
public boolean isNotificaion() {
return this.value.equals(CampaignType.NOTIFICATION.getValue());
return this.equals(SMS);
}
}
@@ -30,7 +30,6 @@ import java.util.Map;
import org.apache.fineract.infrastructure.campaigns.email.data.EmailBusinessRulesData;
import org.apache.fineract.infrastructure.campaigns.email.data.EmailCampaignData;
import org.apache.fineract.infrastructure.campaigns.email.data.EmailCampaignTimeLine;
import org.apache.fineract.infrastructure.campaigns.email.data.ScheduledEmailEnumerations;
import org.apache.fineract.infrastructure.campaigns.email.domain.EmailCampaignStatus;
import org.apache.fineract.infrastructure.campaigns.email.domain.EmailCampaignStatusEnumerations;
import org.apache.fineract.infrastructure.campaigns.email.domain.EmailCampaignType;
@@ -116,24 +115,7 @@ public class EmailCampaignReadPlatformServiceImpl implements EmailCampaignReadPl
final String emailMessage = rs.getString("emailMessage");
final String emailAttachmentFileFormatString = rs.getString("emailAttachmentFileFormat");
final String stretchyReportParamMap = rs.getString("stretchyReportParamMap");
EnumOptionData emailAttachmentFileFormat = null;
if (emailAttachmentFileFormatString != null) {
emailAttachmentFileFormat = ScheduledEmailEnumerations.emailAttachementFileFormat(emailAttachmentFileFormatString);
}
final Long reportId = JdbcSupport.getLong(rs, "stretchyReportId");
final String reportName = rs.getString("reportName");
final String reportType = rs.getString("reportType");
final String reportSubType = rs.getString("reportSubType");
final String reportCategory = rs.getString("reportCategory");
final String reportSql = rs.getString("reportSql");
final String reportDescription = rs.getString("reportDescription");
final boolean coreReport = rs.getBoolean("coreReport");
final boolean useReport = rs.getBoolean("useReport");
/*
* final ReportData stretchyReport = new ReportData(reportId, reportName, reportType, reportSubType,
* reportCategory, reportDescription, reportSql, coreReport, useReport, null);
*/
final Integer statusId = JdbcSupport.getInteger(rs, "statusEnum");
final EnumOptionData status = EmailCampaignStatusEnumerations.status(statusId);
@@ -350,11 +350,11 @@ public class EmailCampaignWritePlatformCommandHandlerImpl implements EmailCampai
throws IOException {
final String reportType = "report";
List<HashMap<String, Object>> resultList = new ArrayList<HashMap<String, Object>>();
List<HashMap<String, Object>> resultList;
final GenericResultsetData results = this.readReportingService.retrieveGenericResultSetForSmsEmailCampaign(reportName, reportType,
queryParams);
final String response = this.genericDataService.generateJsonFromGenericResultsetData(results);
resultList = new ObjectMapper().readValue(response, new TypeReference<List<HashMap<String, Object>>>() {});
resultList = new ObjectMapper().readValue(response, new TypeReference<>() {});
// loop changes array date to string date
for (Iterator<HashMap<String, Object>> it = resultList.iterator(); it.hasNext();) {
HashMap<String, Object> entry = it.next();
@@ -30,7 +30,6 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.useradministration.domain.AppUser;
import org.springframework.stereotype.Service;
@Service
@@ -43,8 +42,9 @@ public class EmailConfigurationWritePlatformServiceImpl implements EmailConfigur
@Override
public CommandProcessingResult update(final JsonCommand command) {
final AppUser currentUser = this.context.authenticatedUser();
// TODO: leaving function call for backward compatibility... but security configuration should be done somewhere
// else
this.context.authenticatedUser();
this.emailConfigurationValidator.validateUpdateConfiguration(command.json());
final String smtpUsername = command.stringValueOfParameterNamed("SMTP_USERNAME");
@@ -193,6 +193,8 @@ public class ExecuteEmailTasklet implements Tasklet {
case "environementUrl":
actualParams.put(entry.getKey(), entry.getKey());
break;
default:
log.warn("Query parameter could not be mapped: {}", entry.getKey());
}
}
return actualParams;
@@ -34,20 +34,16 @@ public enum SmsCampaignStatus {
}
public static SmsCampaignStatus fromInt(final Integer statusValue) {
SmsCampaignStatus enumeration = SmsCampaignStatus.INVALID;
switch (statusValue) {
case 100:
enumeration = SmsCampaignStatus.PENDING;
break;
return PENDING;
case 300:
enumeration = SmsCampaignStatus.ACTIVE;
break;
return ACTIVE;
case 600:
enumeration = SmsCampaignStatus.CLOSED;
break;
return CLOSED;
default:
return INVALID;
}
return enumeration;
}
public Integer getValue() {
@@ -58,15 +54,18 @@ public enum SmsCampaignStatus {
return code;
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isActive() {
return this.value.equals(SmsCampaignStatus.ACTIVE.getValue());
return this.equals(ACTIVE);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isPending() {
return this.value.equals(SmsCampaignStatus.PENDING.getValue());
return this.equals(PENDING);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isClosed() {
return this.value.equals(SmsCampaignStatus.CLOSED.getValue());
return this.equals(CLOSED);
}
}
@@ -41,20 +41,21 @@ public enum SmsCampaignTriggerType {
return code;
}
public static SmsCampaignTriggerType fromInt(final Integer typeValue) {
SmsCampaignTriggerType type = null;
switch (typeValue) {
public static SmsCampaignTriggerType fromInt(final Integer v) {
if (v == null) {
return INVALID;
}
switch (v) {
case 1:
type = DIRECT;
break;
return DIRECT;
case 2:
type = SCHEDULE;
break;
return SCHEDULE;
case 3:
type = TRIGGERED;
break;
return TRIGGERED;
default:
return INVALID;
}
return type;
}
public static EnumOptionData triggerType(final Integer triggerTypeId) {
@@ -62,38 +63,32 @@ public enum SmsCampaignTriggerType {
}
public static EnumOptionData triggerType(final SmsCampaignTriggerType triggerType) {
EnumOptionData optionData = new EnumOptionData(SmsCampaignTriggerType.INVALID.getValue().longValue(),
SmsCampaignTriggerType.INVALID.getCode(), "Invalid");
switch (triggerType) {
case INVALID:
optionData = new EnumOptionData(SmsCampaignTriggerType.INVALID.getValue().longValue(),
SmsCampaignTriggerType.INVALID.getCode(), "Invalid");
break;
return new EnumOptionData(INVALID.getValue().longValue(), INVALID.getCode(), "Invalid");
case DIRECT:
optionData = new EnumOptionData(SmsCampaignTriggerType.DIRECT.getValue().longValue(),
SmsCampaignTriggerType.DIRECT.getCode(), "Direct");
break;
return new EnumOptionData(DIRECT.getValue().longValue(), DIRECT.getCode(), "Direct");
case SCHEDULE:
optionData = new EnumOptionData(SmsCampaignTriggerType.SCHEDULE.getValue().longValue(),
SmsCampaignTriggerType.SCHEDULE.getCode(), "Schedule");
break;
return new EnumOptionData(SCHEDULE.getValue().longValue(), SCHEDULE.getCode(), "Schedule");
case TRIGGERED:
optionData = new EnumOptionData(SmsCampaignTriggerType.TRIGGERED.getValue().longValue(),
SmsCampaignTriggerType.TRIGGERED.getCode(), "Triggered");
break;
return new EnumOptionData(TRIGGERED.getValue().longValue(), TRIGGERED.getCode(), "Triggered");
default:
return new EnumOptionData(INVALID.getValue().longValue(), INVALID.getCode(), "Invalid");
}
return optionData;
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isDirect() {
return this.value.equals(SmsCampaignTriggerType.DIRECT.getValue());
return this.equals(DIRECT);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isSchedule() {
return this.value.equals(SmsCampaignTriggerType.SCHEDULE.getValue());
return this.equals(SCHEDULE);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isTriggered() {
return this.value.equals(SmsCampaignTriggerType.TRIGGERED.getValue());
return this.equals(TRIGGERED);
}
}
@@ -183,18 +183,18 @@ public class SmsCampaignDomainServiceImpl implements SmsCampaignDomainService {
});
if (groupClients.size() > 0) {
if (!groupClients.isEmpty()) {
for (Client client : groupClients) {
HashMap<String, Object> smsParams = processRepaymentDataForSms(loanTransaction, client);
for (String key : campaignParams.keySet()) {
String value = campaignParams.get(key);
for (Map.Entry<String, String> entry : campaignParams.entrySet()) {
String value = entry.getValue();
String spvalue = null;
boolean spkeycheck = smsParams.containsKey(key);
boolean spkeycheck = smsParams.containsKey(entry.getKey());
if (spkeycheck) {
spvalue = smsParams.get(key).toString();
spvalue = smsParams.get(entry.getKey()).toString();
}
if (spkeycheck && !(value.equals("-1") || spvalue.equals(value))) {
if (key.equals("officeId")) {
if (entry.getKey().equals("officeId")) {
Long officeId = Long.valueOf(value);
Office campaignOffice = this.officeRepository.findById(Long.valueOf(value))
.orElseThrow(() -> new OfficeNotFoundException(officeId));
@@ -244,15 +244,15 @@ public class SmsCampaignDomainServiceImpl implements SmsCampaignDomainService {
});
HashMap<String, Object> smsParams = processSavingsTransactionDataForSms(savingsTransaction, client);
for (String key : campaignParams.keySet()) {
String value = campaignParams.get(key);
for (Map.Entry<String, String> entry : campaignParams.entrySet()) {
String value = entry.getValue();
String spvalue = null;
boolean spkeycheck = smsParams.containsKey(key);
boolean spkeycheck = smsParams.containsKey(entry.getKey());
if (spkeycheck) {
spvalue = smsParams.get(key).toString();
spvalue = smsParams.get(entry.getKey()).toString();
}
if (spkeycheck && !(value.equals("-1") || spvalue.equals(value))) {
if (key.equals("officeId")) {
if (entry.getKey().equals("officeId")) {
Long officeId = Long.valueOf(value);
Office campaignOffice = this.officeRepository.findById(officeId)
.orElseThrow(() -> new OfficeNotFoundException(officeId));
@@ -19,7 +19,6 @@
package org.apache.fineract.infrastructure.campaigns.sms.service;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -72,7 +71,7 @@ public class SmsCampaignDropdownReadPlatformServiceImpl implements SmsCampaignDr
@Override
public Collection<SmsProviderData> retrieveSmsProviders() {
Collection<SmsProviderData> smsProviderOptions = new ArrayList<>();
Collection<SmsProviderData> smsProviderOptions;
Map<String, Object> hostConfig = this.smsConfigUtils.getMessageGateWayRequestURI("smsbridges", null);
URI uri = (URI) hostConfig.get("uri");
HttpEntity<?> entity = (HttpEntity<?>) hostConfig.get("entity");
@@ -80,8 +79,7 @@ public class SmsCampaignDropdownReadPlatformServiceImpl implements SmsCampaignDr
ResponseEntity<Collection<SmsProviderData>> responseOne = null;
try {
responseOne = restTemplate.exchange(uri, HttpMethod.GET, entity,
new ParameterizedTypeReference<Collection<SmsProviderData>>() {});
responseOne = restTemplate.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference<>() {});
} catch (ResourceAccessException ex) {
LOG.debug("Mobile service provider {} not available", uri, ex);
}
@@ -0,0 +1,71 @@
/**
* 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.config;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Slf4j
@RequiredArgsConstructor
@Configuration
public class OkHttp3Config {
private final FineractProperties fineractProperties;
@Bean
public OkHttpClient okHttpClient() throws Exception {
var okBuilder = new OkHttpClient.Builder();
if (Boolean.TRUE.equals(fineractProperties.getInsecureHttpClient())) {
final X509TrustManager insecureX509TrustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}// NOSONAR
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}// NOSONAR
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
};
SSLContext insecureSSLContext = SSLContext.getInstance("TLS");
insecureSSLContext.init(null, new TrustManager[] { insecureX509TrustManager }, new SecureRandom());
okBuilder.sslSocketFactory(insecureSSLContext.getSocketFactory(), insecureX509TrustManager);
HostnameVerifier insecureHostnameVerifier = (hostname, session) -> true;// NOSONAR
okBuilder.hostnameVerifier(insecureHostnameVerifier);
}
return okBuilder.build();
}
}
@@ -61,25 +61,53 @@ public class CacheConfig {
CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, ResourcePoolsBuilder.heap(10000))
.withExpiry(ExpiryPolicyBuilder.noExpiration()).build());
cacheManager.createCache("users", defaultTemplate);
cacheManager.createCache("usersByUsername", defaultTemplate);
cacheManager.createCache("tenantsById", defaultTemplate);
cacheManager.createCache("offices", defaultTemplate);
cacheManager.createCache("officesForDropdown", defaultTemplate);
cacheManager.createCache("officesById", defaultTemplate);
cacheManager.createCache("charges", defaultTemplate);
cacheManager.createCache("funds", defaultTemplate);
cacheManager.createCache("code_values", defaultTemplate);
cacheManager.createCache("codes", defaultTemplate);
cacheManager.createCache("hooks", defaultTemplate);
cacheManager.createCache("tfConfig", defaultTemplate);
cacheManager.createCache(CONFIG_BY_NAME_CACHE_NAME, defaultTemplate);
if (cacheManager.getCache("users") == null) {
cacheManager.createCache("users", defaultTemplate);
}
if (cacheManager.getCache("usersByUsername") == null) {
cacheManager.createCache("usersByUsername", defaultTemplate);
}
if (cacheManager.getCache("tenantsById") == null) {
cacheManager.createCache("tenantsById", defaultTemplate);
}
if (cacheManager.getCache("offices") == null) {
cacheManager.createCache("offices", defaultTemplate);
}
if (cacheManager.getCache("officesForDropdown") == null) {
cacheManager.createCache("officesForDropdown", defaultTemplate);
}
if (cacheManager.getCache("officesById") == null) {
cacheManager.createCache("officesById", defaultTemplate);
}
if (cacheManager.getCache("charges") == null) {
cacheManager.createCache("charges", defaultTemplate);
}
if (cacheManager.getCache("funds") == null) {
cacheManager.createCache("funds", defaultTemplate);
}
if (cacheManager.getCache("code_values") == null) {
cacheManager.createCache("code_values", defaultTemplate);
}
if (cacheManager.getCache("codes") == null) {
cacheManager.createCache("codes", defaultTemplate);
}
if (cacheManager.getCache("hooks") == null) {
cacheManager.createCache("hooks", defaultTemplate);
}
if (cacheManager.getCache("tfConfig") == null) {
cacheManager.createCache("tfConfig", defaultTemplate);
}
if (cacheManager.getCache(CONFIG_BY_NAME_CACHE_NAME) == null) {
cacheManager.createCache(CONFIG_BY_NAME_CACHE_NAME, defaultTemplate);
}
javax.cache.configuration.Configuration<Object, Object> accessTokenTemplate = Eh107Configuration.fromEhcacheCacheConfiguration(
CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, ResourcePoolsBuilder.heap(10000))
.withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofHours(2))).build());
cacheManager.createCache("userTFAccessToken", accessTokenTemplate);
if (cacheManager.getCache("userTFAccessToken") == null) {
cacheManager.createCache("userTFAccessToken", accessTokenTemplate);
}
return cacheManager;
}
@@ -21,6 +21,8 @@ package org.apache.fineract.infrastructure.core.service.migration;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import liquibase.change.custom.CustomTaskChange;
import liquibase.database.Database;
import liquibase.database.jvm.JdbcConnection;
@@ -42,6 +44,9 @@ public class TenantPasswordEncryptionTask implements CustomTaskChange, Applicati
private static DatabasePasswordEncryptor databasePasswordEncryptor;
// NOTE: workaround for double execution bug; see: https://github.com/liquibase/liquibase/issues/3945
private Map<String, Boolean> done = new ConcurrentHashMap<>();
@Override
public void execute(Database database) throws CustomChangeException {
JdbcConnection dbConn = (JdbcConnection) database.getConnection(); // autocommit is false
@@ -50,16 +55,18 @@ public class TenantPasswordEncryptionTask implements CustomTaskChange, Applicati
try (ResultSet rs = selectStatement.executeQuery("SELECT id, schema_password FROM tenant_server_connections")) {
while (rs.next()) {
String id = rs.getString("id");
String schemaPassword = rs.getString("schema_password");
String encryptedPassword = TenantPasswordEncryptionTask.databasePasswordEncryptor.encrypt(schemaPassword);
if (!Boolean.TRUE.equals(done.get(id))) {
String schemaPassword = rs.getString("schema_password");
String encryptedPassword = TenantPasswordEncryptionTask.databasePasswordEncryptor.encrypt(schemaPassword);
String updateSql = String.format(
"update tenant_server_connections set schema_password = '%s', master_password_hash = '%s' where id = %s",
encryptedPassword, TenantPasswordEncryptionTask.databasePasswordEncryptor.getMasterPasswordHash(), id);
updateStatement.execute(updateSql);
String updateSql = String.format(
"update tenant_server_connections set schema_password = '%s', master_password_hash = '%s' where id = %s",
encryptedPassword, TenantPasswordEncryptionTask.databasePasswordEncryptor.getMasterPasswordHash(), id);
updateStatement.execute(updateSql);
done.put(id, true);
}
}
}
} catch (Exception e) {
throw new CustomChangeException(e);
}
@@ -21,6 +21,8 @@ package org.apache.fineract.infrastructure.core.service.migration;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import liquibase.change.custom.CustomTaskChange;
import liquibase.database.Database;
import liquibase.database.jvm.JdbcConnection;
@@ -42,6 +44,9 @@ public class TenantReadOnlyPasswordEncryptionTask implements CustomTaskChange, A
private static DatabasePasswordEncryptor databasePasswordEncryptor;
// NOTE: workaround for double execution bug; see: https://github.com/liquibase/liquibase/issues/3945
private Map<String, Boolean> done = new ConcurrentHashMap<>();
@Override
public void execute(Database database) throws CustomChangeException {
JdbcConnection dbConn = (JdbcConnection) database.getConnection(); // autocommit is false
@@ -51,17 +56,20 @@ public class TenantReadOnlyPasswordEncryptionTask implements CustomTaskChange, A
"SELECT id, readonly_schema_password FROM tenant_server_connections WHERE readonly_schema_password IS NOT NULL")) {
while (rs.next()) {
String id = rs.getString("id");
String readOnlySchemaPassword = rs.getString("readonly_schema_password");
String encryptedPassword = TenantReadOnlyPasswordEncryptionTask.databasePasswordEncryptor
.encrypt(readOnlySchemaPassword);
if (!Boolean.TRUE.equals(done.get(id))) {
String readOnlySchemaPassword = rs.getString("readonly_schema_password");
String encryptedPassword = TenantReadOnlyPasswordEncryptionTask.databasePasswordEncryptor
.encrypt(readOnlySchemaPassword);
String updateSql = String.format(
"update tenant_server_connections set readonly_schema_password = '%s', master_password_hash = '%s' where id = %s",
encryptedPassword, TenantReadOnlyPasswordEncryptionTask.databasePasswordEncryptor.getMasterPasswordHash(), id);
updateStatement.execute(updateSql);
String updateSql = String.format(
"update tenant_server_connections set readonly_schema_password = '%s', master_password_hash = '%s' where id = %s",
encryptedPassword, TenantReadOnlyPasswordEncryptionTask.databasePasswordEncryptor.getMasterPasswordHash(),
id);
updateStatement.execute(updateSql);
done.put(id, true);
}
}
}
} catch (Exception e) {
throw new CustomChangeException(e);
}
@@ -39,6 +39,8 @@ import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
@@ -65,18 +67,14 @@ import org.apache.fineract.infrastructure.creditbureau.domain.TokenRepositoryWra
import org.apache.fineract.infrastructure.creditbureau.serialization.CreditBureauTokenCommandFromApiJsonDeserializer;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Component
@Slf4j
@RequiredArgsConstructor
@Service
public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implements ThitsaWorksCreditBureauIntegrationWritePlatformService {
private static final Logger LOG = LoggerFactory.getLogger(ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl.class);
public static final String UPLOAD_CREDIT_REPORT = "UploadCreditReport";
public static final String RESPONSE_MESSAGE = "ResponseMessage";
public static final String IS_NOT_AVAILABLE_SUFFIX = ".is.not.available";
@@ -85,29 +83,8 @@ public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implemen
private final TokenRepositoryWrapper tokenRepositoryWrapper;
private final CreditBureauConfigurationRepositoryWrapper configDataRepository;
private final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final OkHttpClient client;
@Autowired
public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final PlatformSecurityContext context,
final FromJsonHelper fromApiJsonHelper, final TokenRepositoryWrapper tokenRepositoryWrapper,
final CreditBureauConfigurationRepositoryWrapper configDataRepository,
final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
this(new OkHttpClient(), context, fromApiJsonHelper, tokenRepositoryWrapper, configDataRepository, fromApiJsonDeserializer);
}
public ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl(final OkHttpClient okHttpClient,
final PlatformSecurityContext context, final FromJsonHelper fromApiJsonHelper,
final TokenRepositoryWrapper tokenRepositoryWrapper, final CreditBureauConfigurationRepositoryWrapper configDataRepository,
final CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
this.client = okHttpClient;
this.context = context;
this.tokenRepositoryWrapper = tokenRepositoryWrapper;
this.configDataRepository = configDataRepository;
this.fromApiJsonHelper = fromApiJsonHelper;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
}
@Transactional
@Override
public String okHttpConnectionMethod(String userName, String password, String subscriptionKey, String subscriptionId, String url,
@@ -151,7 +128,7 @@ public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implemen
responseMessage = response.body().string();
} catch (IOException e) {
LOG.error("error occured in HTTP request-response method.", e);
log.error("error occured in HTTP request-response method.", e);
}
if (responseCode != HttpURLConnection.HTTP_OK) {
@@ -494,7 +471,7 @@ public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImpl implemen
"creditBureau.Configuration." + configurationParameterName + IS_NOT_AVAILABLE_SUFFIX);
}
} catch (NullPointerException ex) {
} catch (Exception ex) {
baseDataValidator.reset().failWithCode("creditBureau.configuration.is.not.available");
throw new PlatformApiDataValidationException("creditBureau.Configuration.is.not.available" + ex,
"creditBureau.Configuration.is.not.available", dataValidationErrors);
@@ -37,7 +37,6 @@ import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.csv.CSVFormat;
@@ -133,11 +132,8 @@ public class ReadReportingServiceImpl implements ReadReportingService {
String sql = getSql(name, type);
final Set<String> keys = queryParams.keySet();
for (final String key : keys) {
final String pValue = queryParams.get(key);
// LOG.info("({} : {})", key, pValue);
sql = this.genericDataService.replace(sql, key, pValue);
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
sql = this.genericDataService.replace(sql, entry.getKey(), entry.getValue());
}
final AppUser currentUser = this.context.authenticatedUser();
@@ -238,14 +234,9 @@ public class ReadReportingServiceImpl implements ReadReportingService {
row = element.getRow();
rSize = row.size();
for (int j = 0; j < rSize; j++) {
currColType = columnHeaders.get(j).getColumnType();
currVal = (String) row.get(j);
if (currVal != null) {
if (currColType.isNumericType()) {
table.addCell(currVal.toString());
} else {
table.addCell(currVal.toString());
}
table.addCell(currVal);
}
}
}
@@ -453,11 +444,8 @@ public class ReadReportingServiceImpl implements ReadReportingService {
private String sqlToRunForSmsEmailCampaign(final String name, final String type, final Map<String, String> queryParams) {
String sql = getSql(name, type);
final Set<String> keys = queryParams.keySet();
for (String key : keys) {
final String pValue = queryParams.get(key);
key = "${" + key + "}";
sql = this.genericDataService.replace(sql, key, pValue);
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
sql = this.genericDataService.replace(sql, "${" + entry.getKey() + "}", entry.getValue());
}
sql = this.genericDataService.wrapSQL(sql);
@@ -371,7 +371,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
private void registerDataTable(final String entityName, final String dataTableName, final String entitySubType, final Integer category,
final String permissionsSql) {
EntityTables entityTable = resolveEntity(entityName);
resolveEntity(entityName);
validateDatatableName(dataTableName);
validateDataTableExists(dataTableName);
@@ -1294,16 +1294,16 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
List.of(entityTable.getForeignKeyColumnNameOnDatatable(), CREATEDAT_FIELD_NAME, UPDATEDAT_FIELD_NAME));
LocalDateTime auditDateTime = DateUtils.getAuditLocalDateTime();
ArrayList<Object> params = new ArrayList<>(List.of(appTableId, auditDateTime, auditDateTime));
for (String key : dataParams.keySet()) {
if (isTechnicalParam(key)) {
for (Map.Entry<String, String> entry : dataParams.entrySet()) {
if (isTechnicalParam(entry.getKey())) {
continue;
}
ResultsetColumnHeaderData columnHeader = SearchUtil.validateToJdbcColumn(key, headersByName, false);
ResultsetColumnHeaderData columnHeader = SearchUtil.validateToJdbcColumn(entry.getKey(), headersByName, false);
if (!isUserInsertable(entityTable, columnHeader)) {
continue;
}
insertColumns.add(columnHeader.getColumnName());
params.add(SearchUtil.parseJdbcColumnValue(columnHeader, dataParams.get(key), dateFormat, dateTimeFormat, locale, false,
params.add(SearchUtil.parseJdbcColumnValue(columnHeader, entry.getValue(), dateFormat, dateTimeFormat, locale, false,
sqlGenerator));
}
if (addScore) {
@@ -1403,17 +1403,17 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
ArrayList<String> updateColumns = new ArrayList<>(List.of(UPDATEDAT_FIELD_NAME));
ArrayList<Object> params = new ArrayList<>(List.of(DateUtils.getAuditLocalDateTime()));
final HashMap<String, Object> changes = new HashMap<>();
for (String key : dataParams.keySet()) {
if (isTechnicalParam(key)) {
for (Map.Entry<String, String> entry : dataParams.entrySet()) {
if (isTechnicalParam(entry.getKey())) {
continue;
}
ResultsetColumnHeaderData columnHeader = SearchUtil.validateToJdbcColumn(key, headersByName, false);
ResultsetColumnHeaderData columnHeader = SearchUtil.validateToJdbcColumn(entry.getKey(), headersByName, false);
if (!isUserUpdatable(entityTable, columnHeader)) {
continue;
}
String columnName = columnHeader.getColumnName();
Object existingValue = valuesByHeader.get(columnHeader);
Object columnValue = SearchUtil.parseColumnValue(columnHeader, dataParams.get(key), dateFormat, dateTimeFormat, locale, false,
Object columnValue = SearchUtil.parseColumnValue(columnHeader, entry.getValue(), dateFormat, dateTimeFormat, locale, false,
sqlGenerator);
if ((columnHeader.getColumnType().isDecimalType() && MathUtil.isEqualTo((BigDecimal) existingValue, (BigDecimal) columnValue))
|| (existingValue == null ? columnValue == null : existingValue.equals(columnValue))) {
@@ -134,15 +134,13 @@ public class ImageWritePlatformServiceJpaRepositoryImpl implements ImageWritePla
private CommandProcessingResult updateImage(final Object owner, final String imageLocation, final StorageType storageType) {
Image image = null;
Long clientId = null;
if (owner instanceof Client) {
Client client = (Client) owner;
if (owner instanceof Client client) {
image = client.getImage();
clientId = client.getId();
image = createImage(image, imageLocation, storageType);
client.setImage(image);
this.clientRepositoryWrapper.save(client);
} else if (owner instanceof Staff) {
Staff staff = (Staff) owner;
} else if (owner instanceof Staff staff) {
image = staff.getImage();
clientId = staff.getId();
image = createImage(image, imageLocation, storageType);
@@ -150,7 +148,9 @@ public class ImageWritePlatformServiceJpaRepositoryImpl implements ImageWritePla
this.staffRepositoryWrapper.save(staff);
}
this.imageRepository.save(image);
if (image != null) {
this.imageRepository.save(image);
}
return CommandProcessingResult.resourceResult(clientId);
}
@@ -58,10 +58,9 @@ public class KafkaExternalEventProducer implements ExternalEventProducer {
List<CompletableFuture<SendResult<Long, byte[]>>> sendResults = new ArrayList<>();
measure(() -> {
Set<Long> keys = partitions.keySet();
for (Long key : keys) {
List<byte[]> messages = partitions.get(key);
for (byte[] message : messages) {
sendResults.add(externalEventsKafkaTemplate.send(topicName, key, message));
for (Map.Entry<Long, List<byte[]>> entry : partitions.entrySet()) {
for (byte[] message : entry.getValue()) {
sendResults.add(externalEventsKafkaTemplate.send(topicName, entry.getKey(), message));
}
}
@@ -47,7 +47,6 @@ import org.springframework.stereotype.Component;
@RequiredArgsConstructor
public class SchedulerJobListener implements JobListener {
private final String name = SchedulerServiceConstants.DEFAULT_LISTENER_NAME;
private final SchedularWritePlatformService schedularService;
private final AppUserRepositoryWrapper userRepository;
private final BusinessDateReadPlatformService businessDateReadPlatformService;
@@ -55,7 +54,7 @@ public class SchedulerJobListener implements JobListener {
@Override
public String getName() {
return this.name;
return SchedulerServiceConstants.DEFAULT_LISTENER_NAME;
}
@Override
@@ -23,7 +23,6 @@ import jakarta.ws.rs.core.Response;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.fineract.infrastructure.dataqueries.data.ReportExportType;
import org.apache.fineract.infrastructure.security.utils.SQLInjectionValidator;
@@ -35,11 +34,10 @@ public interface ReportingProcessService {
default Map<String, String> getReportParams(final MultivaluedMap<String, String> queryParams) {
final Map<String, String> reportParams = new HashMap<>();
final Set<String> keys = queryParams.keySet();
for (final String k : keys) {
if (k.startsWith("R_")) {
String pKey = "${" + k.substring(2) + "}";
String pValue = queryParams.get(k).get(0);
for (Map.Entry<String, List<String>> entry : queryParams.entrySet()) {
if (entry.getKey().startsWith("R_")) {
String pKey = "${" + entry.getKey().substring(2) + "}";
String pValue = entry.getValue().get(0);
SQLInjectionValidator.validateSQLInput(pValue);
reportParams.put(pKey, pValue);
}
@@ -59,7 +59,7 @@ import org.springframework.stereotype.Component;
@RequiredArgsConstructor
public class SmsApiResource {
private final String resourceNameForPermissions = "SMS";
private static final String RESOURCE_NAME_FOR_PERMISSIONS = "SMS";
private final PlatformSecurityContext context;
private final SmsReadPlatformService readPlatformService;
@@ -69,7 +69,7 @@ public class SmsApiResource {
@GET
public String retrieveAll(@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
final Collection<SmsData> smsMessages = readPlatformService.retrieveAll();
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return toApiJsonSerializer.serialize(settings, smsMessages);
@@ -98,7 +98,7 @@ public class SmsApiResource {
@QueryParam("dateFormat") final String rawDateFormat, @QueryParam("offset") final Integer offset,
@QueryParam("limit") final Integer limit, @QueryParam("orderBy") final String orderBy,
@QueryParam("sortOrder") final String sortOrder) {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
final SearchParameters searchParameters = SearchParameters.forSMSCampaign(offset, limit, orderBy, sortOrder);
final DateFormat dateFormat = StringUtils.isBlank(rawDateFormat) ? null : new DateFormat(rawDateFormat);
@@ -86,7 +86,7 @@ final class SurveyApiResourceSwagger {
@Schema(example = "201")
public Long ppi_fryingpans_cd_q10_fryingpans;
@Schema(example = "2014-12-02 20:30:00")
public ZonedDateTime Date;
public ZonedDateTime date;
@Schema(example = "Y-m-d H:i:s")
public ZonedDateTime dateFormat;
@Schema(example = "en_GB")
@@ -308,8 +308,10 @@ public class TellerApiResource {
@QueryParam("limit") @Parameter(description = "limit") final Integer limit,
@QueryParam("orderBy") @Parameter(description = "orderBy") final String orderBy,
@QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder) {
final TellerData teller = this.readPlatformService.findTeller(tellerId);
final CashierData cashier = this.readPlatformService.findCashier(cashierId);
// TODO: can we remove these 2 calls? we don't use the results, but left it here in case something is done in
// the functions
this.readPlatformService.findTeller(tellerId);
this.readPlatformService.findCashier(cashierId);
final LocalDate fromDate = null;
final LocalDate toDate = null;
@@ -334,8 +336,10 @@ public class TellerApiResource {
@QueryParam("limit") @Parameter(description = "limit") final Integer limit,
@QueryParam("orderBy") @Parameter(description = "orderBy") final String orderBy,
@QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder) {
final TellerData teller = this.readPlatformService.findTeller(tellerId);
final CashierData cashier = this.readPlatformService.findCashier(cashierId);
// TODO: can we remove these 2 calls? we don't use the results, but left it here in case something is done in
// the functions
this.readPlatformService.findTeller(tellerId);
this.readPlatformService.findCashier(cashierId);
final LocalDate fromDate = null;
final LocalDate toDate = null;
@@ -355,8 +355,8 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
this.fromApiJsonDeserializer.validateForCashTxnForCashier(command.json());
// TODO: can we please remove this whole block?!? this is 20 lines of dead code!!!
final String entityType = command.stringValueOfParameterNamed("entityType");
final Long entityId = command.longValueOfParameterNamed("entityId");
if (entityType != null) {
if (entityType.equals("loan account")) {
// TODO : Check if loan account exists
@@ -65,8 +65,6 @@ public class AddressReadPlatformServiceImpl implements AddressReadPlatformServic
final long addressId = rs.getLong("id");
final long clientId = rs.getLong("client_id");
final String street = rs.getString("street");
final String address_line_1 = rs.getString("address_line_1");
@@ -18,33 +18,37 @@
*/
package org.apache.fineract.portfolio.common.domain;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
public enum ConditionType {
INVALID(0, "ConditionType.invalid"), //
LESSTHAN(1, "ConditionType.lessthan"), //
EQUAL(2, "ConditionType.equal"), //
// TODO: fix typo "GREATERTHAN"
GRETERTHAN(3, "ConditionType.greterthan"), //
NOT_EQUAL(4, "ConditionType.notequal");//
private final Integer value;
private final String code;
private static final Map<Integer, ConditionType> intToEnumMap = new HashMap<>();
static {
for (final ConditionType type : ConditionType.values()) {
intToEnumMap.put(type.value, type);
public static ConditionType fromInt(final Integer v) {
if (v == null) {
return INVALID;
}
}
public static ConditionType fromInt(final Integer ruleTypeValue) {
final ConditionType type = intToEnumMap.get(ruleTypeValue);
return type;
switch (v) {
case 1:
return LESSTHAN;
case 2:
return EQUAL;
case 3:
return GRETERTHAN;
case 4:
return NOT_EQUAL;
default:
return INVALID;
}
}
ConditionType(final Integer value, final String code) {
@@ -65,34 +69,13 @@ public enum ConditionType {
return this.code;
}
public boolean isConditionTypeEqual() {
return ConditionType.EQUAL.getValue().equals(this.value);
}
public boolean isConditionTypeGreterThan() {
return ConditionType.GRETERTHAN.getValue().equals(this.value);
}
public boolean isConditionTypeNotEqual() {
return ConditionType.NOT_EQUAL.getValue().equals(this.value);
}
public boolean isConditionTypeLessThan() {
return ConditionType.LESSTHAN.getValue().equals(this.value);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isInvalid() {
return ConditionType.INVALID.getValue().equals(this.value);
}
// TODO: do we really need this?!?
public static Object[] integerValues() {
final List<Integer> values = new ArrayList<>();
for (final ConditionType enumType : values()) {
if (!enumType.isInvalid()) {
values.add(enumType.getValue());
}
}
return values.toArray();
return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
}
}
@@ -18,10 +18,7 @@
*/
package org.apache.fineract.portfolio.interestratechart.incentive;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
public enum InterestIncentiveAttributeName {
@@ -34,19 +31,21 @@ public enum InterestIncentiveAttributeName {
private final Integer value;
private final String code;
private static final Map<Integer, InterestIncentiveAttributeName> intToEnumMap = new HashMap<>();
static {
for (final InterestIncentiveAttributeName type : InterestIncentiveAttributeName.values()) {
intToEnumMap.put(type.value, type);
public static InterestIncentiveAttributeName fromInt(final Integer value) {
switch (value) {
case 2:
return GENDER;
case 3:
return AGE;
case 4:
return CLIENT_TYPE;
case 5:
return CLIENT_CLASSIFICATION;
default:
return INVALID;
}
}
public static InterestIncentiveAttributeName fromInt(final Integer ruleTypeValue) {
final InterestIncentiveAttributeName type = intToEnumMap.get(ruleTypeValue);
return type;
}
InterestIncentiveAttributeName(final Integer value, final String code) {
this.value = value;
this.code = code;
@@ -65,49 +64,45 @@ public enum InterestIncentiveAttributeName {
return this.code;
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isGender() {
return InterestIncentiveAttributeName.GENDER.getValue().equals(this.value);
return GENDER.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isAge() {
return InterestIncentiveAttributeName.AGE.getValue().equals(this.value);
return AGE.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isClientType() {
return InterestIncentiveAttributeName.CLIENT_TYPE.getValue().equals(this.value);
return CLIENT_TYPE.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isClientClassification() {
return InterestIncentiveAttributeName.CLIENT_CLASSIFICATION.getValue().equals(this.value);
return CLIENT_CLASSIFICATION.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isInvalid() {
return InterestIncentiveAttributeName.INVALID.getValue().equals(this.value);
return INVALID.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public static boolean isCodeValueAttribute(InterestIncentiveAttributeName attributeName) {
boolean isCodeValue = false;
switch (attributeName) {
case GENDER:
case CLIENT_TYPE:
case CLIENT_CLASSIFICATION:
isCodeValue = true;
break;
return true;
default:
break;
return false;
}
return isCodeValue;
}
// TODO: do we really need this?!?
public static Object[] integerValues() {
final List<Integer> values = new ArrayList<>();
for (final InterestIncentiveAttributeName enumType : values()) {
if (!enumType.isInvalid()) {
values.add(enumType.getValue());
}
}
return values.toArray();
return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
}
}
@@ -18,10 +18,7 @@
*/
package org.apache.fineract.portfolio.interestratechart.incentive;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
public enum InterestIncentiveEntityType {
@@ -32,17 +29,19 @@ public enum InterestIncentiveEntityType {
private final Integer value;
private final String code;
private static final Map<Integer, InterestIncentiveEntityType> intToEnumMap = new HashMap<>();
static {
for (final InterestIncentiveEntityType type : InterestIncentiveEntityType.values()) {
intToEnumMap.put(type.value, type);
public static InterestIncentiveEntityType fromInt(final Integer v) {
if (v == null) {
return INVALID;
}
}
public static InterestIncentiveEntityType fromInt(final Integer ruleTypeValue) {
final InterestIncentiveEntityType type = intToEnumMap.get(ruleTypeValue);
return type;
switch (v) {
case 2:
return CUSTOMER;
case 3:
return ACCOUNT;
default:
return INVALID;
}
}
InterestIncentiveEntityType(final Integer value, final String code) {
@@ -64,21 +63,15 @@ public enum InterestIncentiveEntityType {
}
public boolean isCustomer() {
return InterestIncentiveEntityType.CUSTOMER.getValue().equals(this.value);
return CUSTOMER.equals(this);
}
public boolean isInvalid() {
return InterestIncentiveEntityType.INVALID.getValue().equals(this.value);
return INVALID.equals(this);
}
// TODO: do we really need this?!?
public static Object[] integerValues() {
final List<Integer> values = new ArrayList<>();
for (final InterestIncentiveEntityType enumType : values()) {
if (!enumType.isInvalid()) {
values.add(enumType.getValue());
}
}
return values.toArray();
return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
}
}
@@ -18,10 +18,7 @@
*/
package org.apache.fineract.portfolio.interestratechart.incentive;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
public enum InterestIncentiveType {
@@ -32,17 +29,19 @@ public enum InterestIncentiveType {
private final Integer value;
private final String code;
private static final Map<Integer, InterestIncentiveType> intToEnumMap = new HashMap<>();
static {
for (final InterestIncentiveType type : InterestIncentiveType.values()) {
intToEnumMap.put(type.value, type);
public static InterestIncentiveType fromInt(final Integer v) {
if (v == null) {
return INVALID;
}
}
public static InterestIncentiveType fromInt(final Integer ruleTypeValue) {
final InterestIncentiveType type = intToEnumMap.get(ruleTypeValue);
return type;
switch (v) {
case 2:
return FIXED;
case 3:
return INCENTIVE;
default:
return INVALID;
}
}
InterestIncentiveType(final Integer value, final String code) {
@@ -63,27 +62,23 @@ public enum InterestIncentiveType {
return this.code;
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isIncentive() {
return InterestIncentiveType.INCENTIVE.getValue().equals(this.value);
return INCENTIVE.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isFixed() {
return InterestIncentiveType.FIXED.getValue().equals(this.value);
return FIXED.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isInvalid() {
return InterestIncentiveType.INVALID.getValue().equals(this.value);
return INVALID.equals(this);
}
// TODO: do we really need this?!?
public static Object[] integerValues() {
final List<Integer> values = new ArrayList<>();
for (final InterestIncentiveType enumType : values()) {
if (!enumType.isInvalid()) {
values.add(enumType.getValue());
}
}
return values.toArray();
return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
}
}
@@ -84,7 +84,7 @@ public class LoanTransactionsApiResource {
private final Set<String> responseDataParameters = new HashSet<>(Arrays.asList("id", "type", "date", "currency", "amount", "externalId",
LoanApiConstants.REVERSAL_EXTERNAL_ID_PARAMNAME, LoanApiConstants.REVERSED_ON_DATE_PARAMNAME));
private final String resourceNameForPermissions = "LOAN";
private static final String RESOURCE_NAME_FOR_PERMISSIONS = "LOAN";
private final PlatformSecurityContext context;
private final LoanReadPlatformService loanReadPlatformService;
@@ -414,7 +414,7 @@ public class LoanTransactionsApiResource {
private String retrieveTransaction(final Long loanId, final String loanExternalIdStr, final Long transactionId,
final String transactionExternalIdStr, final UriInfo uriInfo) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
ExternalId loanExternalId = ExternalIdFactory.produce(loanExternalIdStr);
ExternalId transactionExternalId = ExternalIdFactory.produce(transactionExternalIdStr);
@@ -488,7 +488,7 @@ public class LoanTransactionsApiResource {
private String retrieveTransactionTemplate(Long loanId, String loanExternalIdStr, String commandParam, UriInfo uriInfo,
DateFormat dateFormat, DateParam transactionDateParam, String locale) {
this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS);
ExternalId loanExternalId = ExternalIdFactory.produce(loanExternalIdStr);
@@ -66,23 +66,23 @@ public class ApplyChargeToOverdueLoanInstallmentTasklet implements Tasklet {
}
List<Throwable> exceptions = new ArrayList<>();
for (final Long loanId : overdueScheduleData.keySet()) {
for (Map.Entry<Long, Collection<OverdueLoanScheduleData>> entry : overdueScheduleData.entrySet()) {
try {
loanChargeWritePlatformService.applyOverdueChargesForLoan(loanId, overdueScheduleData.get(loanId));
loanChargeWritePlatformService.applyOverdueChargesForLoan(entry.getKey(), entry.getValue());
} catch (final PlatformApiDataValidationException e) {
final List<ApiParameterError> errors = e.getErrors();
for (final ApiParameterError error : errors) {
log.error("Apply Charges due for overdue loans failed for account {} with message: {}", loanId,
log.error("Apply Charges due for overdue loans failed for account {} with message: {}", entry.getKey(),
error.getDeveloperMessage(), e);
}
exceptions.add(e);
} catch (final AbstractPlatformDomainRuleException e) {
log.error("Apply Charges due for overdue loans failed for account {} with message: {}", loanId,
log.error("Apply Charges due for overdue loans failed for account {} with message: {}", entry.getKey(),
e.getDefaultUserMessage(), e);
exceptions.add(e);
} catch (Exception e) {
log.error("Apply Charges due for overdue loans failed for account {}", loanId, e);
log.error("Apply Charges due for overdue loans failed for account {}", entry.getKey(), e);
exceptions.add(e);
}
}
@@ -39,7 +39,6 @@ public class GenerateLoanlossProvisioningConfig {
private JobRepository jobRepository;
@Autowired
private PlatformTransactionManager transactionManager;
private StepBuilder steps;
@Autowired
private ProvisioningCriteriaReadPlatformService provisioningCriteriaReadPlatformService;
@Autowired
@@ -75,7 +75,7 @@ public class SetLoanDelinquencyTagsTasklet implements Tasklet {
loanScheduleDelinquencyData = this.loanRepaymentScheduleInstallmentRepository
.fetchLoanScheduleDataByDueDateAndObligationsMet(LoanStatus.ACTIVE.getValue(), businessDate, false, processedLoans);
}
processedLoans = applyDelinquencyTagToLoans(loanScheduleDelinquencyData);
applyDelinquencyTagToLoans(loanScheduleDelinquencyData);
return RepeatStatus.FINISHED;
}
@@ -771,10 +771,9 @@ public class LoanScheduleAssembler {
graceApplicable = installment.getDueDate();
}
}
Collection<LocalDate> keySet = adjustDueDateVariations.keySet();
dueDates.addAll(keySet);
for (final LocalDate date : keySet) {
LocalDate removeDate = adjustDueDateVariations.get(date);
dueDates.addAll(adjustDueDateVariations.keySet());
for (Map.Entry<LocalDate, LocalDate> entry : adjustDueDateVariations.entrySet()) {
LocalDate removeDate = entry.getValue();
if (removeDate != null) {
dueDates.remove(removeDate);
}
@@ -1453,8 +1453,6 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
@Override
public CommandProcessingResult undoApplicationApproval(final Long loanId, final JsonCommand command) {
AppUser currentUser = getAppUserIfPresent();
this.fromApiJsonDeserializer.validateForUndo(command.json());
final Loan loan = retrieveLoanBy(loanId);
@@ -125,14 +125,16 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
@Override
public void updateLoanArrearsAgeingDetails(final Loan loan) {
int count = this.jdbcTemplate.queryForObject("select count(mla.loan_id) from m_loan_arrears_aging mla where mla.loan_id =?",
Integer.class, loan.getId());
String updateStatement = constructUpdateStatement(loan, count == 0);
if (updateStatement == null) {
String deletestatement = "DELETE FROM m_loan_arrears_aging WHERE loan_id=?";
this.jdbcTemplate.update(deletestatement, loan.getId()); // NOSONAR
} else {
this.jdbcTemplate.update(updateStatement);
if (loan != null) {
int count = this.jdbcTemplate.queryForObject("select count(mla.loan_id) from m_loan_arrears_aging mla where mla.loan_id =?",
Integer.class, loan.getId());
String updateStatement = constructUpdateStatement(loan, count == 0);
if (updateStatement == null) {
String deletestatement = "DELETE FROM m_loan_arrears_aging WHERE loan_id=?";
this.jdbcTemplate.update(deletestatement, loan.getId()); // NOSONAR
} else {
this.jdbcTemplate.update(updateStatement);
}
}
}
@@ -48,31 +48,24 @@ public enum AttendanceType {
return this.code;
}
public static AttendanceType fromInt(final Integer attendanceTypeId) {
if (attendanceTypeId == null) {
return AttendanceType.INVALID;
public static AttendanceType fromInt(final Integer v) {
if (v == null) {
return INVALID;
}
AttendanceType attendanceType = AttendanceType.INVALID;
switch (attendanceTypeId) {
switch (v) {
case 1:
attendanceType = AttendanceType.PRESENT;
break;
return PRESENT;
case 2:
attendanceType = AttendanceType.ABSENT;
break;
return ABSENT;
case 3:
attendanceType = AttendanceType.APPROVED;
break;
return APPROVED;
case 4:
attendanceType = AttendanceType.LEAVE;
break;
return LEAVE;
case 5:
attendanceType = AttendanceType.LATE;
break;
return LATE;
default:
return INVALID;
}
return attendanceType;
}
}
@@ -23,7 +23,6 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
@@ -42,7 +41,6 @@ public class RateAssembler {
if (element.isJsonObject()) {
final JsonObject topLevelJsonElement = element.getAsJsonObject();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
if (topLevelJsonElement.has(LoanProductConstants.RATES_PARAM_NAME)
&& topLevelJsonElement.get(LoanProductConstants.RATES_PARAM_NAME).isJsonArray()) {
@@ -18,7 +18,6 @@
*/
package org.apache.fineract.portfolio.savings.handler;
import java.time.LocalDate;
import org.apache.fineract.commands.annotation.CommandType;
import org.apache.fineract.commands.handler.NewCommandSourceHandler;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
@@ -43,9 +42,9 @@ public class ApplyAnnualFeeSavingsAccountCommandHandler implements NewCommandSou
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
@SuppressWarnings("unused")
final LocalDate annualFeeTransactionDate = command.localDateValueOfParameterNamed("annualFeeTransactionDate");
// TODO: why do we keep this class when we literally do nothing here?!?
// final LocalDate annualFeeTransactionDate =
// command.localDateValueOfParameterNamed("annualFeeTransactionDate");
// return
// this.writePlatformService.applyAnnualFee(command.getSavingsId(),
@@ -264,15 +264,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
@Transactional
@Override
public CommandProcessingResult gsimDeposit(final Long gsimId, final JsonCommand command) {
Long parentSavingId = gsimId;
// GroupSavingsIndividualMonitoringparentSavings=gsimRepository.findById(parentSavingId).get();
List<SavingsAccount> childSavings = this.savingAccountRepositoryWrapper.findByGsimId(gsimId);
JsonArray savingsArray = command.arrayOfParameterNamed("savingsArray");
JsonArray childAccounts = command.arrayOfParameterNamed("childAccounts");
int count = 0;
CommandProcessingResult result = null;
for (JsonElement element : savingsArray) {
result = deposit(element.getAsJsonObject().get("childAccountId").getAsLong(),
@@ -1457,13 +1450,6 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
existingReversedTransactionIds.addAll(account.findCurrentReversedTransactionIdsWithPivotDateConfig());
}
@SuppressWarnings("unused")
private void updateSavingsTransactionsDetails(SavingsAccountData account, Set<Long> existingTransactionIds,
Set<Long> existingReversedTransactionIds) {
existingTransactionIds.addAll(account.findCurrentTransactionIdsWithPivotDateConfig());
existingReversedTransactionIds.addAll(account.findCurrentReversedTransactionIdsWithPivotDateConfig());
}
private void postJournalEntries(final SavingsAccount savingsAccount, final Set<Long> existingTransactionIds,
final Set<Long> existingReversedTransactionIds, final boolean backdatedTxnsAllowedTill) {
@@ -83,8 +83,8 @@ public class SavingsSchedularInterestPoster {
} catch (DataAccessException exception) {
log.error("Batch update failed due to DataAccessException", exception);
errors.add(exception);
} catch (NullPointerException exception) {
log.error("Batch update failed due to NullPointerException", exception);
} catch (Exception exception) {
log.error("Batch update failed", exception);
errors.add(exception);
}
}
@@ -18,8 +18,7 @@
*/
package org.apache.fineract.portfolio.shareproducts;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
/**
* An enumeration of supported calendar periods used in savings.
@@ -48,39 +47,32 @@ public enum SharePeriodFrequencyType {
return this.code;
}
public static SharePeriodFrequencyType fromInt(final Integer type) {
SharePeriodFrequencyType repaymentFrequencyType = SharePeriodFrequencyType.INVALID;
if (type != null) {
switch (type) {
case 0:
repaymentFrequencyType = SharePeriodFrequencyType.DAYS;
break;
case 1:
repaymentFrequencyType = SharePeriodFrequencyType.WEEKS;
break;
case 2:
repaymentFrequencyType = SharePeriodFrequencyType.MONTHS;
break;
case 3:
repaymentFrequencyType = SharePeriodFrequencyType.YEARS;
break;
}
public static SharePeriodFrequencyType fromInt(final Integer v) {
if (v == null) {
return INVALID;
}
switch (v) {
case 0:
return DAYS;
case 1:
return WEEKS;
case 2:
return MONTHS;
case 3:
return YEARS;
default:
return INVALID;
}
return repaymentFrequencyType;
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isInvalid() {
return this.value.equals(SharePeriodFrequencyType.INVALID.value);
return this.equals(INVALID);
}
// TODO: do we really need this?!?
public static Object[] integerValues() {
final List<Integer> values = new ArrayList<>();
for (final SharePeriodFrequencyType enumType : values()) {
if (!enumType.isInvalid()) {
values.add(enumType.getValue());
}
}
return values.toArray();
return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
}
}
@@ -81,7 +81,7 @@ public class JpaTemplateDomainService implements TemplateDomainService {
template.setText(command.stringValueOfParameterNamed(PROPERTY_TEXT));
template.setEntity(TemplateEntity.values()[command.integerValueSansLocaleOfParameterNamed(PROPERTY_ENTITY)]);
final int templateTypeId = command.integerValueSansLocaleOfParameterNamed(PROPERTY_TYPE);
TemplateType type = null;
TemplateType type;
switch (templateTypeId) {
case 0:
type = TemplateType.DOCUMENT;
@@ -89,6 +89,8 @@ public class JpaTemplateDomainService implements TemplateDomainService {
case 2:
type = TemplateType.SMS;
break;
default:
type = null;
}
template.setType(type);
@@ -55,19 +55,19 @@ public class PermissionWritePlatformServiceJpaRepositoryImpl implements Permissi
final Map<String, Boolean> commandPermissions = permissionsCommand.getPermissions();
final Map<String, Object> changes = new HashMap<>();
final Map<String, Boolean> changedPermissions = new HashMap<>();
for (final String permissionCode : commandPermissions.keySet()) {
for (Map.Entry<String, Boolean> entry : commandPermissions.entrySet()) {
final Permission permission = findPermissionInCollectionByCode(allPermissions, permissionCode);
final Permission permission = findPermissionInCollectionByCode(allPermissions, entry.getKey());
if (permission.getCode().endsWith("_CHECKER") || permission.getCode().startsWith("READ_")
|| permission.getGrouping().equalsIgnoreCase("special")) {
throw new PermissionNotFoundException(permissionCode);
throw new PermissionNotFoundException(entry.getKey());
}
final boolean isSelected = commandPermissions.get(permissionCode).booleanValue();
final boolean isSelected = entry.getValue();
final boolean changed = permission.enableMakerChecker(isSelected);
if (changed) {
changedPermissions.put(permissionCode, isSelected);
changedPermissions.put(entry.getKey(), isSelected);
this.permissionRepository.saveAndFlush(permission);
}
}
@@ -148,13 +148,13 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf
final Map<String, Boolean> commandPermissions = permissionsCommand.getPermissions();
final Map<String, Object> changes = new HashMap<>();
final Map<String, Boolean> changedPermissions = new HashMap<>();
for (final String permissionCode : commandPermissions.keySet()) {
final boolean isSelected = commandPermissions.get(permissionCode).booleanValue();
for (Map.Entry<String, Boolean> entry : commandPermissions.entrySet()) {
final boolean isSelected = entry.getValue();
final Permission permission = findPermissionByCode(allPermissions, permissionCode);
final Permission permission = findPermissionByCode(allPermissions, entry.getKey());
final boolean changed = role.updatePermission(permission, isSelected);
if (changed) {
changedPermissions.put(permissionCode, isSelected);
changedPermissions.put(entry.getKey(), isSelected);
}
}
@@ -171,6 +171,8 @@ fineract.sampling.resetPeriodSec=${FINERACT_SAMPLING_RESET_PERIOD_IN_SEC:60}
fineract.module.investor.enabled=${FINERACT_MODULE_INVESTOR_ENABLED:true}
fineract.insecure-http-client=${FINERACT_INSECURE_HTTP_CLIENT:true}
# Logging pattern for the console
logging.pattern.console=${CONSOLE_LOG_PATTERN:%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%replace([%X{correlationId}]){'\\[\\]', ''}) %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}}
logging.pattern.level=%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]
@@ -6,7 +6,7 @@
/_/ \_\ .__/ \__,_|\___|_| |_|\___| |_| |_|_| |_|\___|_| \__,_|\___|\__|
|_|
${AnsiStyle.FAINT}${AnsiColor.WHITE}(c) 2015-2022 ${application.title} (https://fineract.apache.org)${AnsiColor.BLACK}
${AnsiStyle.FAINT}${AnsiColor.WHITE}(c) 2015-2024 ${application.title} (https://fineract.apache.org)${AnsiColor.BLACK}
${AnsiStyle.FAINT}${AnsiColor.WHITE}Powered by Spring Boot ${spring-boot.version}${AnsiColor.BLACK}
@@ -25,6 +25,7 @@ import com.zaxxer.hikari.HikariDataSource;
import java.util.List;
import javax.sql.DataSource;
import liquibase.change.custom.CustomTaskChange;
import okhttp3.OkHttpClient;
import org.apache.fineract.infrastructure.core.config.FineractProperties;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
import org.apache.fineract.infrastructure.core.service.database.DatabaseIndependentQueryService;
@@ -188,4 +189,10 @@ public class TestConfiguration {
public JobOperator jobOperator() {
return mock(JobOperator.class, RETURNS_MOCKS);
}
@Primary
@Bean
public OkHttpClient okHttpClient() {
return mock(OkHttpClient.class, RETURNS_MOCKS);
}
}
@@ -26,10 +26,9 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import com.google.common.base.Splitter;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.cucumber.java8.En;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;
@@ -44,12 +43,12 @@ import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
import org.apache.fineract.infrastructure.core.domain.ActionContext;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
import org.apache.fineract.mix.data.MixTaxonomyData;
import org.mockito.Mockito;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.context.ApplicationContext;
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class COBBusinessStepServiceStepDefinitions implements En {
private ApplicationContext applicationContext = mock(ApplicationContext.class);
@@ -68,10 +67,6 @@ public class COBBusinessStepServiceStepDefinitions implements En {
private AbstractAuditableCustom outputItem = mock(AbstractAuditableCustom.class);
private AbstractAuditableCustom resultItem;
private HashMap<MixTaxonomyData, BigDecimal> data = new HashMap<>();
private String result;
private Class clazz;
private String jobName;
private BatchBusinessStep batchBusinessStep = mock(BatchBusinessStep.class);
@@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.cucumber.java8.En;
import java.time.LocalDate;
import java.time.ZoneId;
@@ -41,6 +42,7 @@ import org.springframework.batch.core.scope.context.StepContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.security.core.context.SecurityContextHolder;
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class InitialisationTaskletStepDefinitions implements En {
private static final LocalDate TODAY = LocalDate.now(ZoneId.systemDefault());
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.cucumber.java8.En;
import java.time.LocalDate;
import java.time.ZoneId;
@@ -50,6 +51,7 @@ import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class ApplyLoanLockTaskletStepDefinitions implements En {
ArgumentCaptor<List> valueCaptor = ArgumentCaptor.forClass(List.class);
@@ -25,6 +25,7 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.cucumber.java8.En;
import java.time.LocalDate;
import java.time.ZoneId;
@@ -36,6 +37,7 @@ import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.item.ExecutionContext;
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class LoanItemProcessorStepDefinitions implements En {
private COBBusinessStepService cobBusinessStepService = mock(COBBusinessStepService.class);
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import com.google.common.base.Splitter;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.cucumber.java8.En;
import java.time.LocalDate;
import java.time.ZoneId;
@@ -47,6 +48,7 @@ import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.item.ExecutionContext;
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class LoanItemReaderStepDefinitions implements En {
private LoanRepository loanRepository = mock(LoanRepository.class);
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.HashMap;
@@ -54,6 +55,7 @@ import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.context.ApplicationContext;
@ExtendWith(MockitoExtension.class)
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class COBBulkEventConfigurationTest {
@Mock
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDate;
@@ -52,6 +53,7 @@ import org.springframework.transaction.support.TransactionTemplate;
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
class InlineLoanCOBExecutorServiceImplTest {
@InjectMocks
@@ -20,10 +20,12 @@ package org.apache.fineract.commands.provider;
import static org.junit.jupiter.api.Assertions.assertThrows;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.cucumber.java8.En;
import org.apache.fineract.commands.exception.UnsupportedCommandException;
import org.springframework.beans.factory.annotation.Autowired;
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class CommandHandlerExceptionStepDefinitions implements En {
@Autowired
@@ -21,6 +21,7 @@ package org.apache.fineract.commands.service;
import static org.apache.fineract.commands.domain.CommandProcessingResultType.UNDER_PROCESSING;
import static org.mockito.ArgumentMatchers.any;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.time.ZoneId;
import java.util.Optional;
import org.apache.fineract.batch.exception.ErrorInfo;
@@ -44,6 +45,7 @@ import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class CommandSourceServiceTest {
@Mock
@@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Map;
import org.apache.fineract.commands.domain.CommandProcessingResultType;
@@ -48,6 +49,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class SynchronousCommandProcessingServiceTest {
@Mock
@@ -25,6 +25,7 @@ import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Optional;
@@ -55,6 +56,7 @@ import org.mockito.quality.Strictness;
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class BusinessDateWritePlatformServiceTest {
@InjectMocks
@@ -105,7 +105,7 @@ public class LiquibaseStepDefinitions implements En {
});
Then("The database migration did not do anything", () -> {
verify(databaseStateVerifier).isLiquibaseDisabled();
assertThat(verify(databaseStateVerifier).isLiquibaseDisabled()).isFalse();
verifyNoMoreInteractions(databaseStateVerifier);
verifyNoInteractions(tenantDetailsService, tenantStoreDataSource, liquibaseFactory, tenantDataSourceFactory);
});
@@ -20,18 +20,18 @@ package org.apache.fineract.infrastructure.core;
import static org.junit.jupiter.api.Assertions.assertThrows;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.cucumber.java8.En;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.exception.MultiException;
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class MultiExceptionStepDefinitions implements En {
private List<Throwable> exceptions = new ArrayList<>();
private MultiException multiException;
public MultiExceptionStepDefinitions() {
Given("/^A multi exception with exceptions (.*) and (.*)$/", (String exception1, String exception2) -> {
if (!StringUtils.isBlank(exception1)) {
@@ -32,8 +32,10 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.gson.JsonParser;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.ZoneId;
@@ -71,25 +73,26 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest {
@Spy
private FromJsonHelper fromJsonHelper = new FromJsonHelper();
@Spy
private CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer = new CreditBureauTokenCommandFromApiJsonDeserializer(
fromJsonHelper);
@Mock
private OkHttpClient okHttpClient;
@Mock
private CreditBureauConfigurationRepositoryWrapper configurationRepositoryWrapper;
@Mock
private TokenRepositoryWrapper tokenRepositoryWrapper;
@Mock
private PlatformSecurityContext platformSecurityContext;
@Mock
private TokenRepositoryWrapper tokenRepositoryWrapper;
private CreditBureauTokenCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final ObjectMapper mapper = new ObjectMapper();
@@ -261,7 +264,7 @@ public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest {
String jsonResponse = createResponseObjectArrayData(() -> "UPLOADED", data -> data);
Path temp = Files.createTempFile("upload_test" + System.currentTimeMillis(), ".data");
Files.writeString(temp, "test");
Files.writeString(temp, "test", StandardCharsets.UTF_8);
mockOkHttpCall(request -> {
assertEquals(request.header("Authorization"), "Bearer AccessToken");
@@ -474,7 +477,7 @@ public class ThitsaWorksCreditBureauIntegrationWritePlatformServiceImplTest {
String jsonResponse = createResponseObjectArrayData(() -> "ADD_CREDIT_RESPONSE", data -> data);
Path temp = Files.createTempFile("add_credit_report" + System.currentTimeMillis(), ".data");
Files.writeString(temp, "test");
Files.writeString(temp, "test", StandardCharsets.UTF_8);
mockOkHttpCall(request -> {
if (request.url().host().equals("addcredit.report.url")) {
@@ -29,6 +29,7 @@ import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.when;
import com.google.gson.JsonObject;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.List;
import java.util.stream.Stream;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
@@ -49,6 +50,7 @@ import org.mockito.MockitoAnnotations;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class ReadWriteNonCoreDataServiceImplTest {
@Mock
@@ -20,6 +20,7 @@ package org.apache.fineract.infrastructure.event.external.producer.kafka;
import static org.mockito.Mockito.times;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
@@ -36,6 +37,7 @@ import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
@ExtendWith(MockitoExtension.class)
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
class KafkaExternalEventProducerTest {
public static final String TOPIC_NAME = "unit-test";
@@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.persistence.EntityManager;
import org.apache.fineract.infrastructure.event.external.exception.ExternalEventConfigurationNotFoundException;
import org.apache.fineract.infrastructure.event.external.repository.CustomExternalEventConfigurationRepositoryImpl;
@@ -35,6 +36,7 @@ import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class CustomExternalEventConfigurationRepositoryImplTest {
@Mock
@@ -53,7 +53,6 @@ import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.apache.fineract.portfolio.loanaccount.domain.LoanSummary;
import org.apache.fineract.portfolio.loanaccount.service.LoanCalculateRepaymentPastDueService;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -153,7 +152,6 @@ public class LoanRepaymentBusinessEventSerializerTest {
LocalDate loanInstallmentRepaymentDueDate = DateUtils.getBusinessLocalDate().plusDays(1);
Loan loanForProcessing = Mockito.mock(Loan.class);
LoanProduct loanProduct = Mockito.mock(LoanProduct.class);
LoanSummary loanSummary = Mockito.mock(LoanSummary.class);
MonetaryCurrency loanCurrency = Mockito.mock(MonetaryCurrency.class);
@@ -53,7 +53,6 @@ import org.apache.fineract.portfolio.loanaccount.domain.GLIMAccountInfoRepositor
import org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest;
import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequestRepository;
import org.apache.fineract.useradministration.domain.AppUser;
import org.apache.http.HttpStatus;
@@ -254,7 +253,6 @@ class LoanCOBApiFilterTest {
given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
given(fineractProperties.getQuery()).willReturn(fineractQueryProperties);
given(fineractQueryProperties.getInClauseParameterSizeLimit()).willReturn(65000);
LoanRescheduleRequest rescheduleRequest = mock(LoanRescheduleRequest.class);
given(loanRescheduleRequestRepository.getLoanIdByRescheduleRequestId(resourceId)).willReturn(Optional.of(2L));
given(context.authenticatedUser()).willReturn(appUser);
@@ -18,10 +18,12 @@
*/
package org.apache.fineract.infrastructure.security.utils;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Arrays;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
public class SQLInjectionValidatorTest {
private static final String[] DDL_COMMANDS = { "create", "drop", "alter", "truncate", "comment", "sleep" };
@@ -53,16 +53,16 @@ import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class EnricherTest {
private final LocalDate actualDate = LocalDate.now(ZoneId.systemDefault());
private static final LocalDate ACTUAL_DATE = LocalDate.now(ZoneId.systemDefault());
private final String purchasePriceRatio = "100.123";
private final String settlementDate = DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.now(ZoneId.systemDefault()));
private static final String PURCHASE_PRICE_RATIO = "100.123";
private static final String SETTLEMENT_DATE = DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.now(ZoneId.systemDefault()));
@BeforeEach
public void setUp() {
ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null));
ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
ThreadLocalContextUtil.setBusinessDates(new HashMap<>(Map.of(BusinessDateType.BUSINESS_DATE, actualDate)));
ThreadLocalContextUtil.setBusinessDates(new HashMap<>(Map.of(BusinessDateType.BUSINESS_DATE, ACTUAL_DATE)));
}
@@ -73,8 +73,8 @@ public class EnricherTest {
doAnswer(a -> {
LoanAccountDataV1 data = a.getArgument(0, LoanAccountDataV1.class);
data.setExternalOwnerId("1");
data.setSettlementDate(settlementDate);
data.setPurchasePriceRatio(purchasePriceRatio);
data.setSettlementDate(SETTLEMENT_DATE);
data.setPurchasePriceRatio(PURCHASE_PRICE_RATIO);
return null;
}).when(loanAccountDataV1Enricher).enrich(any(LoanAccountDataV1.class));
@@ -86,8 +86,8 @@ public class EnricherTest {
verify(loanAccountDataV1Enricher, times(1)).enrich(any(LoanAccountDataV1.class));
assertEquals("1", original.getExternalOwnerId());
assertEquals(settlementDate, original.getSettlementDate());
assertEquals(purchasePriceRatio, original.getPurchasePriceRatio());
assertEquals(SETTLEMENT_DATE, original.getSettlementDate());
assertEquals(PURCHASE_PRICE_RATIO, original.getPurchasePriceRatio());
}
@Test
@@ -143,8 +143,8 @@ public class EnricherTest {
doAnswer(a -> {
LoanAccountDataV1 data = a.getArgument(0, LoanAccountDataV1.class);
data.setExternalOwnerId("1");
data.setSettlementDate(settlementDate);
data.setPurchasePriceRatio(purchasePriceRatio);
data.setSettlementDate(SETTLEMENT_DATE);
data.setPurchasePriceRatio(PURCHASE_PRICE_RATIO);
return null;
}).when(loanAccountDataV1Enricher).enrich(any(LoanAccountDataV1.class));
@@ -174,8 +174,8 @@ public class EnricherTest {
verify(loanTransactionDataV1Enricher, times(1)).isDataTypeSupported(any());
assertEquals("1", data.getExternalOwnerId());
assertEquals(settlementDate, data.getSettlementDate());
assertEquals(purchasePriceRatio, data.getPurchasePriceRatio());
assertEquals(SETTLEMENT_DATE, data.getSettlementDate());
assertEquals(PURCHASE_PRICE_RATIO, data.getPurchasePriceRatio());
}
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.verify;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanAdjustTransactionBusinessEvent;
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
@@ -37,6 +38,7 @@ import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
@SuppressFBWarnings(value = "RV_EXCEPTION_NOT_THROWN", justification = "False positive")
class ReplayedTransactionBusinessEventServiceIntegrationTest {
@Mock