FINERACT-1932: Fineract modularization - fineract-savings

This commit is contained in:
Jose Alberto Hernandez
2024-01-29 14:14:31 +01:00
committed by Adam Saghy
parent 1f00bb6d33
commit 02cf6749af
213 changed files with 352 additions and 78 deletions
@@ -1,90 +0,0 @@
/**
* 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.dataqueries.api;
/**
* Created by Cieyou on 2/26/14.
*/
public final class DataTableApiConstant {
private DataTableApiConstant() {
}
public static final Integer CATEGORY_PPI = 200;
public static final Integer CATEGORY_DEFAULT = 100;
public static final String categoryParamName = "category";
public static final String localParamName = "locale";
public static final String DATATABLE_RESOURCE_NAME = "dataTables";
public static final String CREATEDAT_FIELD_NAME = "created_at";
public static final String UPDATEDAT_FIELD_NAME = "updated_at";
// associationParameters
public static final String allAssociateParamName = "all";
public static final String repaymentScheduleAssociateParamName = "repaymentSchedule";
public static final String originalScheduleAssociateParamName = "originalSchedule";
public static final String transactionsAssociateParamName = "transactions";
public static final String chargesAssociateParamName = "charges";
public static final String guarantorsAssociateParamName = "guarantors";
public static final String collateralAssociateParamName = "collateral";
public static final String notesAssociateParamName = "notes";
public static final String linkedAccountAssociateParamName = "linkedAccount";
public static final String multiDisburseDetailsAssociateParamName = "multiDisburseDetails";
public static final String futureScheduleAssociateParamName = "futureSchedule";
public static final String meetingAssociateParamName = "meeting";
public static final String emiAmountVariationsAssociateParamName = "emiAmountVariations";
public static final String collectionAssociateParamName = "collection";
public static final String TABLE_COLUMN_CODE_MAPPINGS = "x_table_column_code_mappings";
public static final String TABLE_REGISTERED_TABLE = "x_registered_table";
public static final String TABLE_FIELD_ID = "id";
public static final String API_PARAM_COLUMNS = "columns";
public static final String API_PARAM_CHANGECOLUMNS = "changeColumns";
public static final String API_PARAM_ADDCOLUMNS = "addColumns";
public static final String API_PARAM_DROPCOLUMNS = "dropColumns";
public static final String API_PARAM_DATATABLE_NAME = "datatableName";
public static final String API_PARAM_APPTABLE_NAME = "apptableName";
public static final String API_PARAM_SUBTYPE = "entitySubType";
public static final String API_PARAM_MULTIROW = "multiRow";
public static final String API_FIELD_NAME = "name";
public static final String API_FIELD_NEWNAME = "newName";
public static final String API_FIELD_TYPE = "type";
public static final String API_FIELD_LENGTH = "length";
public static final String API_FIELD_MANDATORY = "mandatory";
public static final String API_FIELD_UNIQUE = "unique";
public static final String API_FIELD_INDEXED = "indexed";
public static final String API_FIELD_AFTER = "after";
public static final String API_FIELD_CODE = "code";
public static final String API_FIELD_NEWCODE = "newCode";
public static final String API_FIELD_TYPE_STRING = "string";
public static final String API_FIELD_TYPE_NUMBER = "number";
public static final String API_FIELD_TYPE_BOOLEAN = "boolean";
public static final String API_FIELD_TYPE_DECIMAL = "decimal";
public static final String API_FIELD_TYPE_DATE = "date";
public static final String API_FIELD_TYPE_DATETIME = "datetime";
public static final String API_FIELD_TYPE_TIMESTAMP = "timestamp";
public static final String API_FIELD_TYPE_TEXT = "text";
public static final String API_FIELD_TYPE_JSON = "json";
public static final String API_FIELD_TYPE_DROPDOWN = "dropdown";
}
@@ -1,131 +0,0 @@
/**
* 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.dataqueries.data;
import static org.apache.fineract.portfolio.search.SearchConstants.API_PARAM_COLUMN;
import static org.apache.fineract.portfolio.search.SearchConstants.API_PARAM_FILTERS;
import static org.apache.fineract.portfolio.search.SearchConstants.API_PARAM_OPERATOR;
import static org.apache.fineract.portfolio.search.SearchConstants.API_PARAM_QUERY;
import static org.apache.fineract.portfolio.search.SearchConstants.API_PARAM_RESULTCOLUMNS;
import static org.apache.fineract.portfolio.search.SearchConstants.API_PARAM_TABLE;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
import jakarta.validation.constraints.NotNull;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.dataqueries.api.DataTableApiConstant;
import org.apache.fineract.portfolio.search.data.AdvancedQueryData;
import org.apache.fineract.portfolio.search.data.AdvancedQueryRequest;
import org.apache.fineract.portfolio.search.data.ColumnFilterData;
import org.apache.fineract.portfolio.search.data.FilterData;
import org.apache.fineract.portfolio.search.data.TableQueryData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class DataTableValidator {
private final FromJsonHelper fromApiJsonHelper;
private static final Set<String> SUPPORTED_PARAMETERS = new HashSet<>(
Arrays.asList(DataTableApiConstant.categoryParamName, DataTableApiConstant.localParamName));
@Autowired
public DataTableValidator(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public void validateDataTableRegistration(final String json) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SUPPORTED_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(DataTableApiConstant.DATATABLE_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
if (this.fromApiJsonHelper.parameterExists(DataTableApiConstant.categoryParamName, element)) {
final Integer category = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(DataTableApiConstant.categoryParamName, element);
Object[] objectArray = new Integer[] { DataTableApiConstant.CATEGORY_PPI, DataTableApiConstant.CATEGORY_DEFAULT };
baseDataValidator.reset().parameter(DataTableApiConstant.categoryParamName).value(category).isOneOfTheseValues(objectArray);
}
baseDataValidator.throwValidationErrors();
}
public void validateTableSearch(@NotNull AdvancedQueryRequest queryRequest) {
final List<ApiParameterError> errors = new ArrayList<>();
final DataValidatorBuilder validator = new DataValidatorBuilder(errors).resource(DataTableApiConstant.DATATABLE_RESOURCE_NAME);
AdvancedQueryData baseQuery = queryRequest.getBaseQuery();
if (baseQuery != null) {
validateQueryData(baseQuery, validator);
}
List<TableQueryData> datatableQueries = queryRequest.getDatatableQueries();
if (datatableQueries != null) {
for (TableQueryData datatableQuery : datatableQueries) {
validator.reset().parameter(API_PARAM_TABLE).value(datatableQuery.getTable()).notBlank();
AdvancedQueryData queryData = datatableQuery.getQuery();
validator.reset().parameter(API_PARAM_QUERY).value(queryData).notBlank();
if (queryData != null) {
validateQueryData(queryData, validator);
}
}
}
validator.throwValidationErrors();
}
public void validateTableSearch(@NotNull AdvancedQueryData queryData) {
final DataValidatorBuilder validator = new DataValidatorBuilder(new ArrayList<>())
.resource(DataTableApiConstant.DATATABLE_RESOURCE_NAME);
validateQueryData(queryData, validator);
validator.throwValidationErrors();
}
private void validateQueryData(@NotNull AdvancedQueryData queryData, @NotNull DataValidatorBuilder validator) {
List<ColumnFilterData> columnFilters = queryData.getColumnFilters();
if (columnFilters != null) {
for (ColumnFilterData columnFilter : columnFilters) {
validator.reset().parameter(API_PARAM_COLUMN).value(columnFilter.getColumn()).notNull();
List<FilterData> filters = columnFilter.getFilters();
validator.reset().parameter(API_PARAM_FILTERS).value(filters == null ? null : filters.toArray()).notNull().arrayNotEmpty();
if (filters != null) {
for (FilterData filter : filters) {
validator.reset().parameter(API_PARAM_OPERATOR).value(filter.getOperator()).notNull();
}
}
}
List<String> resultColumns = queryData.getResultColumns();
if (resultColumns != null) {
for (String resultColumn : resultColumns) {
validator.reset().parameter(API_PARAM_RESULTCOLUMNS).value(resultColumn).notBlank();
}
}
}
}
}
@@ -1,33 +0,0 @@
/**
* 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.dataqueries.data;
import java.io.Serializable;
public class DatatableCheckStatusData implements Serializable {
private final String name;
private final int code;
public DatatableCheckStatusData(final String name, final int code) {
this.name = name;
this.code = code;
}
}
@@ -1,33 +0,0 @@
/**
* 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.dataqueries.data;
import java.io.Serializable;
public class DatatableChecksData implements Serializable {
private static final long serialVersionUID = 3113568562509206452L;
private final String entity;
private final String dataTableName;
public DatatableChecksData(final String entity, final String dataTableName) {
this.entity = entity;
this.dataTableName = dataTableName;
}
}
@@ -1,50 +0,0 @@
/**
* 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.dataqueries.data;
import java.io.Serializable;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
/**
* Immutable data object for role data.
*/
public class EntityDataTableChecksData implements Serializable {
private final long id;
private final String entity;
private final EnumOptionData status;
private final String datatableName;
private final boolean systemDefined;
private final Long order;
private final Long productId;
private final String productName;
public EntityDataTableChecksData(final long id, final String entity, final EnumOptionData status, final String datatableName,
final boolean systemDefined, final Long loanProductId, final String productName) {
this.id = id;
this.entity = entity;
this.status = status;
this.datatableName = datatableName;
this.systemDefined = systemDefined;
this.order = id;
this.productId = loanProductId;
this.productName = productName;
}
}
@@ -1,140 +0,0 @@
/**
* 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.dataqueries.data;
import static org.apache.fineract.infrastructure.dataqueries.data.StatusEnum.ACTIVATE;
import static org.apache.fineract.infrastructure.dataqueries.data.StatusEnum.APPROVE;
import static org.apache.fineract.infrastructure.dataqueries.data.StatusEnum.CLOSE;
import static org.apache.fineract.infrastructure.dataqueries.data.StatusEnum.CREATE;
import static org.apache.fineract.infrastructure.dataqueries.data.StatusEnum.DISBURSE;
import static org.apache.fineract.infrastructure.dataqueries.data.StatusEnum.REJECTED;
import static org.apache.fineract.infrastructure.dataqueries.data.StatusEnum.WITHDRAWN;
import static org.apache.fineract.infrastructure.dataqueries.data.StatusEnum.WRITE_OFF;
import com.google.common.collect.ImmutableList;
import jakarta.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public enum EntityTables {
CLIENT("m_client", "client_id", "id", CREATE, ACTIVATE, CLOSE), //
GROUP("m_group", "group_id", "id", CREATE, ACTIVATE, CLOSE), //
CENTER("m_center", "m_group", "center_id", "id"), //
OFFICE("m_office", "office_id", "id"), //
LOAN_PRODUCT("m_product_loan", "product_loan_id", "id"), //
LOAN("m_loan", "loan_id", "id", CREATE, APPROVE, DISBURSE, WITHDRAWN, REJECTED, WRITE_OFF), //
SAVINGS_PRODUCT("m_savings_product", "savings_product_id", "id"), //
SAVINGS("m_savings_account", "savings_account_id", "id", CREATE, APPROVE, ACTIVATE, WITHDRAWN, REJECTED, CLOSE), //
SAVINGS_TRANSACTION("m_savings_account_transaction", "savings_transaction_id", "id"), //
SHARE_PRODUCT("m_share_product", "share_product_id", "id"), //
;
public static final EntityTables[] VALUES = values();
private static final List<String> ENTITY_NAMES = Arrays.stream(VALUES).map(EntityTables::getName).toList();
private static final Map<String, EntityTables> BY_ENTITY_NAME = Arrays.stream(VALUES)
.collect(Collectors.toMap(EntityTables::getName, e -> e));
@NotNull
private final String name;
@NotNull
private final String apptableName;
@NotNull
private final String foreignKeyColumnNameOnDatatable;
@NotNull
private final String refColumn; // referenced column name on apptable
private final ImmutableList<StatusEnum> checkStatuses;
EntityTables(@NotNull String name, @NotNull String apptableName, @NotNull String foreignKeyColumnNameOnDatatable,
@NotNull String refColumn, StatusEnum... statuses) {
this.name = name;
this.apptableName = apptableName;
this.foreignKeyColumnNameOnDatatable = foreignKeyColumnNameOnDatatable;
this.refColumn = refColumn;
this.checkStatuses = statuses == null ? ImmutableList.of() : ImmutableList.copyOf(statuses);
}
EntityTables(@NotNull String name, @NotNull String foreignKeyColumnNameOnDatatable, @NotNull String refColumn, StatusEnum... statuses) {
this(name, name, foreignKeyColumnNameOnDatatable, refColumn, statuses);
}
@NotNull
public String getName() {
return name;
}
@NotNull
public String getApptableName() {
return apptableName;
}
@NotNull
public String getForeignKeyColumnNameOnDatatable() {
return this.foreignKeyColumnNameOnDatatable;
}
@NotNull
public String getRefColumn() {
return refColumn;
}
public List<StatusEnum> getCheckStatuses() {
return checkStatuses;
}
public boolean hasCheck() {
return checkStatuses != null && !checkStatuses.isEmpty();
}
public static List<String> getEntityNames() {
return ENTITY_NAMES;
}
public static EntityTables fromEntityName(String name) {
return name == null ? null : BY_ENTITY_NAME.get(name.toLowerCase());
}
public static String getForeignKeyColumnNameOnDatatable(String name) {
EntityTables entityTable = fromEntityName(name);
return entityTable == null ? null : entityTable.getForeignKeyColumnNameOnDatatable();
}
@NotNull
public static List<StatusEnum> getCheckStatuses(String name) {
EntityTables entityTable = fromEntityName(name);
return entityTable == null ? List.of() : entityTable.getCheckStatuses();
}
@NotNull
public static List<Integer> getCheckStatusCodes(String name) {
return getCheckStatuses(name).stream().map(StatusEnum::getCode).toList();
}
@NotNull
public static List<EntityTables> getFiltered(Predicate<EntityTables> filter) {
return Arrays.stream(VALUES).filter(filter).toList();
}
}
@@ -1,65 +0,0 @@
/**
* 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.dataqueries.data;
import java.util.List;
import org.apache.fineract.infrastructure.core.service.database.JdbcJavaType;
/**
* Immutable data object for generic resultset data.
*/
public final class GenericResultsetData {
private final List<ResultsetColumnHeaderData> columnHeaders;
private final List<ResultsetRowData> data;
public GenericResultsetData(final List<ResultsetColumnHeaderData> columnHeaders, final List<ResultsetRowData> resultsetDataRows) {
this.columnHeaders = columnHeaders;
this.data = resultsetDataRows;
}
public List<ResultsetColumnHeaderData> getColumnHeaders() {
return this.columnHeaders;
}
public List<ResultsetRowData> getData() {
return this.data;
}
public JdbcJavaType getColTypeOfColumnNamed(final String columnName) {
for (final ResultsetColumnHeaderData columnHeader : this.columnHeaders) {
if (columnHeader.isNamed(columnName)) {
return columnHeader.getColumnType();
}
}
return null;
}
public boolean hasNoEntries() {
return this.data.isEmpty();
}
public boolean hasEntries() {
return !hasNoEntries();
}
public boolean hasMoreThanOneEntry() {
return this.data.size() > 1;
}
}
@@ -1,104 +0,0 @@
/**
* 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.dataqueries.data;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class ReportData {
@SuppressWarnings("unused")
private final Long id;
@SuppressWarnings("unused")
private final String reportName;
@SuppressWarnings("unused")
private final String reportType;
@SuppressWarnings("unused")
private final String reportSubType;
@SuppressWarnings("unused")
private final String reportCategory;
@SuppressWarnings("unused")
private final String description;
@SuppressWarnings("unused")
private final String reportSql;
@SuppressWarnings("unused")
private final Boolean coreReport;
@SuppressWarnings("unused")
private final Boolean useReport;
@SuppressWarnings("unused")
private final Collection<ReportParameterData> reportParameters;
@SuppressWarnings("unused")
private List<String> allowedReportTypes;
@SuppressWarnings("unused")
private List<String> allowedReportSubTypes;
@SuppressWarnings("unused")
private Collection<ReportParameterData> allowedParameters;
public ReportData(final Long id, final String reportName, final String reportType, final String reportSubType,
final String reportCategory, final String description, final String reportSql, final Boolean coreReport,
final Boolean useReport, final Collection<ReportParameterData> reportParameters) {
this.id = id;
this.reportName = reportName;
this.reportType = reportType;
this.reportSubType = reportSubType;
this.reportCategory = reportCategory;
this.description = description;
this.reportParameters = reportParameters;
this.reportSql = reportSql;
this.coreReport = coreReport;
this.useReport = useReport;
this.allowedReportTypes = null;
this.allowedReportSubTypes = null;
this.allowedParameters = null;
}
public ReportData() {
this.id = null;
this.reportName = null;
this.reportType = null;
this.reportSubType = null;
this.reportCategory = null;
this.description = null;
this.reportParameters = null;
this.reportSql = null;
this.coreReport = null;
this.useReport = null;
this.allowedReportTypes = null;
this.allowedReportSubTypes = null;
this.allowedParameters = null;
}
public void appendedTemplate(final Collection<ReportParameterData> allowedParameters, final Collection<String> allowedReportTypes) {
final List<String> reportTypes = new ArrayList<>();
reportTypes.addAll(allowedReportTypes);
this.allowedReportTypes = reportTypes;
final List<String> reportSubTypes = new ArrayList<>();
reportSubTypes.add("Bar");
reportSubTypes.add("Pie");
this.allowedReportSubTypes = reportSubTypes;
this.allowedParameters = allowedParameters;
}
}
@@ -1,31 +0,0 @@
/**
* 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.dataqueries.data;
import java.io.Serializable;
import lombok.Data;
import lombok.RequiredArgsConstructor;
@Data
@RequiredArgsConstructor
public class ReportExportType implements Serializable {
private final String key;
private final String queryParameter;
}
@@ -1,39 +0,0 @@
/**
* 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.dataqueries.data;
/* used to show list of parameters used by a report and also for getting a list of parameters available (the reportParameterName is left null */
public final class ReportParameterData {
@SuppressWarnings("unused")
private final Long id;
@SuppressWarnings("unused")
private final Long parameterId;
@SuppressWarnings("unused")
private final String parameterName;
@SuppressWarnings("unused")
private final String reportParameterName;
public ReportParameterData(final Long id, final Long parameterId, final String reportParameterName, final String parameterName) {
this.id = id;
this.parameterId = parameterId;
this.parameterName = parameterName;
this.reportParameterName = reportParameterName;
}
}
@@ -1,108 +0,0 @@
/**
* 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.dataqueries.data;
public final class ReportParameterJoinData {
private final Long reportId;
private final String reportName;
private final String reportType;
private final String reportSubType;
private final String reportCategory;
private final String description;
private final String reportSql;
private final Boolean coreReport;
private final Boolean useReport;
private final Long reportParameterId;
private final Long parameterId;
private final String reportParameterName;
private final String parameterName;
public ReportParameterJoinData(final Long reportId, final String reportName, final String reportType, final String reportSubType,
final String reportCategory, final String description, final String reportSql, final Boolean coreReport,
final Boolean useReport, final Long reportParameterId, final Long parameterId, final String reportParameterName,
final String parameterName) {
this.reportId = reportId;
this.reportName = reportName;
this.reportType = reportType;
this.reportSubType = reportSubType;
this.reportCategory = reportCategory;
this.description = description;
this.reportSql = reportSql;
this.coreReport = coreReport;
this.useReport = useReport;
this.reportParameterId = reportParameterId;
this.parameterId = parameterId;
this.reportParameterName = reportParameterName;
this.parameterName = parameterName;
}
public Long getReportId() {
return this.reportId;
}
public String getReportName() {
return this.reportName;
}
public String getReportType() {
return this.reportType;
}
public String getReportSubType() {
return this.reportSubType;
}
public String getReportCategory() {
return this.reportCategory;
}
public String getReportSql() {
return this.reportSql;
}
public Boolean getCoreReport() {
return this.coreReport;
}
public Boolean getUseReport() {
return this.useReport;
}
public Long getReportParameterId() {
return this.reportParameterId;
}
public Long getParameterId() {
return this.parameterId;
}
public String getReportParameterName() {
return this.reportParameterName;
}
public String getParameterName() {
return this.parameterName;
}
public String getDescription() {
return this.description;
}
}
@@ -1,38 +0,0 @@
/**
* 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.dataqueries.data;
import java.util.List;
public final class ResultsetRowData {
private final List<Object> row;
public static ResultsetRowData create(final List<Object> rowValues) {
return new ResultsetRowData(rowValues);
}
private ResultsetRowData(final List<Object> rowValues) {
this.row = rowValues;
}
public List<Object> getRow() {
return this.row;
}
}
@@ -1,105 +0,0 @@
/**
* 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.dataqueries.data;
import java.util.ArrayList;
import java.util.List;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
public enum StatusEnum {
CREATE("create", 100), APPROVE("approve", 200), ACTIVATE("activate", 300), WITHDRAWN("withdraw", 400), REJECTED("reject", 500), CLOSE(
"close", 600), WRITE_OFF("write off", 601), RESCHEDULE("reschedule", 602), OVERPAY("overpay", 700), DISBURSE("disburse", 800);
private final String name;
private final Integer code;
public Integer getCode() {
return code;
}
StatusEnum(String name, Integer code) {
this.name = name;
this.code = code;
}
public static List<DatatableCheckStatusData> getStatusList() {
List<DatatableCheckStatusData> data = new ArrayList<DatatableCheckStatusData>();
for (StatusEnum status : StatusEnum.values()) {
data.add(new DatatableCheckStatusData(status.name, status.code));
}
return data;
}
public static StatusEnum fromInt(final Integer code) {
StatusEnum ret = null;
switch (code) {
case 100:
ret = StatusEnum.CREATE;
break;
case 200:
ret = StatusEnum.APPROVE;
break;
case 300:
ret = StatusEnum.ACTIVATE;
break;
case 400:
ret = StatusEnum.WITHDRAWN;
break;
case 500:
ret = StatusEnum.REJECTED;
break;
case 600:
ret = StatusEnum.CLOSE;
break;
case 601:
ret = StatusEnum.WRITE_OFF;
break;
case 602:
ret = StatusEnum.RESCHEDULE;
break;
case 700:
ret = StatusEnum.OVERPAY;
break;
case 800:
ret = StatusEnum.DISBURSE;
break;
default:
break;
}
return ret;
}
public static EnumOptionData statusTypeEnum(final Integer id) {
return statusType(StatusEnum.fromInt(id));
}
public static EnumOptionData statusType(final StatusEnum statusType) {
final EnumOptionData optionData = new EnumOptionData(statusType.getCode().longValue(), statusType.name(), statusType.name());
return optionData;
}
}
@@ -1,43 +0,0 @@
/**
* 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.dataqueries.service;
import java.util.List;
import org.apache.fineract.infrastructure.dataqueries.data.GenericResultsetData;
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetRowData;
public interface GenericDataService {
GenericResultsetData fillGenericResultSet(String sql);
List<ResultsetColumnHeaderData> fillResultsetColumnHeaders(String tableName);
List<ResultsetRowData> fillResultsetRowData(String sql, List<ResultsetColumnHeaderData> columnHeaders);
String generateJsonFromGenericResultsetData(GenericResultsetData grs);
String replace(String str, String pattern, String replace);
String wrapSQL(String sql);
boolean isExplicitlyUnique(String tableName, String columnName);
boolean isExplicitlyIndexed(String tableName, String columnName);
}
@@ -1,89 +0,0 @@
/**
* 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.dataqueries.service;
import com.google.gson.JsonObject;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Locale;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.service.PagedLocalRequest;
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
import org.apache.fineract.infrastructure.dataqueries.data.GenericResultsetData;
import org.apache.fineract.portfolio.search.data.AdvancedQueryData;
import org.springframework.data.domain.Page;
import org.springframework.security.access.prepost.PreAuthorize;
public interface ReadWriteNonCoreDataService {
List<DatatableData> retrieveDatatableNames(String appTable);
DatatableData retrieveDatatable(String datatable);
@PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'REGISTER_DATATABLE')")
void registerDatatable(JsonCommand command);
@PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'REGISTER_DATATABLE')")
void registerDatatable(String dataTableName, String applicationTableName, String entitySubType);
@PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'REGISTER_DATATABLE')")
void registerDatatable(JsonCommand command, String permissionTable);
@PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'DEREGISTER_DATATABLE')")
void deregisterDatatable(String datatable);
GenericResultsetData retrieveDataTableGenericResultSet(String datatable, Long appTableId, String order, Long id);
CommandProcessingResult createDatatable(JsonCommand command);
void updateDatatable(String datatableName, JsonCommand command);
void deleteDatatable(String datatableName);
CommandProcessingResult createNewDatatableEntry(String datatable, Long appTableId, JsonCommand command);
CommandProcessingResult createNewDatatableEntry(String datatable, Long appTableId, String json);
CommandProcessingResult createPPIEntry(String datatable, Long appTableId, JsonCommand command);
CommandProcessingResult updateDatatableEntryOneToOne(String datatable, Long appTableId, JsonCommand command);
CommandProcessingResult updateDatatableEntryOneToMany(String datatable, Long appTableId, Long datatableId, JsonCommand command);
CommandProcessingResult deleteDatatableEntries(String datatable, Long appTableId, JsonCommand command);
CommandProcessingResult deleteDatatableEntry(String datatable, Long appTableId, Long datatableId, JsonCommand command);
String getTableName(String Url);
String getDataTableName(String Url);
Long countDatatableEntries(String datatableName, Long appTableId, String foreignKeyColumn);
List<JsonObject> queryDataTable(@NotNull String datatable, @NotNull String columnName, String columnValue,
@NotNull String resultColumns);
Page<JsonObject> queryDataTableAdvanced(@NotNull String datatable, @NotNull PagedLocalRequest<AdvancedQueryData> pagedRequest);
boolean buildDataQueryEmbedded(@NotNull EntityTables entityTable, @NotNull String datatable, @NotNull AdvancedQueryData request,
@NotNull List<String> selectColumns, @NotNull StringBuilder select, @NotNull StringBuilder from, @NotNull StringBuilder where,
@NotNull List<Object> params, String mainAlias, String alias, String dateFormat, String dateTimeFormat, Locale locale);
}
@@ -1,142 +0,0 @@
/**
* 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.interoperation.data;
import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.interoperation.domain.InteropIdentifier;
import org.apache.fineract.portfolio.accountdetails.domain.AccountType;
import org.apache.fineract.portfolio.savings.DepositAccountType;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountStatusType;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountSubStatusEnum;
import org.apache.fineract.portfolio.savings.domain.SavingsProduct;
public class InteropAccountData extends CommandProcessingResult {
@NotNull
private final String accountId;
@NotNull
private final String savingProductId;
@NotNull
private final String productName;
@NotNull
private final String shortProductName;
@NotNull
private final String currency;
@NotNull
private final BigDecimal accountBalance;
@NotNull
private final BigDecimal availableBalance;
@NotNull
private final SavingsAccountStatusType status;
private final SavingsAccountSubStatusEnum subStatus;
private final AccountType accountType; // differentiate Individual, JLG or
// Group account
private final DepositAccountType depositType; // differentiate deposit
// accounts Savings, FD and RD
// accounts
@NotNull
private final LocalDate activatedOn;
private final LocalDate statusUpdateOn;
private final LocalDate withdrawnOn;
private final LocalDate balanceOn;
@NotNull
private List<InteropIdentifierData> identifiers;
InteropAccountData(Long resourceId, Long officeId, Long commandId, Map<String, Object> changesOnly, String accountId, String productId,
String productName, String shortProductName, String currency, BigDecimal accountBalance, BigDecimal availableBalance,
SavingsAccountStatusType status, SavingsAccountSubStatusEnum subStatus, AccountType accountType, DepositAccountType depositType,
LocalDate activatedOn, LocalDate statusUpdateOn, LocalDate withdrawnOn, LocalDate balanceOn,
List<InteropIdentifierData> identifiers, long clientId) {
super(resourceId, officeId, commandId, changesOnly, clientId);
this.accountId = accountId;
this.savingProductId = productId;
this.productName = productName;
this.shortProductName = shortProductName;
this.currency = currency;
this.accountBalance = accountBalance;
this.availableBalance = availableBalance;
this.status = status;
this.subStatus = subStatus;
this.accountType = accountType;
this.depositType = depositType;
this.activatedOn = activatedOn;
this.statusUpdateOn = statusUpdateOn;
this.withdrawnOn = withdrawnOn;
this.balanceOn = balanceOn;
this.identifiers = identifiers;
}
InteropAccountData(String accountId, String productId, String productName, String shortProductName, String currency,
BigDecimal accountBalance, BigDecimal availableBalance, SavingsAccountStatusType status, SavingsAccountSubStatusEnum subStatus,
AccountType accountType, DepositAccountType depositType, LocalDate activatedOn, LocalDate statusUpdateOn, LocalDate withdrawnOn,
LocalDate balanceOn, List<InteropIdentifierData> identifiers, long clientId) {
this(null, null, null, null, accountId, productId, productName, shortProductName, currency, accountBalance, availableBalance,
status, subStatus, accountType, depositType, activatedOn, statusUpdateOn, withdrawnOn, balanceOn, identifiers, clientId);
}
public static InteropAccountData build(SavingsAccount account) {
if (account == null) {
return null;
}
List<InteropIdentifierData> ids = new ArrayList<>();
for (InteropIdentifier identifier : account.getIdentifiers()) {
ids.add(InteropIdentifierData.build(identifier));
}
SavingsProduct product = account.savingsProduct();
SavingsAccountSubStatusEnum subStatus = SavingsAccountSubStatusEnum.fromInt(account.getSubStatus());
return new InteropAccountData(account.getExternalId().getValue(), product.getId().toString(), product.getName(),
product.getShortName(), account.getCurrency().getCode(), account.getAccountBalance(), account.getWithdrawableBalance(),
account.getStatus(), subStatus, account.getAccountType(), account.depositAccountType(), account.getActivationDate(),
calcStatusUpdateOn(account), account.getWithdrawnOnDate(), account.retrieveLastTransactionDate(), ids,
account.getClient().getId());
}
private static LocalDate calcStatusUpdateOn(@NotNull SavingsAccount account) {
if (account.getClosedOnDate() != null) {
return account.getClosedOnDate();
}
if (account.getWithdrawnOnDate() != null) {
return account.getWithdrawnOnDate();
}
if (account.getActivationDate() != null) {
return account.getActivationDate();
}
if (account.getRejectedOnDate() != null) {
return account.getRejectedOnDate();
}
if (account.getApprovedOnDate() != null) {
return account.getApprovedOnDate();
}
if (account.getSubmittedOnDate() != null) {
return account.getSubmittedOnDate();
}
return null;
}
}
@@ -1,60 +0,0 @@
/**
* 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.interoperation.data;
import jakarta.validation.constraints.NotNull;
import org.apache.fineract.interoperation.domain.InteropIdentifier;
import org.apache.fineract.interoperation.domain.InteropIdentifierType;
public class InteropIdentifierData {
@NotNull
private final InteropIdentifierType idType;
@NotNull
private final String idValue;
private final String subIdOrType;
public InteropIdentifierData(@NotNull InteropIdentifierType idType, @NotNull String idValue, String subIdOrType) {
this.idType = idType;
this.idValue = idValue;
this.subIdOrType = subIdOrType;
}
protected InteropIdentifierData(@NotNull InteropIdentifierType idType, @NotNull String idValue) {
this(idType, idValue, null);
}
public InteropIdentifierType getIdType() {
return idType;
}
public String getIdValue() {
return idValue;
}
public String getSubIdOrType() {
return subIdOrType;
}
public static InteropIdentifierData build(InteropIdentifier identifier) {
return new InteropIdentifierData(identifier.getType(), identifier.getValue(), identifier.getSubType());
}
}
@@ -21,41 +21,18 @@ package org.apache.fineract.interoperation.data;
import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDate;
import lombok.Getter;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.service.MathUtil;
import org.apache.fineract.portfolio.note.domain.Note;
import org.apache.fineract.portfolio.savings.SavingsAccountTransactionType;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountChargePaidBy;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
import org.apache.fineract.portfolio.savings.service.SavingsEnumerations;
@Getter
public class InteropTransactionData extends CommandProcessingResult {
// private final SavingsAccountTransactionEnumData transactionType;
// private final PaymentDetailData paymentDetailData;
// private final BigDecimal outstandingChargeAmount;
// private final boolean reversed;
// private final AccountTransferData transfer;
// private final LocalDate submittedOnDate;
// private final boolean interestedPostedAsOn;
// private final String submittedByUsername;
// // templates
// final Collection<PaymentTypeData> paymentTypeOptions;
// //import fields
// private Long paymentTypeId;
// private String checkNumber;
// private String routingCode;
// private String receiptNumber;
// private String bankNumber;
// private String transactionReference;
// private String statementReference;
// private CreditDebitType creditDebit;
// private TransactionStatus status;
// private String transactionInformation;
// private String addressLine;
@NotNull
private final String accountId;
@NotNull
@@ -75,7 +52,7 @@ public class InteropTransactionData extends CommandProcessingResult {
@NotNull
private final LocalDate valueDateTime;
private final String note;
private String note;
public InteropTransactionData(Long entityId, String accountId, String transactionId, SavingsAccountTransactionType transactionType,
BigDecimal amount, BigDecimal chargeAmount, String currency, BigDecimal accountBalance, LocalDate bookingDateTime,
@@ -117,33 +94,14 @@ public class InteropTransactionData extends CommandProcessingResult {
LocalDate valueDateTime = endOfBalanceLocalDate == null ? bookingDateTime : endOfBalanceLocalDate;
StringBuilder sb = new StringBuilder();
int currLength = 0;
for (Note note : transaction.getNotes()) {
String s = note.getNote();
if (s == null) {
continue;
}
int availableLength = 500 - currLength;
if (availableLength <= 1) {
break;
}
if (currLength > 0) {
sb.append(' ');
availableLength--;
}
if (s.length() > availableLength) {
s = s.substring(availableLength);
}
sb.append(s);
currLength = sb.length();
}
if (currLength == 0) {
sb.append(SavingsEnumerations.transactionType(transactionType).getValue());
}
sb.append(SavingsEnumerations.transactionType(transactionType).getValue());
return new InteropTransactionData(savingsAccount.getId(), savingsAccount.getExternalId().getValue(), transactionId, transactionType,
amount, chargeAmount, currency, runningBalance, bookingDateTime, valueDateTime, sb.toString());
}
public void updateNote(String note) {
this.note = note;
}
}
@@ -22,11 +22,15 @@ import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lombok.Getter;
import lombok.Setter;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction;
@Getter
@Setter
public class InteropTransactionsData extends CommandProcessingResult {
List<InteropTransactionData> transactions;
@@ -1,23 +0,0 @@
/**
* 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.interoperation.domain;
public enum InteropActionState {
ACCEPTED, REJECTED
}
@@ -1,23 +0,0 @@
/**
* 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.interoperation.domain;
public enum InteropAmountType {
SEND, RECEIVE
}
@@ -1,162 +0,0 @@
/**
* 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.interoperation.domain;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.Objects;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
@Entity
@Table(name = "interop_identifier", uniqueConstraints = {
@UniqueConstraint(name = "uk_hathor_identifier_account", columnNames = { "account_id", "type" }),
@UniqueConstraint(name = "uk_hathor_identifier_value", columnNames = { "type", "a_value", "sub_value_or_type" }) })
public class InteropIdentifier extends AbstractPersistableCustom {
@ManyToOne(optional = false)
@JoinColumn(name = "account_id", nullable = false)
private SavingsAccount account;
@Column(name = "type", nullable = false, length = 32)
@Enumerated(EnumType.STRING)
private InteropIdentifierType type;
@Column(name = "a_value", nullable = false, length = 128)
private String value;
@Column(name = "sub_value_or_type", length = 128)
private String subType;
@Column(name = "created_by", nullable = false, length = 32)
private String createdBy;
@Column(name = "created_on", nullable = false)
private LocalDateTime createdOn;
@Column(name = "modified_by", length = 32)
private String modifiedBy;
@Column(name = "modified_on")
private LocalDateTime modifiedOn;
protected InteropIdentifier() {}
public InteropIdentifier(@NotNull SavingsAccount account, @NotNull InteropIdentifierType type, @NotNull String value, String subType,
@NotNull String createdBy) {
this.account = account;
this.type = type;
this.value = value;
this.subType = subType;
this.createdBy = createdBy;
this.createdOn = DateUtils.getAuditLocalDateTime();
}
public InteropIdentifier(@NotNull SavingsAccount account, @NotNull InteropIdentifierType type, @NotNull String createdBy) {
this(account, type, null, null, createdBy);
}
public SavingsAccount getAccount() {
return account;
}
public InteropIdentifierType getType() {
return type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getSubType() {
return subType;
}
public void setSubType(String subType) {
this.subType = subType;
}
public String getCreatedBy() {
return createdBy;
}
public LocalDateTime getCreatedOn() {
return createdOn;
}
public String geModifiedBy() {
return modifiedBy;
}
public void setModifiedBy(String modifiedBy) {
this.modifiedBy = modifiedBy;
}
public LocalDateTime getModifiedOn() {
return modifiedOn;
}
public void setModifiedOn(LocalDateTime modifiedOn) {
this.modifiedOn = modifiedOn;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || !(o instanceof InteropIdentifier)) {
return false;
}
InteropIdentifier that = (InteropIdentifier) o;
if (!account.equals(that.account)) {
return false;
}
if (type != that.type) {
return false;
}
if (!value.equals(that.value)) {
return false;
}
return Objects.equals(subType, that.subType);
}
@Override
public int hashCode() {
int result = type.hashCode();
result = 31 * result + value.hashCode();
result = 31 * result + (subType != null ? subType.hashCode() : 0);
return result;
}
}
@@ -1,24 +0,0 @@
/**
* 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.interoperation.domain;
public enum InteropIdentifierType {
MSISDN, EMAIL, PERSONAL_ID, BUSINESS, DEVICE, ACCOUNT_ID, IBAN, ALIAS
}
@@ -1,23 +0,0 @@
/**
* 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.interoperation.domain;
public enum InteropInitiatorType {
CONSUMER, AGENT, BUSINESS, DEVICE
}
@@ -1,34 +0,0 @@
/**
* 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.interoperation.domain;
import org.apache.fineract.portfolio.savings.SavingsAccountTransactionType;
public enum InteropTransactionRole {
PAYER, PAYEE,;
public boolean isWithdraw() {
return this == PAYER;
}
public SavingsAccountTransactionType getTransactionType() {
return this == PAYER ? SavingsAccountTransactionType.WITHDRAWAL : SavingsAccountTransactionType.DEPOSIT;
}
}
@@ -1,24 +0,0 @@
/**
* 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.interoperation.domain;
public enum InteropTransactionScenario {
DEPOSIT, WITHDRAWAL, TRANSFER, PAYMENT, REFUND
}
@@ -1,24 +0,0 @@
/**
* 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.interoperation.domain;
public enum InteropTransferActionType {
PREPARE, CREATE, RELEASE;
}
@@ -64,6 +64,7 @@ import org.apache.fineract.interoperation.data.InteropKycResponseData;
import org.apache.fineract.interoperation.data.InteropQuoteRequestData;
import org.apache.fineract.interoperation.data.InteropQuoteResponseData;
import org.apache.fineract.interoperation.data.InteropRequestData;
import org.apache.fineract.interoperation.data.InteropTransactionData;
import org.apache.fineract.interoperation.data.InteropTransactionRequestData;
import org.apache.fineract.interoperation.data.InteropTransactionRequestResponseData;
import org.apache.fineract.interoperation.data.InteropTransactionsData;
@@ -218,7 +219,27 @@ public class InteropServiceImpl implements InteropService {
return (transactionsTo == null || transactionsTo.compareTo(transactionDate) > 0) && (transactionsFrom == null
|| transactionsFrom.compareTo(transactionDate.withHour(23).withMinute(59).withSecond(59)) <= 0);
};
return InteropTransactionsData.build(savingsAccount, transFilter);
InteropTransactionsData interopTransactionsData = InteropTransactionsData.build(savingsAccount, transFilter);
for (InteropTransactionData interopTransactionData : interopTransactionsData.getTransactions()) {
final List<Note> transactionNotes = noteRepository
.findBySavingsTransactionId(Long.valueOf(interopTransactionData.getTransactionId()));
StringBuilder sb = new StringBuilder();
for (final Note note : transactionNotes) {
String s = note.getNote();
if (s == null) {
continue;
}
sb.append(s + " ");
}
if (sb.toString().length() > 0) {
String text = interopTransactionData.getNote() + " " + sb.toString();
if (text.length() > 500) {
text = text.substring(0, 500);
}
interopTransactionData.updateNote(text);
}
}
return interopTransactionsData;
}
@NotNull
@@ -1,82 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.accountdetails.data;
import java.math.BigDecimal;
import java.time.LocalDate;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.portfolio.savings.data.SavingsAccountApplicationTimelineData;
import org.apache.fineract.portfolio.savings.data.SavingsAccountStatusEnumData;
import org.apache.fineract.portfolio.savings.data.SavingsAccountSubStatusEnumData;
@SuppressWarnings("unused")
public class SavingsSummaryCustom {
private final Long id;
private final String displayName;
private final String accountNo;
private final String externalId;
private final Long productId;
private final String productName;
private final String shortProductName;
private final SavingsAccountStatusEnumData status;
private final CurrencyData currency;
private final BigDecimal accountBalance;
// differentiate Individual, JLG or Group account
private final EnumOptionData accountType;
private final SavingsAccountApplicationTimelineData timeline;
private final SavingsAccountSubStatusEnumData subStatus;
private final LocalDate lastActiveTransactionDate;
// differentiate deposit accounts Savings, FD and RD accounts
private final EnumOptionData depositType;
public SavingsSummaryCustom(final Long id, final String displayName, final String accountNo, final String externalId,
final Long productId, final String productName, final String shortProductName, final SavingsAccountStatusEnumData status,
final CurrencyData currency, final BigDecimal accountBalance, final EnumOptionData accountType,
final SavingsAccountApplicationTimelineData timeline, final EnumOptionData depositType,
final SavingsAccountSubStatusEnumData subStatus, final LocalDate lastActiveTransactionDate) {
this.id = id;
this.displayName = displayName;
this.accountNo = accountNo;
this.externalId = externalId;
this.productId = productId;
this.productName = productName;
this.shortProductName = shortProductName;
this.status = status;
this.currency = currency;
this.accountBalance = accountBalance;
this.accountType = accountType;
this.timeline = timeline;
this.depositType = depositType;
this.subStatus = subStatus;
this.lastActiveTransactionDate = lastActiveTransactionDate;
}
public String getAccountNo() {
return accountNo;
}
public Long getId() {
return id;
}
}
@@ -1,30 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.charge.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class ChargeCannotBeAppliedToException extends AbstractPlatformDomainRuleException {
public ChargeCannotBeAppliedToException(final String postFix, final String defaultUserMessage, final Object... defaultUserMessageArgs) {
super("error.msg.charge.cannot.be.applied.to" + postFix, defaultUserMessage, defaultUserMessageArgs);
}
}
@@ -1,61 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.charge.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class SavingsAccountChargeCannotBeWaivedException extends AbstractPlatformDomainRuleException {
/*** enum of reasons of why Savings Account Charge cannot be waived **/
public enum SavingsAccountChargeCannotBeWaivedReason {
ALREADY_PAID, ALREADY_WAIVED, SAVINGS_ACCOUNT_NOT_ACTIVE, SAVINGS_ACCOUNT_CLOSED;
public String errorMessage() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "This savings account charge has been completely paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "This savings account charge has already been waived";
} else if (name().toString().equalsIgnoreCase("SAVINGS_ACCOUNT_NOT_ACTIVE")) {
return "This savings account charge cannot be waived as the Savings account associated with it is not active";
} else if (name().toString().equalsIgnoreCase("SAVINGS_ACCOUNT_CLOSED")) {
return "This savings account charge cannot be waived as the Savings account associated with it is closed";
}
return name().toString();
}
public String errorCode() {
if (name().toString().equalsIgnoreCase("ALREADY_PAID")) {
return "error.msg.savings.account.charge.already.paid";
} else if (name().toString().equalsIgnoreCase("ALREADY_WAIVED")) {
return "error.msg.savings.account.charge.already.waived";
} else if (name().toString().equalsIgnoreCase("SAVINGS_ACCOUNT_NOT_ACTIVE")) {
return "error.msg.savings.account.charge.associated.savings.account.not.active";
} else if (name().toString().equalsIgnoreCase("SAVINGS_ACCOUNT_CLOSED")) {
return "error.msg.savings.account.charge.associated.savings.account.closed";
}
return name().toString();
}
}
public SavingsAccountChargeCannotBeWaivedException(final SavingsAccountChargeCannotBeWaivedReason reason,
final Long savingsAccountChargeId) {
super(reason.errorCode(), reason.errorMessage(), savingsAccountChargeId);
}
}
@@ -1,43 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.charge.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
import org.springframework.dao.EmptyResultDataAccessException;
/**
* {@link AbstractPlatformDomainRuleException} thrown when savings account charge does not exist.
*/
public class SavingsAccountChargeNotFoundException extends AbstractPlatformResourceNotFoundException {
public SavingsAccountChargeNotFoundException(final Long id) {
super("error.msg.savings.account.charge.id.invalid", "Savings Account charge with identifier " + id + " does not exist", id);
}
public SavingsAccountChargeNotFoundException(final Long id, final Long savingsAccountId) {
super("error.msg.savings.account.charge.id.invalid.for.given.savings.account",
"Savings Account charge with identifier " + id + " does not exist for Savings Account " + savingsAccountId, id,
savingsAccountId);
}
public SavingsAccountChargeNotFoundException(Long id, EmptyResultDataAccessException e) {
super("error.msg.savings.account.charge.id.invalid", "Savings Account charge with identifier " + id + " does not exist", id, e);
}
}
@@ -1,33 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.charge.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* {@link AbstractPlatformDomainRuleException} thrown when currency mismatch occurs
*/
public class SavingsAccountChargeWithoutMandatoryFieldException extends AbstractPlatformDomainRuleException {
public SavingsAccountChargeWithoutMandatoryFieldException(final String entity, final String postFix, final String defaultUserMessage,
final Object... defaultUserMessageArgs) {
super("error.msg." + entity + "." + postFix + ".cannot.be.blank", defaultUserMessage, defaultUserMessageArgs);
}
}
@@ -1,52 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.collectionsheet;
public final class CollectionSheetConstants {
private CollectionSheetConstants() {
}
public static final String COLLECTIONSHEET_RESOURCE_NAME = "collectionsheet";
public static final String localeParamName = "locale";
public static final String dateFormatParamName = "dateFormat";
public static final String transactionDateParamName = "transactionDate";
public static final String actualDisbursementDateParamName = "actualDisbursementDate";
public static final String bulkRepaymentTransactionsParamName = "bulkRepaymentTransactions";
public static final String bulkDisbursementTransactionsParamName = "bulkDisbursementTransactions";
public static final String bulkSavingsDueTransactionsParamName = "bulkSavingsDueTransactions";
public static final String noteParamName = "note";
public static final String calendarIdParamName = "calendarId";
public static final String officeIdParamName = "officeId";
public static final String staffIdParamName = "staffId";
public static final String isTransactionDateOnNonMeetingDateParamName = "isTransactionDateOnNonMeetingDate";
// attendance parameters
public static final String clientsAttendanceParamName = "clientsAttendance";
public static final String clientIdParamName = "clientId";
public static final String attendanceTypeParamName = "attendanceType";
public static final String loanIdParamName = "loanId";
public static final String savingsIdParamName = "savingsId";
public static final String transactionAmountParamName = "transactionAmount";
public static final String depositAccountTypeParamName = "depositAccountType";
}
@@ -1,81 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.common.domain;
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;
public static ConditionType fromInt(final Integer v) {
if (v == null) {
return INVALID;
}
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) {
this.value = value;
this.code = code;
}
@Override
public String toString() {
return name().toString().replace("_", " ");
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return this.code;
}
// 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() {
return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
}
}
@@ -1,170 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.common.service;
import java.util.ArrayList;
import java.util.List;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.portfolio.common.domain.ConditionType;
import org.apache.fineract.portfolio.common.domain.DaysInMonthType;
import org.apache.fineract.portfolio.common.domain.DaysInYearType;
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
public final class CommonEnumerations {
private CommonEnumerations() {
}
public static final String DAYS_IN_MONTH_TYPE = "daysInMonthType";
public static final String DAYS_IN_YEAR_TYPE = "daysInYearType";
public static EnumOptionData commonEnumueration(final String typeName, final int id) {
EnumOptionData enumData = null;
if (typeName.equals(DAYS_IN_MONTH_TYPE)) {
enumData = daysInMonthType(id);
} else if (typeName.equals(DAYS_IN_YEAR_TYPE)) {
enumData = daysInYearType(id);
}
return enumData;
}
public static EnumOptionData termFrequencyType(final int id, final String codePrefix) {
return termFrequencyType(PeriodFrequencyType.fromInt(id), codePrefix);
}
public static EnumOptionData termFrequencyType(final PeriodFrequencyType type, final String codePrefix) {
EnumOptionData optionData = null;
switch (type) {
case DAYS:
optionData = new EnumOptionData(PeriodFrequencyType.DAYS.getValue().longValue(),
codePrefix + PeriodFrequencyType.DAYS.getCode(), "Days");
break;
case WEEKS:
optionData = new EnumOptionData(PeriodFrequencyType.WEEKS.getValue().longValue(),
codePrefix + PeriodFrequencyType.WEEKS.getCode(), "Weeks");
break;
case MONTHS:
optionData = new EnumOptionData(PeriodFrequencyType.MONTHS.getValue().longValue(),
codePrefix + PeriodFrequencyType.MONTHS.getCode(), "Months");
break;
case YEARS:
optionData = new EnumOptionData(PeriodFrequencyType.YEARS.getValue().longValue(),
codePrefix + PeriodFrequencyType.YEARS.getCode(), "Years");
break;
default:
optionData = new EnumOptionData(PeriodFrequencyType.INVALID.getValue().longValue(), PeriodFrequencyType.INVALID.getCode(),
"Invalid");
break;
}
return optionData;
}
public static EnumOptionData conditionType(final int id, final String codePrefix) {
return conditionType(ConditionType.fromInt(id), codePrefix);
}
public static EnumOptionData conditionType(final ConditionType type, final String codePrefix) {
EnumOptionData optionData = null;
switch (type) {
case EQUAL:
optionData = new EnumOptionData(ConditionType.EQUAL.getValue().longValue(), codePrefix + ConditionType.EQUAL.getCode(),
"equal");
break;
case NOT_EQUAL:
optionData = new EnumOptionData(ConditionType.NOT_EQUAL.getValue().longValue(),
codePrefix + ConditionType.NOT_EQUAL.getCode(), "notEqual");
break;
case GRETERTHAN:
optionData = new EnumOptionData(ConditionType.GRETERTHAN.getValue().longValue(),
codePrefix + ConditionType.GRETERTHAN.getCode(), "greterthan");
break;
case LESSTHAN:
optionData = new EnumOptionData(ConditionType.LESSTHAN.getValue().longValue(),
codePrefix + ConditionType.LESSTHAN.getCode(), "lessthan");
break;
default:
optionData = new EnumOptionData(ConditionType.INVALID.getValue().longValue(), ConditionType.INVALID.getCode(), "Invalid");
break;
}
return optionData;
}
public static List<EnumOptionData> conditionType(final ConditionType[] conditionTypes, final String codePrefix) {
final List<EnumOptionData> optionDatas = new ArrayList<>();
for (final ConditionType conditionType : conditionTypes) {
if (!conditionType.isInvalid()) {
optionDatas.add(conditionType(conditionType, codePrefix));
}
}
return optionDatas;
}
public static EnumOptionData daysInMonthType(final int id) {
return daysInMonthType(DaysInMonthType.fromInt(id));
}
public static EnumOptionData daysInMonthType(final DaysInMonthType type) {
EnumOptionData optionData = null;
switch (type) {
case ACTUAL:
optionData = new EnumOptionData(DaysInMonthType.ACTUAL.getValue().longValue(), DaysInMonthType.ACTUAL.getCode(), "Actual");
break;
case DAYS_30:
optionData = new EnumOptionData(DaysInMonthType.DAYS_30.getValue().longValue(), DaysInMonthType.DAYS_30.getCode(),
"30 Days");
break;
default:
optionData = new EnumOptionData(DaysInMonthType.INVALID.getValue().longValue(), DaysInMonthType.INVALID.getCode(),
"Invalid");
break;
}
return optionData;
}
public static EnumOptionData daysInYearType(final int id) {
return daysInYearType(DaysInYearType.fromInt(id));
}
public static EnumOptionData daysInYearType(final DaysInYearType type) {
EnumOptionData optionData = null;
switch (type) {
case ACTUAL:
optionData = new EnumOptionData(DaysInYearType.ACTUAL.getValue().longValue(), DaysInYearType.ACTUAL.getCode(), "Actual");
break;
case DAYS_360:
optionData = new EnumOptionData(DaysInYearType.DAYS_360.getValue().longValue(), DaysInYearType.DAYS_360.getCode(),
"360 Days");
break;
case DAYS_364:
optionData = new EnumOptionData(DaysInYearType.DAYS_364.getValue().longValue(), DaysInYearType.DAYS_364.getCode(),
"364 Days");
break;
case DAYS_365:
optionData = new EnumOptionData(DaysInYearType.DAYS_365.getValue().longValue(), DaysInYearType.DAYS_365.getCode(),
"365 Days");
break;
default:
optionData = new EnumOptionData(DaysInYearType.INVALID.getValue().longValue(), DaysInYearType.INVALID.getCode(), "Invalid");
break;
}
return optionData;
}
}
@@ -1,41 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public interface InterestIncentiveApiConstants {
String idParamName = "id";
String entityTypeParamName = "entityType";
String attributeNameParamName = "attributeName";
String conditionTypeParamName = "conditionType";
String attributeValueParamName = "attributeValue";
String incentiveTypeparamName = "incentiveType";
String amountParamName = "amount";
String deleteParamName = "delete";
String INCENTIVE_RESOURCE_NAME = "interest.rate.incentives";
Set<String> INTERESTRATE_INCENTIVE_RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList(idParamName, entityTypeParamName,
attributeNameParamName, conditionTypeParamName, attributeValueParamName, incentiveTypeparamName, amountParamName));
}
@@ -1,69 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart;
public final class InterestRateChartApiConstants {
private InterestRateChartApiConstants() {
}
public static final String INTERESTRATE_CHART_RESOURCE_NAME = "interestchart";
// actions
public static final String summitalAction = ".summital";
// command
public static final String COMMAND_UNDO_TRANSACTION = "undo";
// general
public static final String localeParamName = "locale";
public static final String dateFormatParamName = "dateFormat";
// interest rate chart parameters
public static final String idParamName = "id";
public static final String nameParamName = "name";
public static final String descriptionParamName = "description";
public static final String fromDateParamName = "fromDate";
public static final String endDateParamName = "endDate";
public static final String productIdParamName = "productId";
public static final String productNameParamName = "productName";
public static final String isPrimaryGroupingByAmountParamName = "isPrimaryGroupingByAmount";
// interest rate chart Slabs parameters
// public static final String periodTypeParamName = "periodType";
// public static final String fromPeriodParamName = "fromPeriod";
// public static final String toPeriodParamName = "toPeriod";
// public static final String amountRangeFromParamName = "amountRangeFrom";
// public static final String amountRangeToParamName = "amountRangeTo";
// public static final String annualInterestRateParamName =
// "annualInterestRate";
// public static final String interestRateForFemaleParamName =
// "interestRateForFemale";
// public static final String interestRateForChildrenParamName =
// "interestRateForChildren";
// public static final String interestRateForSeniorCitizenParamName =
// "interestRateForSeniorCitizen";
// associations
public static final String chartSlabs = "chartSlabs";
// to delete chart Slabs from chart
public static final String deleteParamName = "delete";
}
@@ -1,48 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart;
public final class InterestRateChartSlabApiConstants {
private InterestRateChartSlabApiConstants() {
}
public static final String INTERESTRATE_CHART_SLAB_RESOURCE_NAME = "chartslab";
// actions
// command
// general
public static final String localeParamName = "locale";
public static final String dateFormatParamName = "dateFormat";
// interest rate chart Slabs parameters
public static final String idParamName = "id";
public static final String descriptionParamName = "description";
public static final String periodTypeParamName = "periodType";
public static final String fromPeriodParamName = "fromPeriod";
public static final String toPeriodParamName = "toPeriod";
public static final String amountRangeFromParamName = "amountRangeFrom";
public static final String amountRangeToParamName = "amountRangeTo";
public static final String annualInterestRateParamName = "annualInterestRate";
public static final String currencyCodeParamName = "currencyCode";
public static final String incentivesParamName = "incentives";
}
@@ -1,87 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.data;
import java.math.BigDecimal;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
public final class InterestIncentiveData {
@SuppressWarnings("unused")
private final Long id;
private final EnumOptionData entityType;
private final EnumOptionData attributeName;
private final EnumOptionData conditionType;
private final String attributeValue;
private final String attributeValueDesc;
private final EnumOptionData incentiveType;
private final BigDecimal amount;
public static InterestIncentiveData instance(final Long id, final EnumOptionData entityType, final EnumOptionData attributeName,
final EnumOptionData conditionType, final String attributeValue, final String attributeValueDesc,
final EnumOptionData incentiveType, final BigDecimal amount) {
return new InterestIncentiveData(id, entityType, attributeName, conditionType, attributeValue, attributeValueDesc, incentiveType,
amount);
}
private InterestIncentiveData(final Long id, final EnumOptionData entityType, final EnumOptionData attributeName,
final EnumOptionData conditionType, final String attributeValue, final String attributeValueDesc,
final EnumOptionData incentiveType, final BigDecimal amount) {
this.id = id;
this.entityType = entityType;
this.attributeName = attributeName;
this.conditionType = conditionType;
this.attributeValue = attributeValue;
this.attributeValueDesc = attributeValueDesc;
this.incentiveType = incentiveType;
this.amount = amount;
}
public EnumOptionData entityType() {
return this.entityType;
}
public EnumOptionData attributeName() {
return this.attributeName;
}
public EnumOptionData conditionType() {
return this.conditionType;
}
public String attributeValue() {
return this.attributeValue;
}
public EnumOptionData incentiveType() {
return this.incentiveType;
}
public BigDecimal amount() {
return this.amount;
}
public String attributeValueDesc() {
return this.attributeValueDesc;
}
}
@@ -1,206 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.data;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.service.DateUtils;
/**
* Immutable data object representing a InterestRateChart.
*/
public final class InterestRateChartData {
private final Long id;
private final String name;
private final String description;
private final LocalDate fromDate;
private final LocalDate endDate;
private final Long productId;
private final String productName;
private final boolean isPrimaryGroupingByAmount;
// associations
private Collection<InterestRateChartSlabData> chartSlabs;
// template
private final Collection<EnumOptionData> periodTypes;
private final Collection<EnumOptionData> entityTypeOptions;
private final Collection<EnumOptionData> attributeNameOptions;
private final Collection<EnumOptionData> conditionTypeOptions;
private final Collection<EnumOptionData> incentiveTypeOptions;
private final Collection<CodeValueData> genderOptions;
private final Collection<CodeValueData> clientTypeOptions;
private final Collection<CodeValueData> clientClassificationOptions;
public static InterestRateChartData instance(Long id, String name, String description, LocalDate fromDate, LocalDate endDate,
boolean isPrimaryGroupingByAmount, Long savingsProductId, String savingsProductName) {
Collection<EnumOptionData> periodTypes = null;
Collection<InterestRateChartSlabData> chartSlabs = null;
final Collection<EnumOptionData> entityTypeOptions = null;
final Collection<EnumOptionData> attributeNameOptions = null;
final Collection<EnumOptionData> conditionTypeOptions = null;
final Collection<EnumOptionData> incentiveTypeOptions = null;
final Collection<CodeValueData> genderOptions = null;
final Collection<CodeValueData> clientTypeOptions = null;
final Collection<CodeValueData> clientClassificationOptions = null;
return new InterestRateChartData(id, name, description, fromDate, endDate, isPrimaryGroupingByAmount, savingsProductId,
savingsProductName, chartSlabs, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions,
incentiveTypeOptions, genderOptions, clientTypeOptions, clientClassificationOptions);
}
public static InterestRateChartData withSlabs(InterestRateChartData interestRateChartData,
Collection<InterestRateChartSlabData> chartSlabs) {
return new InterestRateChartData(interestRateChartData.id, interestRateChartData.name, interestRateChartData.description,
interestRateChartData.fromDate, interestRateChartData.endDate, interestRateChartData.isPrimaryGroupingByAmount,
interestRateChartData.productId, interestRateChartData.productName, chartSlabs, interestRateChartData.periodTypes,
interestRateChartData.entityTypeOptions, interestRateChartData.attributeNameOptions,
interestRateChartData.conditionTypeOptions, interestRateChartData.incentiveTypeOptions, interestRateChartData.genderOptions,
interestRateChartData.clientTypeOptions, interestRateChartData.clientClassificationOptions);
}
public static InterestRateChartData withTemplate(InterestRateChartData interestRateChartData, Collection<EnumOptionData> periodTypes,
final Collection<EnumOptionData> entityTypeOptions, final Collection<EnumOptionData> attributeNameOptions,
final Collection<EnumOptionData> conditionTypeOptions, final Collection<EnumOptionData> incentiveTypeOptions,
final Collection<CodeValueData> genderOptions, final Collection<CodeValueData> clientTypeOptions,
final Collection<CodeValueData> clientClassificationOptions) {
return new InterestRateChartData(interestRateChartData.id, interestRateChartData.name, interestRateChartData.description,
interestRateChartData.fromDate, interestRateChartData.endDate, interestRateChartData.isPrimaryGroupingByAmount,
interestRateChartData.productId, interestRateChartData.productName, interestRateChartData.chartSlabs, periodTypes,
entityTypeOptions, attributeNameOptions, conditionTypeOptions, incentiveTypeOptions, genderOptions, clientTypeOptions,
clientClassificationOptions);
}
public static InterestRateChartData template(Collection<EnumOptionData> periodTypes, final Collection<EnumOptionData> entityTypeOptions,
final Collection<EnumOptionData> attributeNameOptions, final Collection<EnumOptionData> conditionTypeOptions,
final Collection<EnumOptionData> incentiveTypeOptions, final Collection<CodeValueData> genderOptions,
final Collection<CodeValueData> clientTypeOptions, final Collection<CodeValueData> clientClassificationOptions) {
final Long id = null;
final String name = null;
final String description = null;
final LocalDate fromDate = null;
final LocalDate endDate = null;
final boolean isPrimaryGroupingByAmount = false;
final Long savingsProductId = null;
final String savingsProductName = null;
final Collection<InterestRateChartSlabData> chartSlabs = null;
return new InterestRateChartData(id, name, description, fromDate, endDate, isPrimaryGroupingByAmount, savingsProductId,
savingsProductName, chartSlabs, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions,
incentiveTypeOptions, genderOptions, clientTypeOptions, clientClassificationOptions);
}
private InterestRateChartData(Long id, String name, String description, LocalDate fromDate, LocalDate endDate,
boolean isPrimaryGroupingByAmount, Long savingsProductId, String savingsProductName,
Collection<InterestRateChartSlabData> chartSlabs, Collection<EnumOptionData> periodTypes,
final Collection<EnumOptionData> entityTypeOptions, final Collection<EnumOptionData> attributeNameOptions,
final Collection<EnumOptionData> conditionTypeOptions, final Collection<EnumOptionData> incentiveTypeOptions,
final Collection<CodeValueData> genderOptions, final Collection<CodeValueData> clientTypeOptions,
final Collection<CodeValueData> clientClassificationOptions) {
this.id = id;
this.name = name;
this.description = description;
this.fromDate = fromDate;
this.endDate = endDate;
this.isPrimaryGroupingByAmount = isPrimaryGroupingByAmount;
this.chartSlabs = chartSlabs;
this.productId = savingsProductId;
this.productName = savingsProductName;
this.periodTypes = periodTypes;
this.attributeNameOptions = attributeNameOptions;
this.entityTypeOptions = entityTypeOptions;
this.conditionTypeOptions = conditionTypeOptions;
this.incentiveTypeOptions = incentiveTypeOptions;
this.genderOptions = genderOptions;
this.clientTypeOptions = clientTypeOptions;
this.clientClassificationOptions = clientClassificationOptions;
}
public void addChartSlab(final InterestRateChartSlabData chartSlab) {
if (this.chartSlabs == null) {
this.chartSlabs = new ArrayList<>();
}
this.chartSlabs.add(chartSlab);
}
public boolean isFromDateAfter(final LocalDate compareDate) {
return compareDate != null && DateUtils.isAfter(this.fromDate, compareDate);
}
public LocalDate endDate() {
return this.endDate;
}
public LocalDate fromDate() {
return this.fromDate;
}
public String name() {
return this.name;
}
public String description() {
return this.description;
}
public Collection<InterestRateChartSlabData> chartSlabs() {
return this.chartSlabs;
}
public Collection<EnumOptionData> periodTypes() {
return this.periodTypes;
}
public Collection<EnumOptionData> entityTypeOptions() {
return this.entityTypeOptions;
}
public Collection<EnumOptionData> attributeNameOptions() {
return this.attributeNameOptions;
}
public Collection<EnumOptionData> conditionTypeOptions() {
return this.conditionTypeOptions;
}
public Collection<EnumOptionData> incentiveTypeOptions() {
return this.incentiveTypeOptions;
}
public Collection<CodeValueData> genderOptions() {
return this.genderOptions;
}
public Collection<CodeValueData> clientTypeOptions() {
return this.clientTypeOptions;
}
public Collection<CodeValueData> clientClassificationOptions() {
return this.clientClassificationOptions;
}
public boolean isPrimaryGroupingByAmount() {
return this.isPrimaryGroupingByAmount;
}
}
@@ -1,208 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.data;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
/**
* Immutable data object representing a InterestRateChartSlab.
*/
public final class InterestRateChartSlabData {
private final Long id;
private final String description;
private final EnumOptionData periodType;
private final Integer fromPeriod;
private final Integer toPeriod;
private final BigDecimal amountRangeFrom;
private final BigDecimal amountRangeTo;
private final BigDecimal annualInterestRate;
private final CurrencyData currency;
// associations
private Set<InterestIncentiveData> incentives;
// template
private final Collection<EnumOptionData> periodTypes;
private final Collection<EnumOptionData> entityTypeOptions;
private final Collection<EnumOptionData> attributeNameOptions;
private final Collection<EnumOptionData> conditionTypeOptions;
private final Collection<EnumOptionData> incentiveTypeOptions;
private final Collection<CodeValueData> genderOptions;
private final Collection<CodeValueData> clientTypeOptions;
private final Collection<CodeValueData> clientClassificationOptions;
public static InterestRateChartSlabData instance(final Long id, final String description, final EnumOptionData periodType,
final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo,
final BigDecimal annualInterestRate, final CurrencyData currency) {
final Collection<EnumOptionData> periodTypes = null;
final Set<InterestIncentiveData> incentivesData = null;
final Collection<EnumOptionData> entityTypeOptions = null;
final Collection<EnumOptionData> attributeNameOptions = null;
final Collection<EnumOptionData> conditionTypeOptions = null;
final Collection<EnumOptionData> incentiveTypeOptions = null;
final Collection<CodeValueData> genderOptions = null;
final Collection<CodeValueData> clientTypeOptions = null;
final Collection<CodeValueData> clientClassificationOptions = null;
return new InterestRateChartSlabData(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo,
annualInterestRate, currency, incentivesData, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions,
incentiveTypeOptions, genderOptions, clientTypeOptions, clientClassificationOptions);
}
public static InterestRateChartSlabData withTemplate(final InterestRateChartSlabData chartSlab,
final Collection<EnumOptionData> periodTypes, final Collection<EnumOptionData> entityTypeOptions,
final Collection<EnumOptionData> attributeNameOptions, final Collection<EnumOptionData> conditionTypeOptions,
final Collection<EnumOptionData> incentiveTypeOptions, final Collection<CodeValueData> genderOptions,
final Collection<CodeValueData> clientTypeOptions, final Collection<CodeValueData> clientClassificationOptions) {
return new InterestRateChartSlabData(chartSlab.id, chartSlab.description, chartSlab.periodType, chartSlab.fromPeriod,
chartSlab.toPeriod, chartSlab.amountRangeFrom, chartSlab.amountRangeTo, chartSlab.annualInterestRate, chartSlab.currency,
chartSlab.incentives, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions, incentiveTypeOptions,
genderOptions, clientTypeOptions, clientClassificationOptions);
}
public static InterestRateChartSlabData template(final Collection<EnumOptionData> periodTypes,
final Collection<EnumOptionData> entityTypeOptions, final Collection<EnumOptionData> attributeNameOptions,
final Collection<EnumOptionData> conditionTypeOptions, final Collection<EnumOptionData> incentiveTypeOptions,
final Collection<CodeValueData> genderOptions, final Collection<CodeValueData> clientTypeOptions,
final Collection<CodeValueData> clientClassificationOptions) {
final Long id = null;
final String description = null;
final EnumOptionData periodType = null;
final Integer fromPeriod = null;
final Integer toPeriod = null;
final BigDecimal amountRangeFrom = null;
final BigDecimal amountRangeTo = null;
final BigDecimal annualInterestRate = null;
final CurrencyData currency = null;
final Set<InterestIncentiveData> incentivesData = null;
return new InterestRateChartSlabData(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo,
annualInterestRate, currency, incentivesData, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions,
incentiveTypeOptions, genderOptions, clientTypeOptions, clientClassificationOptions);
}
private InterestRateChartSlabData(final Long id, final String description, final EnumOptionData periodType, final Integer fromPeriod,
final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo, final BigDecimal annualInterestRate,
final CurrencyData currency, final Set<InterestIncentiveData> incentivesData, final Collection<EnumOptionData> periodTypes,
final Collection<EnumOptionData> entityTypeOptions, final Collection<EnumOptionData> attributeNameOptions,
final Collection<EnumOptionData> conditionTypeOptions, final Collection<EnumOptionData> incentiveTypeOptions,
final Collection<CodeValueData> genderOptions, final Collection<CodeValueData> clientTypeOptions,
final Collection<CodeValueData> clientClassificationOptions) {
this.id = id;
this.description = description;
this.periodType = periodType;
this.fromPeriod = fromPeriod;
this.toPeriod = toPeriod;
this.amountRangeFrom = amountRangeFrom;
this.amountRangeTo = amountRangeTo;
this.annualInterestRate = annualInterestRate;
this.currency = currency;
this.periodTypes = periodTypes;
this.incentives = incentivesData;
this.attributeNameOptions = attributeNameOptions;
this.entityTypeOptions = entityTypeOptions;
this.conditionTypeOptions = conditionTypeOptions;
this.incentiveTypeOptions = incentiveTypeOptions;
this.genderOptions = genderOptions;
this.clientTypeOptions = clientTypeOptions;
this.clientClassificationOptions = clientClassificationOptions;
}
public String description() {
return this.description;
}
public EnumOptionData periodType() {
return this.periodType;
}
public Integer fromPeriod() {
return this.fromPeriod;
}
public Integer toPeriod() {
return this.toPeriod;
}
public BigDecimal amountRangeFrom() {
return this.amountRangeFrom;
}
public BigDecimal amountRangeTo() {
return this.amountRangeTo;
}
public BigDecimal annualInterestRate() {
return this.annualInterestRate;
}
public CurrencyData currency() {
return this.currency;
}
public Collection<EnumOptionData> periodTypes() {
return this.periodTypes;
}
public void addIncentives(final InterestIncentiveData incentiveData) {
if (this.incentives == null) {
this.incentives = new HashSet<>();
}
this.incentives.add(incentiveData);
}
public Set<InterestIncentiveData> incentives() {
return this.incentives;
}
public Collection<EnumOptionData> entityTypeOptions() {
return this.entityTypeOptions;
}
public Collection<EnumOptionData> attributeNameOptions() {
return this.attributeNameOptions;
}
public Collection<EnumOptionData> conditionTypeOptions() {
return this.conditionTypeOptions;
}
public Collection<EnumOptionData> incentiveTypeOptions() {
return this.incentiveTypeOptions;
}
public Collection<CodeValueData> genderOptions() {
return this.genderOptions;
}
public Collection<CodeValueData> clientTypeOptions() {
return this.clientTypeOptions;
}
public Collection<CodeValueData> clientClassificationOptions() {
return this.clientClassificationOptions;
}
}
@@ -1,78 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.domain;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.util.Locale;
import java.util.Map;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
@Entity
@Table(name = "m_interest_incentives")
public class InterestIncentives extends AbstractPersistableCustom {
@ManyToOne
@JoinColumn(name = "interest_rate_slab_id", nullable = false)
private InterestRateChartSlab interestRateChartSlab;
@Embedded
private InterestIncentivesFields interestIncentivesFields;
protected InterestIncentives() {
}
/*
* public InterestIncentives(final InterestRateChartSlab interestRateChartSlab, final InterestIncentivesFields
* interestIncentivesFields) { this.interestRateChartSlab = interestRateChartSlab; this.interestIncentivesFields =
* interestIncentivesFields; }
*/
public InterestRateChartSlab interestRateChartSlab() {
return this.interestRateChartSlab;
}
public void updateInterestRateChartSlab(InterestRateChartSlab interestRateChartSlab) {
this.interestRateChartSlab = interestRateChartSlab;
}
public InterestIncentives(final InterestRateChartSlab interestRateChartSlab, final InterestIncentivesFields interestIncentivesFields) {
this.interestRateChartSlab = interestRateChartSlab;
this.interestIncentivesFields = interestIncentivesFields;
if (this.interestRateChartSlab != null) {
interestRateChartSlab.addInterestIncentive(this);
}
}
public void update(final JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator,
final Locale locale) {
this.interestIncentivesFields.update(command, actualChanges, baseDataValidator, locale);
}
public InterestIncentivesFields interestIncentivesFields() {
return this.interestIncentivesFields;
}
}
@@ -1,177 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.domain;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.amountParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.attributeNameParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.attributeValueParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.conditionTypeParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.entityTypeParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.incentiveTypeparamName;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import java.math.BigDecimal;
import java.util.Locale;
import java.util.Map;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.portfolio.common.domain.ConditionType;
import org.apache.fineract.portfolio.interestratechart.incentive.InterestIncentiveAttributeName;
import org.apache.fineract.portfolio.interestratechart.incentive.InterestIncentiveEntityType;
import org.apache.fineract.portfolio.interestratechart.incentive.InterestIncentiveType;
@Embeddable
public class InterestIncentivesFields {
@Column(name = "entiry_type", nullable = false)
private Integer entityType;
@Column(name = "attribute_name", nullable = false)
private Integer attributeName;
@Column(name = "condition_type", nullable = false)
private Integer conditionType;
@Column(name = "attribute_value", nullable = false)
private String attributeValue;
@Column(name = "incentive_type", nullable = false)
private Integer incentiveType;
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
private BigDecimal amount;
protected InterestIncentivesFields() {
}
public static InterestIncentivesFields createNew(final Integer entityType, final Integer attributeName, final Integer conditionType,
final String attributeValue, final Integer incentiveType, final BigDecimal amount,
final DataValidatorBuilder baseDataValidator) {
return new InterestIncentivesFields(entityType, attributeName, conditionType, attributeValue, incentiveType, amount,
baseDataValidator);
}
private InterestIncentivesFields(final Integer entityType, final Integer attributeName, final Integer conditionType,
final String attributeValue, final Integer incentiveType, final BigDecimal amount,
final DataValidatorBuilder baseDataValidator) {
this.entityType = entityType;
this.attributeName = attributeName;
this.attributeValue = attributeValue;
this.conditionType = conditionType;
this.incentiveType = incentiveType;
this.amount = amount;
validateIncentiveData(baseDataValidator);
}
public InterestIncentiveAttributeName attributeName() {
return InterestIncentiveAttributeName.fromInt(this.attributeName);
}
public ConditionType conditionType() {
return ConditionType.fromInt(this.conditionType);
}
public String attributeValue() {
return this.attributeValue;
}
public InterestIncentiveType incentiveType() {
return InterestIncentiveType.fromInt(this.incentiveType);
}
public BigDecimal amount() {
return this.amount;
}
public InterestIncentiveEntityType entiryType() {
return InterestIncentiveEntityType.fromInt(this.entityType);
}
public void update(final JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator,
final Locale locale) {
if (command.isChangeInIntegerParameterNamed(entityTypeParamName, this.entityType, locale)) {
final Integer newValue = command.integerValueOfParameterNamed(entityTypeParamName, locale);
actualChanges.put(entityTypeParamName, newValue);
this.entityType = newValue;
}
if (command.isChangeInIntegerParameterNamed(attributeNameParamName, this.attributeName, locale)) {
final Integer newValue = command.integerValueOfParameterNamed(attributeNameParamName, locale);
actualChanges.put(attributeNameParamName, newValue);
this.attributeName = newValue;
}
if (command.isChangeInIntegerParameterNamed(conditionTypeParamName, this.conditionType, locale)) {
final Integer newValue = command.integerValueOfParameterNamed(conditionTypeParamName, locale);
actualChanges.put(conditionTypeParamName, newValue);
this.conditionType = newValue;
}
if (command.isChangeInStringParameterNamed(attributeValueParamName, this.attributeValue)) {
final String newValue = command.stringValueOfParameterNamed(attributeValueParamName);
actualChanges.put(attributeValueParamName, newValue);
this.attributeValue = newValue;
}
if (command.isChangeInIntegerParameterNamed(incentiveTypeparamName, this.incentiveType, locale)) {
final Integer newValue = command.integerValueOfParameterNamed(incentiveTypeparamName, locale);
actualChanges.put(incentiveTypeparamName, newValue);
this.incentiveType = newValue;
}
if (command.isChangeInBigDecimalParameterNamed(amountParamName, this.amount, locale)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountParamName, locale);
actualChanges.put(amountParamName, newValue);
this.amount = newValue;
}
validateIncentiveData(baseDataValidator);
}
public void validateIncentiveData(final DataValidatorBuilder baseDataValidator) {
switch (attributeName()) {
case GENDER:
baseDataValidator.reset().parameter(attributeValueParamName).value(this.attributeValue).longGreaterThanZero();
baseDataValidator.reset().parameter(conditionTypeParamName).value(this.conditionType)
.isOneOfTheseValues(ConditionType.EQUAL.getValue(), ConditionType.NOT_EQUAL.getValue());
break;
case AGE:
baseDataValidator.reset().parameter(attributeValueParamName).value(this.attributeValue).longGreaterThanZero();
break;
case CLIENT_CLASSIFICATION:
baseDataValidator.reset().parameter(attributeValueParamName).value(this.attributeValue).longGreaterThanZero();
baseDataValidator.reset().parameter(conditionTypeParamName).value(this.conditionType)
.isOneOfTheseValues(ConditionType.EQUAL.getValue(), ConditionType.NOT_EQUAL.getValue());
break;
case CLIENT_TYPE:
baseDataValidator.reset().parameter(attributeValueParamName).value(this.attributeValue).longGreaterThanZero();
baseDataValidator.reset().parameter(conditionTypeParamName).value(this.conditionType)
.isOneOfTheseValues(ConditionType.EQUAL.getValue(), ConditionType.NOT_EQUAL.getValue());
break;
default:
break;
}
}
}
@@ -1,341 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.domain;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.INTERESTRATE_CHART_RESOURCE_NAME;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.deleteParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.idParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.amountRangeFromParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.amountRangeToParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.annualInterestRateParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.fromPeriodParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.periodTypeParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.toPeriodParamName;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants;
import org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants;
import org.apache.fineract.portfolio.savings.SavingsPeriodFrequencyType;
@Entity
@Table(name = "m_interest_rate_chart")
public class InterestRateChart extends AbstractPersistableCustom {
@Embedded
private InterestRateChartFields chartFields;
@OneToMany(mappedBy = "interestRateChart", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Set<InterestRateChartSlab> chartSlabs = new HashSet<>();
protected InterestRateChart() {
//
}
public static InterestRateChart createNew(InterestRateChartFields chartFields,
Collection<InterestRateChartSlab> interestRateChartSlabs) {
return new InterestRateChart(chartFields, new HashSet<>(interestRateChartSlabs));
}
private InterestRateChart(InterestRateChartFields chartFields, Set<InterestRateChartSlab> interestRateChartSlabs) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_RESOURCE_NAME);
this.chartFields = chartFields;
// validate before setting the other fields
this.validateChartSlabs(baseDataValidator);
this.throwExceptionIfValidationWarningsExist(dataValidationErrors);
this.addChartSlabs(interestRateChartSlabs);
}
public void validateChartSlabs(DataValidatorBuilder baseDataValidator) {
Collection<InterestRateChartSlab> chartSlabs = this.setOfChartSlabs();
Integer tmpPeriodType = null;
List<InterestRateChartSlab> chartSlabsList = new ArrayList<>(chartSlabs);
boolean isPrimaryGroupingByAmount = this.chartFields.isPrimaryGroupingByAmount();
chartSlabsList.sort(new InterestRateChartSlabComparator<InterestRateChartSlab>(isPrimaryGroupingByAmount));
boolean isPeriodChart = !isPrimaryGroupingByAmount;
boolean isAmountChart = isPrimaryGroupingByAmount;
for (int i = 0; i < chartSlabsList.size(); i++) {
InterestRateChartSlab iSlabs = chartSlabsList.get(i);
if (!iSlabs.slabFields().isValidChart(isPrimaryGroupingByAmount)) {
if (isPrimaryGroupingByAmount) {
baseDataValidator.parameter(InterestRateChartSlabApiConstants.amountRangeFromParamName).failWithCode("cannot.be.blank");
} else {
baseDataValidator.parameter(InterestRateChartSlabApiConstants.fromPeriodParamName).failWithCode("cannot.be.blank");
}
} else if (i > 0) {
if (isPeriodChart ^ iSlabs.slabFields().fromPeriod() != null) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.period.range.incomplete");
isPeriodChart = isPeriodChart || iSlabs.slabFields().fromPeriod() != null;
}
if (isAmountChart ^ iSlabs.slabFields().getAmountRangeFrom() != null) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.amount.range.incomplete");
isAmountChart = isAmountChart || iSlabs.slabFields().getAmountRangeFrom() != null;
}
}
if (i == 0) {
tmpPeriodType = iSlabs.slabFields().periodType();
if (iSlabs.slabFields().isNotProperChartStart()) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.range.start.incorrect",
iSlabs.slabFields().fromPeriod(), iSlabs.slabFields().getAmountRangeFrom());
}
isAmountChart = isAmountChart || iSlabs.slabFields().getAmountRangeFrom() != null;
isPeriodChart = isPeriodChart || iSlabs.slabFields().fromPeriod() != null;
} else if (iSlabs.slabFields().periodType() != null && !iSlabs.slabFields().periodType().equals(tmpPeriodType)) {
baseDataValidator.parameter(periodTypeParamName).value(iSlabs.slabFields().periodType())
.failWithCode("period.type.is.not.same", tmpPeriodType);
}
if (i + 1 < chartSlabsList.size()) {
InterestRateChartSlab nextSlabs = chartSlabsList.get(i + 1);
if (iSlabs.slabFields().isValidChart(isPrimaryGroupingByAmount)
&& nextSlabs.slabFields().isValidChart(isPrimaryGroupingByAmount)) {
if (iSlabs.slabFields().isRateChartOverlapping(nextSlabs.slabFields(), isPrimaryGroupingByAmount)) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.range.overlapping",
iSlabs.slabFields().fromPeriod(), iSlabs.slabFields().toPeriod(), nextSlabs.slabFields().fromPeriod(),
nextSlabs.slabFields().toPeriod(), iSlabs.slabFields().getAmountRangeFrom(),
iSlabs.slabFields().getAmountRangeTo(), nextSlabs.slabFields().getAmountRangeFrom(),
nextSlabs.slabFields().getAmountRangeTo());
} else if (iSlabs.slabFields().isRateChartHasGap(nextSlabs.slabFields(), isPrimaryGroupingByAmount)) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.range.has.gap",
iSlabs.slabFields().fromPeriod(), iSlabs.slabFields().toPeriod(), nextSlabs.slabFields().fromPeriod(),
nextSlabs.slabFields().toPeriod(), iSlabs.slabFields().getAmountRangeFrom(),
iSlabs.slabFields().getAmountRangeTo(), nextSlabs.slabFields().getAmountRangeFrom(),
nextSlabs.slabFields().getAmountRangeTo());
}
if (isPrimaryGroupingByAmount) {
if (!iSlabs.slabFields().isAmountSame(nextSlabs.slabFields())) {
if (InterestRateChartSlabFields.isNotProperPeriodStart(nextSlabs.slabFields())) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.period.range.start.incorrect",
nextSlabs.slabFields().toPeriod());
}
if (iSlabs.slabFields().toPeriod() != null) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.period.range.end.incorrect",
iSlabs.slabFields().toPeriod());
}
}
} else if (!iSlabs.slabFields().isPeriodsSame(nextSlabs.slabFields())) {
if (InterestRateChartSlabFields.isNotProperAmountStart(nextSlabs.slabFields())) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.amount.range.start.incorrect",
nextSlabs.slabFields().getAmountRangeFrom());
}
if (iSlabs.slabFields().getAmountRangeTo() != null) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.amount.range.end.incorrect",
iSlabs.slabFields().getAmountRangeTo());
}
}
}
} else if (iSlabs.slabFields().isNotProperPriodEnd()) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.slabs.range.end.incorrect", iSlabs.slabFields().toPeriod(),
iSlabs.slabFields().getAmountRangeTo());
}
}
}
public void addChartSlabs(Collection<InterestRateChartSlab> interestRateChartSlabsSet) {
Set<InterestRateChartSlab> existingChartSlabs = setOfChartSlabs();
for (InterestRateChartSlab newChartSlabs : interestRateChartSlabsSet) {
newChartSlabs.setInterestRateChart(this);
existingChartSlabs.add(newChartSlabs);
}
}
public void addChartSlab(InterestRateChartSlab newChartSlab) {
newChartSlab.setInterestRateChart(this);
setOfChartSlabs().add(newChartSlab);
}
public Set<InterestRateChartSlab> setOfChartSlabs() {
if (this.chartSlabs == null) {
this.chartSlabs = new HashSet<>();
}
return this.chartSlabs;
}
public void update(JsonCommand command, final Map<String, Object> actualChanges) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_RESOURCE_NAME);
this.update(command, actualChanges, baseDataValidator, null, null);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void update(JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator,
final Set<InterestRateChart> existingCharts, String currencyCode) {
this.chartFields.update(command, actualChanges, baseDataValidator);
// interestRateChartSlabs
if (command.hasParameter(InterestRateChartApiConstants.chartSlabs)) {
updateChartSlabs(command, actualChanges, baseDataValidator, currencyCode);
}
this.validateCharts(baseDataValidator, existingCharts);
}
private void validateCharts(final DataValidatorBuilder baseDataValidator, final Set<InterestRateChart> existingCharts) {
for (InterestRateChart existingChart : existingCharts) {
if (!existingChart.equals(this)) {
if (this.chartFields.isOverlapping(existingChart.chartFields)) {
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("chart.overlapping.from.and.end.dates",
existingChart.getFromDate(), existingChart.getEndDate(), this.getFromDate(), this.getEndDate());
}
}
}
}
public void updateChartSlabs(JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator,
String currencyCode) {
final Map<String, Object> deleteChartSlabs = new HashMap<>();
final Map<String, Object> chartSlabsChanges = new HashMap<>();
final Locale locale = command.extractLocale();
if (command.hasParameter(InterestRateChartApiConstants.chartSlabs)) {
final JsonArray array = command.arrayOfParameterNamed(InterestRateChartApiConstants.chartSlabs);
if (array != null) {
for (int i = 0; i < array.size(); i++) {
final JsonObject chartSlabsElement = array.get(i).getAsJsonObject();
JsonCommand chartSlabsCommand = JsonCommand.fromExistingCommand(command, chartSlabsElement);
if (chartSlabsCommand.parameterExists(idParamName)) {
final Long chartSlabId = chartSlabsCommand.longValueOfParameterNamed(idParamName);
final InterestRateChartSlab chartSlab = this.findChartSlab(chartSlabId);
if (chartSlab == null) {
baseDataValidator.parameter(idParamName).value(chartSlabId).failWithCode("no.chart.slab.associated.with.id");
} else if (chartSlabsCommand.parameterExists(deleteParamName)) {
if (this.removeChartSlab(chartSlab)) {
deleteChartSlabs.put(idParamName, chartSlabId);
}
} else {
chartSlab.update(chartSlabsCommand, chartSlabsChanges, baseDataValidator, locale);
}
} else {
/**
* TODO: AA: Move this code to InterestRateChartSlabAssembler
*/
final String description = chartSlabsCommand.stringValueOfParameterNamed(descriptionParamName);
final Integer periodTypeId = chartSlabsCommand.integerValueOfParameterNamed(periodTypeParamName, locale);
final SavingsPeriodFrequencyType periodFrequencyType = SavingsPeriodFrequencyType.fromInt(periodTypeId);
final Integer fromPeriod = chartSlabsCommand.integerValueOfParameterNamed(fromPeriodParamName, locale);
final Integer toPeriod = chartSlabsCommand.integerValueOfParameterNamed(toPeriodParamName, locale);
final BigDecimal amountRangeFrom = chartSlabsCommand.bigDecimalValueOfParameterNamed(amountRangeFromParamName,
locale);
final BigDecimal amountRangeTo = chartSlabsCommand.bigDecimalValueOfParameterNamed(amountRangeToParamName, locale);
final BigDecimal annualInterestRate = chartSlabsCommand.bigDecimalValueOfParameterNamed(annualInterestRateParamName,
locale);
final InterestRateChartSlabFields slabFields = InterestRateChartSlabFields.createNew(description,
periodFrequencyType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo, annualInterestRate,
currencyCode);
final InterestRateChartSlab chartSlab = InterestRateChartSlab.createNew(slabFields, this);
chartSlab.slabFields().validateChartSlabPlatformRules(chartSlabsCommand, baseDataValidator, locale);
chartSlab.updateIncentives(chartSlabsCommand, actualChanges, baseDataValidator, chartSlab, locale);
this.addChartSlab(chartSlab);
}
}
}
}
// add chart slab changes to actual changes list.
if (!chartSlabsChanges.isEmpty()) {
actualChanges.put(InterestRateChartApiConstants.chartSlabs, chartSlabsChanges);
}
// add deleted chart Slabs to actual changes
if (!deleteChartSlabs.isEmpty()) {
actualChanges.put("deletedChartSlabs", deleteChartSlabs);
}
this.validateChartSlabs(baseDataValidator);
}
public InterestRateChartSlab findChartSlab(Long chartSlabId) {
final Set<InterestRateChartSlab> chartSlabs = setOfChartSlabs();
for (InterestRateChartSlab interestRateChartSlab : chartSlabs) {
if (interestRateChartSlab.getId().equals(chartSlabId)) {
return interestRateChartSlab;
}
}
return null;
}
private boolean removeChartSlab(InterestRateChartSlab chartSlab) {
final Set<InterestRateChartSlab> chartSlabs = setOfChartSlabs();
return chartSlabs.remove(chartSlab);
}
public LocalDate getFromDate() {
return this.chartFields.getFromDate();
}
public LocalDate getEndDate() {
return this.chartFields.getEndDate();
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
}
public InterestRateChartFields chartFields() {
return this.chartFields;
}
public boolean isApplicableChartFor(final LocalDate target) {
return this.chartFields.isApplicableChartFor(target);
}
}
@@ -1,161 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.domain;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.dateFormatParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.endDateParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.fromDateParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.isPrimaryGroupingByAmountParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.localeParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.nameParamName;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import java.time.LocalDate;
import java.util.Map;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.domain.LocalDateInterval;
import org.apache.fineract.infrastructure.core.service.DateUtils;
@Embeddable
public class InterestRateChartFields {
@Column(name = "name", length = 100, unique = false, nullable = false)
private String name;
@Column(name = "description", nullable = true)
private String description;
@Column(name = "from_date", nullable = false)
private LocalDate fromDate;
@Column(name = "end_date", nullable = true)
private LocalDate endDate;
@Column(name = "is_primary_grouping_by_amount", nullable = false)
private boolean isPrimaryGroupingByAmount;
protected InterestRateChartFields() {
//
}
public static InterestRateChartFields createNew(String name, String description, LocalDate fromDate, LocalDate toDate,
boolean isPrimaryGroupingByAmount) {
return new InterestRateChartFields(name, description, fromDate, toDate, isPrimaryGroupingByAmount);
}
private InterestRateChartFields(String name, String description, LocalDate fromDate, LocalDate toDate,
boolean isPrimaryGroupingByAmount) {
this.name = name;
this.description = description;
this.fromDate = fromDate;
this.endDate = toDate;
this.isPrimaryGroupingByAmount = isPrimaryGroupingByAmount;
}
public void update(JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator) {
if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
final String newValue = command.stringValueOfParameterNamed(nameParamName);
actualChanges.put(nameParamName, newValue);
this.name = newValue;
}
if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) {
final String newValue = command.stringValueOfParameterNamed(descriptionParamName);
actualChanges.put(descriptionParamName, newValue);
this.description = newValue;
}
final String localeAsInput = command.locale();
final String dateFormat = command.dateFormat();
if (command.isChangeInLocalDateParameterNamed(fromDateParamName, getFromDate())) {
final String newValueAsString = command.stringValueOfParameterNamed(fromDateParamName);
actualChanges.put(fromDateParamName, newValueAsString);
actualChanges.put(localeParamName, localeAsInput);
actualChanges.put(dateFormatParamName, dateFormat);
this.fromDate = command.localDateValueOfParameterNamed(fromDateParamName);
}
if (command.isChangeInLocalDateParameterNamed(endDateParamName, getEndDate())) {
final String newValueAsString = command.stringValueOfParameterNamed(endDateParamName);
actualChanges.put(endDateParamName, newValueAsString);
actualChanges.put(localeParamName, localeAsInput);
actualChanges.put(dateFormatParamName, dateFormat);
this.endDate = command.localDateValueOfParameterNamed(endDateParamName);
}
if (command.isChangeInBooleanParameterNamed(isPrimaryGroupingByAmountParamName, this.isPrimaryGroupingByAmount)) {
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(isPrimaryGroupingByAmountParamName);
actualChanges.put(isPrimaryGroupingByAmountParamName, newValue);
this.isPrimaryGroupingByAmount = newValue;
}
if (isFromDateAfterToDate()) {
baseDataValidator.parameter(fromDateParamName).value(fromDate).failWithCode("from.date.is.after.to.date");
}
}
public boolean isFromDateAfterToDate() {
return isFromDateAfter(getEndDate());
}
public boolean isFromDateAfter(LocalDate compare) {
return compare != null && DateUtils.isAfter(getFromDate(), compare);
}
public LocalDate getFromDate() {
return this.fromDate;
}
public LocalDate getEndDate() {
return this.endDate;
}
public boolean isOverlapping(InterestRateChartFields that) {
final LocalDate thisFromDate = this.getFromDate();
LocalDate thisEndDate = this.getEndDate();
thisEndDate = thisEndDate == null ? DateUtils.getBusinessLocalDate() : thisEndDate;
final LocalDate thatFromDate = that.getFromDate();
LocalDate thatEndDate = that.getEndDate();
thatEndDate = thatEndDate == null ? DateUtils.getBusinessLocalDate() : thatEndDate;
final LocalDateInterval thisInterval = LocalDateInterval.create(thisFromDate, thisEndDate);
final LocalDateInterval thatInterval = LocalDateInterval.create(thatFromDate, thatEndDate);
if (thisInterval.containsPortionOf(thatInterval) || thatInterval.containsPortionOf(thisInterval)) {
return true;
}
return false;// no overlapping
}
public boolean isApplicableChartFor(final LocalDate target) {
final LocalDate endDate = this.endDate == null ? DateUtils.getBusinessLocalDate() : this.getEndDate();
final LocalDateInterval interval = LocalDateInterval.create(getFromDate(), endDate);
return interval.contains(target);
}
public boolean isPrimaryGroupingByAmount() {
return this.isPrimaryGroupingByAmount;
}
}
@@ -1,26 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface InterestRateChartRepository extends JpaRepository<InterestRateChart, Long>, JpaSpecificationExecutor<InterestRateChart> {
}
@@ -1,61 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.domain;
import org.apache.fineract.portfolio.interestratechart.exception.InterestRateChartNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* <p>
* Wrapper for {@link InterestRateChartRepository} that is responsible for checking if {@link InterestRateChart} is
* returned when using <code>findOne</code> repository method and throwing an appropriate not found exception.
* </p>
*
* <p>
* This is to avoid need for checking and throwing in multiple areas of code base where
* {@link InterestRateChartRepository} is required.
* </p>
*/
@Service
public class InterestRateChartRepositoryWrapper {
private final InterestRateChartRepository repository;
@Autowired
public InterestRateChartRepositoryWrapper(final InterestRateChartRepository repository) {
this.repository = repository;
}
public InterestRateChart findOneWithNotFoundDetection(final Long intrestRateChartId) {
return this.repository.findById(intrestRateChartId).orElseThrow(() -> new InterestRateChartNotFoundException(intrestRateChartId));
}
public void save(final InterestRateChart interestRateChart) {
this.repository.save(interestRateChart);
}
public void delete(final InterestRateChart interestRateChart) {
this.repository.delete(interestRateChart);
}
public void saveAndFlush(final InterestRateChart interestRateChart) {
this.repository.saveAndFlush(interestRateChart);
}
}
@@ -1,196 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.domain;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.amountParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.attributeNameParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.attributeValueParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.conditionTypeParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.entityTypeParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.incentiveTypeparamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.deleteParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.idParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.INTERESTRATE_CHART_SLAB_RESOURCE_NAME;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants;
import org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants;
@Entity
@Table(name = "m_interest_rate_slab")
public class InterestRateChartSlab extends AbstractPersistableCustom {
@Embedded
private InterestRateChartSlabFields slabFields;
@ManyToOne(optional = false)
@JoinColumn(name = "interest_rate_chart_id", referencedColumnName = "id", nullable = false)
private InterestRateChart interestRateChart;
@OneToMany(mappedBy = "interestRateChartSlab", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Set<InterestIncentives> interestIncentives = new HashSet<>();
protected InterestRateChartSlab() {
//
}
public static InterestRateChartSlab createNew(InterestRateChartSlabFields slabFields, InterestRateChart interestRateChart) {
return new InterestRateChartSlab(slabFields, interestRateChart);
}
public void update(JsonCommand command, final Map<String, Object> actualChanges, final Locale locale) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_SLAB_RESOURCE_NAME);
this.update(command, actualChanges, baseDataValidator, locale);
this.interestRateChart.validateChartSlabs(baseDataValidator);
this.throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void update(JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator,
final Locale locale) {
this.slabFields.update(command, actualChanges, baseDataValidator, locale);
updateIncentives(command, actualChanges, baseDataValidator, this, locale);
}
private InterestRateChartSlab(InterestRateChartSlabFields slabFields, InterestRateChart interestRateChart) {
this.slabFields = slabFields;
this.interestRateChart = interestRateChart;
if (this.interestRateChart != null) {
interestRateChart.addChartSlab(this);
}
}
public void setInterestRateChart(InterestRateChart interestRateChart) {
this.interestRateChart = interestRateChart;
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
}
public InterestRateChartSlabFields slabFields() {
return this.slabFields;
}
public Set<InterestIncentives> setOfInterestIncentives() {
if (this.interestIncentives == null) {
this.interestIncentives = new HashSet<>();
}
return this.interestIncentives;
}
public void addInterestIncentive(InterestIncentives interestIncentives) {
interestIncentives.updateInterestRateChartSlab(this);
setOfInterestIncentives().add(interestIncentives);
}
public InterestIncentives findInterestIncentive(Long interestIncentiveId) {
final Set<InterestIncentives> interestIncentives = setOfInterestIncentives();
for (InterestIncentives interestIncentive : interestIncentives) {
if (interestIncentive.getId().equals(interestIncentiveId)) {
return interestIncentive;
}
}
return null;
}
public boolean removeInterestIncentive(InterestIncentives incentive) {
final Set<InterestIncentives> incentives = setOfInterestIncentives();
return incentives.remove(incentive);
}
public void updateIncentives(JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator,
final InterestRateChartSlab chartSlab, final Locale locale) {
final Map<String, Object> deleteIncentives = new HashMap<>();
final Map<String, Object> IncentiveChanges = new HashMap<>();
if (command.hasParameter(InterestRateChartSlabApiConstants.incentivesParamName)) {
final JsonArray array = command.arrayOfParameterNamed(InterestRateChartSlabApiConstants.incentivesParamName);
if (array != null) {
for (int i = 0; i < array.size(); i++) {
final JsonObject incentiveElement = array.get(i).getAsJsonObject();
JsonCommand incentivesCommand = JsonCommand.fromExistingCommand(command, incentiveElement);
if (incentivesCommand.parameterExists(InterestIncentiveApiConstants.idParamName)) {
final Long interestIncentiveId = incentivesCommand
.longValueOfParameterNamed(InterestIncentiveApiConstants.idParamName);
final InterestIncentives interestIncentives = chartSlab.findInterestIncentive(interestIncentiveId);
if (interestIncentives == null) {
baseDataValidator.parameter(InterestIncentiveApiConstants.idParamName).value(interestIncentiveId)
.failWithCode("no.interest.incentive.associated.with.id");
} else if (incentivesCommand.parameterExists(deleteParamName)) {
if (chartSlab.removeInterestIncentive(interestIncentives)) {
deleteIncentives.put(idParamName, interestIncentiveId);
}
} else {
interestIncentives.update(incentivesCommand, IncentiveChanges, baseDataValidator, locale);
}
} else {
Integer entityType = incentivesCommand.integerValueOfParameterNamed(entityTypeParamName, locale);
Integer conditionType = incentivesCommand.integerValueOfParameterNamed(conditionTypeParamName, locale);
Integer attributeName = incentivesCommand.integerValueOfParameterNamed(attributeNameParamName, locale);
String attributeValue = incentivesCommand.stringValueOfParameterNamed(attributeValueParamName);
Integer incentiveType = incentivesCommand.integerValueOfParameterNamed(incentiveTypeparamName, locale);
BigDecimal amount = incentivesCommand.bigDecimalValueOfParameterNamed(amountParamName, locale);
InterestIncentivesFields incentivesFields = InterestIncentivesFields.createNew(entityType, attributeName,
conditionType, attributeValue, incentiveType, amount, baseDataValidator);
InterestIncentives incentives = new InterestIncentives(chartSlab, incentivesFields);
chartSlab.addInterestIncentive(incentives);
}
}
}
// add chart slab changes to actual changes list.
if (!IncentiveChanges.isEmpty()) {
actualChanges.put(InterestRateChartSlabApiConstants.incentivesParamName, IncentiveChanges);
}
// add deleted chart Slabs to actual changes
if (!deleteIncentives.isEmpty()) {
actualChanges.put("deletedIncentives", deleteIncentives);
}
}
}
}
@@ -1,91 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.domain;
import java.math.BigDecimal;
import java.util.Comparator;
import org.apache.fineract.portfolio.savings.domain.DepositAccountInterestRateChartSlabs;
/**
* Sort InterestRateChartSlab by input range
*/
public class InterestRateChartSlabComparator<T> implements Comparator<T> {
private final boolean isPrimaryGroupingByAmount;
public InterestRateChartSlabComparator(final boolean isPrimaryGroupingByAmount) {
this.isPrimaryGroupingByAmount = isPrimaryGroupingByAmount;
}
@Override
public int compare(final T o1, final T o2) {
int compareResult = 0;
InterestRateChartSlabFields slabs1 = null;
InterestRateChartSlabFields slabs2 = null;
if (o1 instanceof InterestRateChartSlab) {
slabs1 = ((InterestRateChartSlab) o1).slabFields();
slabs2 = ((InterestRateChartSlab) o2).slabFields();
} else if (o1 instanceof DepositAccountInterestRateChartSlabs) {
slabs1 = ((DepositAccountInterestRateChartSlabs) o1).slabFields();
slabs2 = ((DepositAccountInterestRateChartSlabs) o2).slabFields();
} else {
return compareResult;
}
if (slabs1.isPeriodsSame(slabs2) && slabs1.isAmountSame(slabs2)) {
compareResult = 0;
} else {
if (isPrimaryGroupingByAmount) {
if (slabs1.isAmountSame(slabs2)) {
compareResult = comparePeriods(slabs1, slabs2);
} else {
compareResult = compareAmounts(slabs1, slabs2);
}
} else {
if (slabs1.isPeriodsSame(slabs2)) {
compareResult = compareAmounts(slabs1, slabs2);
} else {
compareResult = comparePeriods(slabs1, slabs2);
}
}
}
return compareResult;
}
private int comparePeriods(final InterestRateChartSlabFields slabs1, InterestRateChartSlabFields slabs2) {
int compareResult = 0;
Integer periodFrom1 = slabs1.fromPeriod();
Integer periodFrom2 = slabs2.fromPeriod();
if (periodFrom1 != null && periodFrom2 != null) {
compareResult = periodFrom1.compareTo(periodFrom2);
}
return compareResult;
}
private int compareAmounts(final InterestRateChartSlabFields slabs1, InterestRateChartSlabFields slabs2) {
int compareResult = 0;
BigDecimal amountFrom1 = slabs1.getAmountRangeFrom();
BigDecimal amountFrom2 = slabs2.getAmountRangeFrom();
if (amountFrom1 != null && amountFrom2 != null) {
compareResult = amountFrom1.compareTo(amountFrom2);
}
return compareResult;
}
}
@@ -1,376 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.domain;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.amountRangeFromParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.amountRangeToParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.annualInterestRateParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.descriptionParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.fromPeriodParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.periodTypeParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.toPeriodParamName;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Comparator;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.portfolio.savings.SavingsPeriodFrequencyType;
@Embeddable
public class InterestRateChartSlabFields {
@Column(name = "description", nullable = true)
private String description;
@Column(name = "period_type_enum", nullable = true)
private Integer periodType;
@Column(name = "from_period")
private Integer fromPeriod;
@Column(name = "to_period")
private Integer toPeriod;
@Column(name = "amount_range_from", scale = 6, precision = 19)
private BigDecimal amountRangeFrom;
public BigDecimal getAmountRangeFrom() {
return this.amountRangeFrom;
}
public BigDecimal getAmountRangeTo() {
return this.amountRangeTo;
}
@Column(name = "amount_range_to", scale = 6, precision = 19)
private BigDecimal amountRangeTo;
@Column(name = "annual_interest_rate", scale = 6, precision = 19, nullable = false)
private BigDecimal annualInterestRate;
@Column(name = "currency_code", nullable = false)
private String currencyCode;
protected InterestRateChartSlabFields() {
//
}
public static InterestRateChartSlabFields createNew(final String description, final SavingsPeriodFrequencyType periodFrequencyType,
final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo,
final BigDecimal annualInterestRate, final String currencyCode) {
return new InterestRateChartSlabFields(description, periodFrequencyType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo,
annualInterestRate, currencyCode);
}
private InterestRateChartSlabFields(final String description, final SavingsPeriodFrequencyType periodFrequencyType,
final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo,
final BigDecimal annualInterestRate, final String currencyCode) {
this.description = description;
this.periodType = (periodFrequencyType == null || periodFrequencyType.isInvalid()) ? null : periodFrequencyType.getValue();
this.fromPeriod = fromPeriod;
this.toPeriod = toPeriod;
this.amountRangeFrom = amountRangeFrom;
this.amountRangeTo = amountRangeTo;
this.annualInterestRate = annualInterestRate;
this.currencyCode = currencyCode;
}
public void update(final JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator,
final Locale locale) {
if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) {
final String newValue = command.stringValueOfParameterNamed(descriptionParamName);
actualChanges.put(descriptionParamName, newValue);
this.description = newValue;
}
if (command.isChangeInIntegerParameterNamed(periodTypeParamName, this.periodType, locale)) {
final Integer newValue = command.integerValueOfParameterNamed(periodTypeParamName, locale);
actualChanges.put(periodTypeParamName, newValue);
this.periodType = newValue;
}
if (command.isChangeInIntegerParameterNamed(fromPeriodParamName, this.fromPeriod, locale)) {
final Integer newValue = command.integerValueOfParameterNamed(fromPeriodParamName, locale);
actualChanges.put(fromPeriodParamName, newValue);
this.fromPeriod = newValue;
}
if (command.isChangeInIntegerParameterNamed(toPeriodParamName, this.toPeriod, locale)) {
final Integer newValue = command.integerValueOfParameterNamed(toPeriodParamName, locale);
actualChanges.put(toPeriodParamName, newValue);
this.toPeriod = newValue;
}
if (command.isChangeInBigDecimalParameterNamed(amountRangeFromParamName, this.amountRangeFrom, locale)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountRangeFromParamName, locale);
actualChanges.put(amountRangeFromParamName, newValue);
this.amountRangeFrom = newValue;
}
if (command.isChangeInBigDecimalParameterNamed(amountRangeToParamName, this.amountRangeTo, locale)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountRangeToParamName, locale);
actualChanges.put(amountRangeToParamName, newValue);
this.amountRangeTo = newValue;
}
if (command.isChangeInBigDecimalParameterNamed(annualInterestRateParamName, this.annualInterestRate, locale)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(annualInterestRateParamName, locale);
actualChanges.put(annualInterestRateParamName, newValue);
this.annualInterestRate = newValue;
}
validateChartSlabPlatformRules(command, baseDataValidator, locale);
}
public void validateChartSlabPlatformRules(final JsonCommand chartSlabsCommand, final DataValidatorBuilder baseDataValidator,
Locale locale) {
if (isFromPeriodGreaterThanToPeriod()) {
final Integer fromPeriod = chartSlabsCommand.integerValueOfParameterNamed(fromPeriodParamName, locale);
baseDataValidator.parameter(fromPeriodParamName).value(fromPeriod).failWithCode("from.period.is.greater.than.to.period");
}
if (isAmountRangeFromGreaterThanTo()) {
final BigDecimal amountRangeFrom = chartSlabsCommand.bigDecimalValueOfParameterNamed(amountRangeFromParamName, locale);
baseDataValidator.parameter(amountRangeFromParamName).value(amountRangeFrom)
.failWithCode("amount.range.from.is.greater.than.amount.range.to");
}
}
public boolean isFromPeriodGreaterThanToPeriod() {
boolean isGreater = false;
if (this.toPeriod != null && this.fromPeriod.compareTo(this.toPeriod) > 0) {
isGreater = true;
}
return isGreater;
}
public boolean isAmountRangeFromGreaterThanTo() {
boolean isGreater = false;
if (this.amountRangeFrom != null && this.amountRangeTo != null && this.amountRangeFrom.compareTo(this.amountRangeTo) > 0) {
isGreater = true;
}
return isGreater;
}
public Integer periodType() {
return this.periodType;
}
public Integer fromPeriod() {
return this.fromPeriod;
}
public Integer toPeriod() {
return this.toPeriod;
}
public boolean isRateChartHasGap(final InterestRateChartSlabFields that, final boolean isPrimaryGroupingByAmount) {
boolean isPeriodSame = isPeriodsSame(that);
boolean isAmountSame = isAmountSame(that);
boolean hasPeriods = this.fromPeriod != null || that.fromPeriod != null;
boolean hasAmounts = this.amountRangeFrom != null || that.amountRangeFrom != null;
if (isPrimaryGroupingByAmount) {
if (isAmountSame) {
if (hasPeriods) {
if (this.toPeriod == null) {
return true;
}
return isNotProperPeriodStart(that.fromPeriod);
}
} else {
return isNotProperAmountStart(that.amountRangeFrom) || isNotProperPeriodStart(that);
}
} else {
if (isPeriodSame) {
if (hasAmounts) {
if (this.amountRangeTo == null) {
return true;
}
return isNotProperAmountStart(that.amountRangeFrom);
}
} else {
return isNotProperPeriodStart(that.fromPeriod) || isNotProperAmountStart(that);
}
}
return false;
}
public boolean isValidChart(boolean isPrimaryGroupingByAmount) {
return (!isPrimaryGroupingByAmount && this.fromPeriod != null) || (isPrimaryGroupingByAmount && this.amountRangeFrom != null);
}
public boolean isNotProperChartStart() {
return isNotProperPeriodStart(this) || isNotProperAmountStart(this);
}
public static boolean isNotProperAmountStart(final InterestRateChartSlabFields interestRateChartSlabFields) {
return interestRateChartSlabFields.amountRangeFrom != null
&& (interestRateChartSlabFields.amountRangeFrom.compareTo(BigDecimal.ONE) != 0
&& interestRateChartSlabFields.amountRangeFrom.compareTo(BigDecimal.ZERO) != 0);
}
private boolean isNotProperAmountStart(final BigDecimal amount) {
return this.amountRangeTo == null || (amount != null && amount.compareTo(this.amountRangeTo.add(BigDecimal.ONE)) != 0);
}
private boolean isNotProperPeriodStart(final Integer period) {
return this.toPeriod == null || (period != null && period.compareTo(this.toPeriod + 1) != 0);
}
public static boolean isNotProperPeriodStart(InterestRateChartSlabFields interestRateChartSlabFields) {
return interestRateChartSlabFields.fromPeriod != null
&& !(interestRateChartSlabFields.fromPeriod.equals(1) || interestRateChartSlabFields.fromPeriod.equals(0));
}
public boolean isNotProperPriodEnd() {
return !(this.toPeriod == null && this.amountRangeTo == null);
}
public boolean isRateChartOverlapping(final InterestRateChartSlabFields that, final boolean isPrimaryGroupingByAmount) {
boolean isPeriodOverLapping = isPeriodOverlapping(that);
boolean isAmountOverLapping = isAmountOverlapping(that);
boolean isPeriodSame = isPeriodsSame(that);
boolean isAmountSame = isAmountSame(that);
boolean isOverlapping = false;
if (isPrimaryGroupingByAmount) {
isOverlapping = (isAmountOverLapping && !isAmountSame) || (isPeriodOverLapping && isAmountSame);
} else {
isOverlapping = (isPeriodOverLapping && !isPeriodSame) || (isAmountOverLapping && isPeriodSame);
}
return isOverlapping;
}
private boolean isPeriodOverlapping(final InterestRateChartSlabFields that) {
if (isIntegerSame(that.toPeriod, this.toPeriod)) {
return true;
} else if (isIntegerSame(that.fromPeriod, this.fromPeriod)) {
return true;
} else if (this.toPeriod == null) {
return true;
} else if (that.toPeriod == null) {
return that.fromPeriod <= this.toPeriod;
}
return this.fromPeriod <= that.toPeriod && that.fromPeriod <= this.toPeriod;
}
private boolean isAmountOverlapping(final InterestRateChartSlabFields that) {
if (isBigDecimalSame(that.amountRangeFrom, this.amountRangeFrom)) {
return true;
} else if (isBigDecimalSame(that.amountRangeTo, this.amountRangeTo)) {
return true;
} else if (this.amountRangeTo == null) {
return true;
} else if (that.amountRangeTo == null) {
return that.amountRangeFrom.compareTo(this.amountRangeTo) <= 0;
}
return this.amountRangeFrom.compareTo(that.amountRangeTo) <= 0 && that.amountRangeFrom.compareTo(this.amountRangeTo) <= 0;
}
public boolean isAmountSame(final InterestRateChartSlabFields that) {
return isBigDecimalSame(this.amountRangeFrom, that.amountRangeFrom) && isBigDecimalSame(this.amountRangeTo, that.amountRangeTo);
}
public boolean isPeriodsSame(final InterestRateChartSlabFields that) {
return isIntegerSame(this.fromPeriod, that.fromPeriod) && isIntegerSame(this.toPeriod, that.toPeriod);
}
public boolean isIntegerSame(final Integer obj1, final Integer obj2) {
if (obj1 == null || obj2 == null) {
if (Objects.equals(obj1, obj2)) {
return true;
}
return false;
}
return obj1.equals(obj2);
}
public boolean isBigDecimalSame(final BigDecimal obj1, final BigDecimal obj2) {
if (obj1 == null || obj2 == null) {
return Objects.compare(obj1, obj2, Comparator.nullsFirst(Comparator.naturalOrder())) == 0;
}
return obj1.compareTo(obj2) == 0;
}
public boolean isBetweenPeriod(final LocalDate periodStartDate, final LocalDate periodEndDate) {
final Integer compare = depositPeriod(periodStartDate, periodEndDate);
return isPeriodBetween(compare);
}
public boolean isAmountRangeProvided() {
return this.amountRangeFrom != null;
}
public BigDecimal annualInterestRate() {
return this.annualInterestRate;
}
public Integer depositPeriod(final LocalDate periodStartDate, final LocalDate periodEndDate) {
Integer actualDepositPeriod = 0;
final SavingsPeriodFrequencyType periodFrequencyType = SavingsPeriodFrequencyType.fromInt(periodType());
switch (periodFrequencyType) {
case DAYS:
actualDepositPeriod = Math.toIntExact(ChronoUnit.DAYS.between(periodStartDate, periodEndDate));
break;
case WEEKS:
actualDepositPeriod = Math.toIntExact(ChronoUnit.WEEKS.between(periodStartDate, periodEndDate));
break;
case MONTHS:
actualDepositPeriod = Math.toIntExact(ChronoUnit.MONTHS.between(periodStartDate, periodEndDate));
break;
case YEARS:
actualDepositPeriod = Math.toIntExact(ChronoUnit.YEARS.between(periodStartDate, periodEndDate));
break;
case INVALID:
actualDepositPeriod = 0;// default value
break;
}
return actualDepositPeriod;
}
public boolean isAmountBetween(final BigDecimal depositAmount) {
boolean returnValue = true;
if (amountRangeFrom != null && amountRangeTo != null) {
returnValue = depositAmount.compareTo(amountRangeFrom) >= 0 && depositAmount.compareTo(amountRangeTo) <= 0;
} else if (amountRangeFrom != null) {
returnValue = depositAmount.compareTo(amountRangeFrom) >= 0;
}
return returnValue;
}
public boolean isPeriodBetween(final Integer periods) {
boolean returnValue = true;
if (fromPeriod != null && toPeriod != null) {
returnValue = periods.compareTo(fromPeriod) >= 0 && periods.compareTo(toPeriod) <= 0;
} else if (fromPeriod != null) {
returnValue = periods.compareTo(fromPeriod) >= 0;
}
return returnValue;
}
}
@@ -1,27 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface InterestRateChartSlabRepository
extends JpaRepository<InterestRateChartSlab, Long>, JpaSpecificationExecutor<InterestRateChartSlab> {
}
@@ -1,62 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.domain;
import org.apache.fineract.portfolio.interestratechart.exception.InterestRateChartSlabNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* <p>
* Wrapper for {@link InterestRateChartSlabRepository} that is responsible for checking if {@link InterestRateChartSlab}
* is returned when using <code>findOne</code> repository method and throwing an appropriate not found exception.
* </p>
*
* <p>
* This is to avoid need for checking and throwing in multiple areas of code base where
* {@link InterestRateChartSlabRepository} is required.
* </p>
*/
@Service
public class InterestRateChartSlabRepositoryWrapper {
private final InterestRateChartSlabRepository repository;
@Autowired
public InterestRateChartSlabRepositoryWrapper(final InterestRateChartSlabRepository repository) {
this.repository = repository;
}
public InterestRateChartSlab findOneWithNotFoundDetection(final Long chartSlabId) {
return this.repository.findById(chartSlabId).orElseThrow(() -> new InterestRateChartSlabNotFoundException(chartSlabId));
}
public void save(final InterestRateChartSlab chartSlab) {
this.repository.save(chartSlab);
}
public void delete(final InterestRateChartSlab chartSlab) {
this.repository.delete(chartSlab);
}
public void saveAndFlush(final InterestRateChartSlab chartSlab) {
this.repository.saveAndFlush(chartSlab);
}
}
@@ -1,33 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
import org.springframework.dao.EmptyResultDataAccessException;
public class InterestRateChartNotFoundException extends AbstractPlatformResourceNotFoundException {
public InterestRateChartNotFoundException(final Long id) {
super("error.msg.interest.rate.chart.id.invalid", "Interest rate chart with identifier " + id + " does not exist", id);
}
public InterestRateChartNotFoundException(Long id, EmptyResultDataAccessException e) {
super("error.msg.interest.rate.chart.id.invalid", "Interest rate chart with identifier " + id + " does not exist", id, e);
}
}
@@ -1,34 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class InterestRateChartSlabNotFoundException extends AbstractPlatformResourceNotFoundException {
public InterestRateChartSlabNotFoundException(final Long id) {
super("error.msg.interest.rate.chart.slab.id.invalid", "Interest rate chart slab with identifier " + id + " does not exist", id);
}
public InterestRateChartSlabNotFoundException(final Long id, final Long chartId) {
super("error.msg.interest.rate.chart.slab.id.invalid",
"Interest rate chart slab with identifier " + id + " does not exist in interest chart with identifier " + chartId, id,
chartId);
}
}
@@ -1,50 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.incentive;
import java.math.BigDecimal;
import org.apache.fineract.portfolio.common.domain.ConditionType;
public abstract class AttributeIncentiveCalculation {
public abstract BigDecimal calculateIncentive(IncentiveDTO incentiveDTO);
public boolean applyIncentive(ConditionType conditionType, Long attributeValue, Long actualValue) {
boolean applyIncentive = false;
int compareVal = actualValue.compareTo(attributeValue);
switch (conditionType) {
case LESSTHAN:
applyIncentive = compareVal < 0;
break;
case EQUAL:
applyIncentive = compareVal == 0;
break;
case NOT_EQUAL:
applyIncentive = compareVal != 0;
break;
case GRETERTHAN:
applyIncentive = compareVal > 0;
break;
default:
applyIncentive = false;
break;
}
return applyIncentive;
}
}
@@ -1,39 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.incentive;
public final class AttributeIncentiveCalculationFactory {
private AttributeIncentiveCalculationFactory() {
}
public static AttributeIncentiveCalculation findAttributeIncentiveCalculation(InterestIncentiveEntityType entityType) {
AttributeIncentiveCalculation attributeIncentiveCalculation = null;
switch (entityType) {
case CUSTOMER:
attributeIncentiveCalculation = new ClientAttributeIncentiveCalculation();
break;
default:
break;
}
return attributeIncentiveCalculation;
}
}
@@ -1,85 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.incentive;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.portfolio.client.domain.Client;
import org.apache.fineract.portfolio.interestratechart.domain.InterestIncentivesFields;
public class ClientAttributeIncentiveCalculation extends AttributeIncentiveCalculation {
@Override
public BigDecimal calculateIncentive(IncentiveDTO incentiveDTO) {
final Client client = incentiveDTO.client();
BigDecimal interest = incentiveDTO.interest();
final InterestIncentivesFields incentivesFields = incentiveDTO.incentives();
boolean applyIncentive = false;
switch (incentivesFields.attributeName()) {
case GENDER:
if (client.genderId() != null) {
applyIncentive = applyIncentive(incentivesFields.conditionType(), Long.valueOf(incentivesFields.attributeValue()),
client.genderId());
}
break;
case AGE:
if (client.dateOfBirth() != null) {
final LocalDate dobLocalDate = client.dateOfBirth();
final int age = Math.toIntExact(ChronoUnit.YEARS.between(dobLocalDate, DateUtils.getBusinessLocalDate()));
applyIncentive = applyIncentive(incentivesFields.conditionType(), Long.valueOf(incentivesFields.attributeValue()),
(long) age);
}
break;
case CLIENT_TYPE:
if (client.clientTypeId() != null) {
applyIncentive = applyIncentive(incentivesFields.conditionType(), Long.valueOf(incentivesFields.attributeValue()),
client.clientTypeId());
}
break;
case CLIENT_CLASSIFICATION:
if (client.clientClassificationId() != null) {
applyIncentive = applyIncentive(incentivesFields.conditionType(), Long.valueOf(incentivesFields.attributeValue()),
client.clientClassificationId());
}
break;
default:
break;
}
if (applyIncentive) {
switch (incentivesFields.incentiveType()) {
case FIXED:
interest = incentivesFields.amount();
break;
case INCENTIVE:
interest = interest.add(incentivesFields.amount());
break;
default:
break;
}
}
return interest;
}
}
@@ -1,48 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.incentive;
import java.math.BigDecimal;
import org.apache.fineract.portfolio.client.domain.Client;
import org.apache.fineract.portfolio.interestratechart.domain.InterestIncentivesFields;
public class IncentiveDTO {
private final Client client;
private final BigDecimal interest;
private final InterestIncentivesFields incentives;
public IncentiveDTO(final Client client, final BigDecimal interest, final InterestIncentivesFields incentives) {
this.client = client;
this.interest = interest;
this.incentives = incentives;
}
public Client client() {
return this.client;
}
public BigDecimal interest() {
return this.interest;
}
public InterestIncentivesFields incentives() {
return this.incentives;
}
}
@@ -1,108 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.incentive;
import java.util.Arrays;
public enum InterestIncentiveAttributeName {
INVALID(1, "InterestIncentiveAttributeName.invalid"), //
GENDER(2, "InterestIncentiveAttributeName.gender"), //
AGE(3, "InterestIncentiveAttributeName.age"), //
CLIENT_TYPE(4, "InterestIncentiveAttributeName.clientType"), //
CLIENT_CLASSIFICATION(5, "InterestIncentiveAttributeName.clientClassification"); //
private final Integer value;
private final String code;
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;
}
}
InterestIncentiveAttributeName(final Integer value, final String code) {
this.value = value;
this.code = code;
}
@Override
public String toString() {
return name().toString().replaceAll("_", " ");
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return this.code;
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isGender() {
return GENDER.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isAge() {
return AGE.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isClientType() {
return CLIENT_TYPE.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isClientClassification() {
return CLIENT_CLASSIFICATION.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isInvalid() {
return INVALID.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public static boolean isCodeValueAttribute(InterestIncentiveAttributeName attributeName) {
switch (attributeName) {
case GENDER:
case CLIENT_TYPE:
case CLIENT_CLASSIFICATION:
return true;
default:
return false;
}
}
// TODO: do we really need this?!?
public static Object[] integerValues() {
return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
}
}
@@ -1,77 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.incentive;
import java.util.Arrays;
public enum InterestIncentiveEntityType {
INVALID(1, "InterestIncentiveEntityType.invalid"), //
CUSTOMER(2, "InterestIncentiveEntityType.customer"), //
ACCOUNT(3, "InterestIncentiveEntityType.account"); //
private final Integer value;
private final String code;
public static InterestIncentiveEntityType fromInt(final Integer v) {
if (v == null) {
return INVALID;
}
switch (v) {
case 2:
return CUSTOMER;
case 3:
return ACCOUNT;
default:
return INVALID;
}
}
InterestIncentiveEntityType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
@Override
public String toString() {
return name().toString().replaceAll("_", " ");
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return this.code;
}
public boolean isCustomer() {
return CUSTOMER.equals(this);
}
public boolean isInvalid() {
return INVALID.equals(this);
}
// TODO: do we really need this?!?
public static Object[] integerValues() {
return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
}
}
@@ -1,84 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.incentive;
import java.util.Arrays;
public enum InterestIncentiveType {
INVALID(1, "InterestIncentiveType.invalid"), //
FIXED(2, "InterestIncentiveType.fixed"), //
INCENTIVE(3, "InterestIncentiveType.incentive"); //
private final Integer value;
private final String code;
public static InterestIncentiveType fromInt(final Integer v) {
if (v == null) {
return INVALID;
}
switch (v) {
case 2:
return FIXED;
case 3:
return INCENTIVE;
default:
return INVALID;
}
}
InterestIncentiveType(final Integer value, final String code) {
this.value = value;
this.code = code;
}
@Override
public String toString() {
return name().toString().replaceAll("_", " ");
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return this.code;
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isIncentive() {
return INCENTIVE.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isFixed() {
return FIXED.equals(this);
}
// TODO: why not just use the enum values... just more boilerplate code here!!
public boolean isInvalid() {
return INVALID.equals(this);
}
// TODO: do we really need this?!?
public static Object[] integerValues() {
return Arrays.stream(values()).filter(value -> !INVALID.equals(value)).map(value -> value.value).toList().toArray();
}
}
@@ -1,98 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.service;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.INCENTIVE_RESOURCE_NAME;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.amountParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.attributeNameParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.attributeValueParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.conditionTypeParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.entityTypeParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants.incentiveTypeparamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.incentivesParamName;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.interestratechart.domain.InterestIncentives;
import org.apache.fineract.portfolio.interestratechart.domain.InterestIncentivesFields;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartSlab;
@RequiredArgsConstructor
public class InterestIncentiveAssembler {
private final FromJsonHelper fromApiJsonHelper;
public Collection<InterestIncentives> assembleIncentivesFrom(final JsonElement element, InterestRateChartSlab interestRateChartSlab,
final Locale locale) {
final Collection<InterestIncentives> interestIncentivesSet = new HashSet<>();
if (element.isJsonObject()) {
final JsonObject topLevelJsonElement = element.getAsJsonObject();
if (topLevelJsonElement.has(incentivesParamName) && topLevelJsonElement.get(incentivesParamName).isJsonArray()) {
final JsonArray array = topLevelJsonElement.get(incentivesParamName).getAsJsonArray();
for (int i = 0; i < array.size(); i++) {
final JsonObject incentiveElement = array.get(i).getAsJsonObject();
final InterestIncentives incentives = this.assembleFrom(incentiveElement, interestRateChartSlab, locale);
interestIncentivesSet.add(incentives);
}
}
}
return interestIncentivesSet;
}
private InterestIncentives assembleFrom(final JsonElement element, final InterestRateChartSlab interestRateChartSlab,
final Locale locale) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(INCENTIVE_RESOURCE_NAME);
InterestIncentivesFields incentivesFields = createInterestIncentiveFields(element, baseDataValidator, locale);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
return new InterestIncentives(interestRateChartSlab, incentivesFields);
}
private InterestIncentivesFields createInterestIncentiveFields(final JsonElement element, final DataValidatorBuilder baseDataValidator,
final Locale locale) {
Integer entityType = this.fromApiJsonHelper.extractIntegerNamed(entityTypeParamName, element, locale);
Integer conditionType = this.fromApiJsonHelper.extractIntegerNamed(conditionTypeParamName, element, locale);
Integer attributeName = this.fromApiJsonHelper.extractIntegerNamed(attributeNameParamName, element, locale);
String attributeValue = this.fromApiJsonHelper.extractStringNamed(attributeValueParamName, element);
Integer incentiveType = this.fromApiJsonHelper.extractIntegerNamed(incentiveTypeparamName, element, locale);
BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalNamed(amountParamName, element, locale);
return InterestIncentivesFields.createNew(entityType, attributeName, conditionType, attributeValue, incentiveType, amount,
baseDataValidator);
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
}
}
@@ -1,99 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.service;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.INTERESTRATE_CHART_RESOURCE_NAME;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.endDateParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.fromDateParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.isPrimaryGroupingByAmountParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.nameParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.currencyCodeParamName;
import com.google.gson.JsonElement;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChart;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartFields;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartRepositoryWrapper;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartSlab;
@RequiredArgsConstructor
public class InterestRateChartAssembler {
private final FromJsonHelper fromApiJsonHelper;
private final InterestRateChartRepositoryWrapper interestRateChartRepositoryWrapper;
private final InterestRateChartSlabAssembler chartSlabAssembler;
/**
* Assembles a new {@link InterestRateChart} from JSON Slabs passed in request
*/
public InterestRateChart assembleFrom(final JsonCommand command) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_RESOURCE_NAME);
final JsonElement element = command.parsedJson();
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(currencyCodeParamName, element);
final InterestRateChart newChart = this.assembleFrom(element, currencyCode, baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
return newChart;
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
}
public InterestRateChart assembleFrom(final JsonElement element, final String currencyCode,
final DataValidatorBuilder baseDataValidator) {
final String name = this.fromApiJsonHelper.extractStringNamed(nameParamName, element);
final String description = this.fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
final LocalDate fromDate = this.fromApiJsonHelper.extractLocalDateNamed(fromDateParamName, element);
final LocalDate toDate = this.fromApiJsonHelper.extractLocalDateNamed(endDateParamName, element);
Boolean isPrimaryGroupingByAmount = this.fromApiJsonHelper.extractBooleanNamed(isPrimaryGroupingByAmountParamName, element);
if (isPrimaryGroupingByAmount == null) {
isPrimaryGroupingByAmount = false;
}
// assemble chart Slabs
final Collection<InterestRateChartSlab> newChartSlabs = this.chartSlabAssembler.assembleChartSlabsFrom(element, currencyCode);
final InterestRateChartFields fields = InterestRateChartFields.createNew(name, description, fromDate, toDate,
isPrimaryGroupingByAmount);
final InterestRateChart newChart = InterestRateChart.createNew(fields, newChartSlabs);
newChart.validateChartSlabs(baseDataValidator);
return newChart;
}
public InterestRateChart assembleFrom(final Long interestRateChartId) {
final InterestRateChart interestRateChart = this.interestRateChartRepositoryWrapper
.findOneWithNotFoundDetection(interestRateChartId);
return interestRateChart;
}
}
@@ -1,142 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.interestratechart.service;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.chartSlabs;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConstants.descriptionParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.INTERESTRATE_CHART_SLAB_RESOURCE_NAME;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.amountRangeFromParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.amountRangeToParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.annualInterestRateParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.currencyCodeParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.fromPeriodParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.periodTypeParamName;
import static org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants.toPeriodParamName;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChart;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartRepositoryWrapper;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartSlab;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartSlabFields;
import org.apache.fineract.portfolio.interestratechart.exception.InterestRateChartSlabNotFoundException;
import org.apache.fineract.portfolio.savings.SavingsPeriodFrequencyType;
@RequiredArgsConstructor
public class InterestRateChartSlabAssembler {
private final FromJsonHelper fromApiJsonHelper;
private final InterestRateChartRepositoryWrapper interestRateChartRepositoryWrapper;
private final InterestIncentiveAssembler incentiveAssembler;
/**
* Assembles a new {@link InterestRateChartSlab} from JSON Slabs passed in request
*/
public InterestRateChartSlab assembleFrom(final JsonCommand command) {
final JsonElement element = command.parsedJson();
final JsonObject elementObject = element.getAsJsonObject();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(elementObject);
final String currencyCode = command.stringValueOfParameterNamed(currencyCodeParamName);
final Long chartId = command.subentityId();// returns chart id
final InterestRateChart chart = this.interestRateChartRepositoryWrapper.findOneWithNotFoundDetection(chartId);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(INTERESTRATE_CHART_SLAB_RESOURCE_NAME);
final InterestRateChartSlab newChartSlab = assembleChartSlabs(chart, elementObject, currencyCode, locale);
// validate chart Slabs
newChartSlab.slabFields().validateChartSlabPlatformRules(command, baseDataValidator, locale);
chart.validateChartSlabs(baseDataValidator);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
return newChartSlab;
}
private InterestRateChartSlab assembleChartSlabs(final InterestRateChart interestRateChart, final JsonElement element,
final String currencyCode, final Locale locale) {
final String description = this.fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
final Integer periodTypeId = this.fromApiJsonHelper.extractIntegerNamed(periodTypeParamName, element, locale);
final SavingsPeriodFrequencyType periodType = SavingsPeriodFrequencyType.fromInt(periodTypeId);
final Integer fromPeriod = this.fromApiJsonHelper.extractIntegerNamed(fromPeriodParamName, element, locale);
final Integer toPeriod = this.fromApiJsonHelper.extractIntegerNamed(toPeriodParamName, element, locale);
final BigDecimal amountRangeFrom = this.fromApiJsonHelper.extractBigDecimalNamed(amountRangeFromParamName, element, locale);
final BigDecimal amountRangeTo = this.fromApiJsonHelper.extractBigDecimalNamed(amountRangeToParamName, element, locale);
final BigDecimal annualInterestRate = this.fromApiJsonHelper.extractBigDecimalNamed(annualInterestRateParamName, element, locale);
final InterestRateChartSlabFields slabFields = InterestRateChartSlabFields.createNew(description, periodType, fromPeriod, toPeriod,
amountRangeFrom, amountRangeTo, annualInterestRate, currencyCode);
InterestRateChartSlab interestRateChartSlab = InterestRateChartSlab.createNew(slabFields, interestRateChart);
this.incentiveAssembler.assembleIncentivesFrom(element, interestRateChartSlab, locale);
return interestRateChartSlab;
}
public InterestRateChartSlab assembleFrom(final Long chartSlabId, final Long chartId) {
final InterestRateChart chart = this.interestRateChartRepositoryWrapper.findOneWithNotFoundDetection(chartId);
final InterestRateChartSlab interestRateChartSlab = chart.findChartSlab(chartSlabId);
if (interestRateChartSlab == null) {
throw new InterestRateChartSlabNotFoundException(chartSlabId, chartId);
}
return interestRateChartSlab;
}
public Collection<InterestRateChartSlab> assembleChartSlabsFrom(final JsonElement element, String currencyCode) {
final Collection<InterestRateChartSlab> interestRateChartSlabsSet = new HashSet<>();
if (element.isJsonObject()) {
final JsonObject topLevelJsonElement = element.getAsJsonObject();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
if (topLevelJsonElement.has(chartSlabs) && topLevelJsonElement.get(chartSlabs).isJsonArray()) {
final JsonArray array = topLevelJsonElement.get(chartSlabs).getAsJsonArray();
for (int i = 0; i < array.size(); i++) {
final JsonObject interstRateChartElement = array.get(i).getAsJsonObject();
final InterestRateChartSlab chartSlab = this.assembleChartSlabs(null, interstRateChartElement, currencyCode, locale);
interestRateChartSlabsSet.add(chartSlab);
}
}
}
return interestRateChartSlabsSet;
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
}
}
@@ -40,6 +40,7 @@ import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
import org.apache.fineract.organisation.holiday.domain.Holiday;
import org.apache.fineract.organisation.holiday.domain.HolidayRepository;
import org.apache.fineract.organisation.holiday.domain.HolidayStatusType;
import org.apache.fineract.organisation.monetary.exception.InvalidCurrencyException;
import org.apache.fineract.organisation.staff.domain.Staff;
import org.apache.fineract.organisation.staff.domain.StaffRepository;
import org.apache.fineract.organisation.staff.exception.StaffNotFoundException;
@@ -84,7 +85,6 @@ import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
import org.apache.fineract.portfolio.loanproduct.exception.InvalidCurrencyException;
import org.apache.fineract.portfolio.loanproduct.exception.LinkedAccountRequiredException;
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException;
import org.apache.fineract.portfolio.rate.domain.Rate;
@@ -60,6 +60,7 @@ import org.apache.fineract.infrastructure.event.business.domain.loan.transaction
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.Money;
import org.apache.fineract.organisation.monetary.exception.InvalidCurrencyException;
import org.apache.fineract.portfolio.account.PortfolioAccountType;
import org.apache.fineract.portfolio.account.data.AccountTransferDTO;
import org.apache.fineract.portfolio.account.data.PortfolioAccountData;
@@ -126,7 +127,6 @@ import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.DefaultSche
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.ScheduledDateGenerator;
import org.apache.fineract.portfolio.loanaccount.serialization.LoanChargeApiJsonValidator;
import org.apache.fineract.portfolio.loanproduct.data.LoanOverdueDTO;
import org.apache.fineract.portfolio.loanproduct.exception.InvalidCurrencyException;
import org.apache.fineract.portfolio.loanproduct.exception.LinkedAccountRequiredException;
import org.apache.fineract.portfolio.note.domain.Note;
import org.apache.fineract.portfolio.note.domain.NoteRepository;
@@ -1,32 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.loanproduct.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* {@link AbstractPlatformDomainRuleException} thrown when currency mismatch occurs
*/
public class InvalidCurrencyException extends AbstractPlatformDomainRuleException {
public InvalidCurrencyException(final String entity, final String postFix, final String defaultUserMessage,
final Object... defaultUserMessageArgs) {
super("error.msg." + entity + "." + postFix + ".invalid.currency", defaultUserMessage, defaultUserMessageArgs);
}
}
@@ -40,6 +40,7 @@ import org.apache.fineract.infrastructure.entityaccess.service.FineractEntityAcc
import org.apache.fineract.infrastructure.event.business.domain.loan.product.LoanProductCreateBusinessEvent;
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.organisation.monetary.exception.InvalidCurrencyException;
import org.apache.fineract.portfolio.charge.domain.Charge;
import org.apache.fineract.portfolio.charge.domain.ChargeRepositoryWrapper;
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket;
@@ -58,7 +59,6 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductCreditAllocationRule;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductPaymentAllocationRule;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
import org.apache.fineract.portfolio.loanproduct.exception.InvalidCurrencyException;
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductCannotBeModifiedDueToNonClosedLoansException;
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductDateException;
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException;
@@ -26,6 +26,8 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface NoteRepository extends JpaRepository<Note, Long>, JpaSpecificationExecutor<Note> {
@@ -46,4 +48,8 @@ public interface NoteRepository extends JpaRepository<Note, Long>, JpaSpecificat
List<Note> findBySavingsAccount(SavingsAccount savingAccount);
Note findBySavingsAccountAndId(SavingsAccount savingAccount, Long id);
@Query("select note from Note note where note.savingsTransaction.id = :savingsTransactionId")
List<Note> findBySavingsTransactionId(@Param("savingsTransactionId") Long savingsTransactionId);
}
@@ -1,71 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings;
import java.time.LocalDate;
import org.apache.fineract.portfolio.calendar.domain.CalendarFrequencyType;
import org.apache.fineract.portfolio.calendar.service.CalendarUtils;
import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class DepositAccountUtils {
private DepositAccountUtils() {
}
private static final Logger LOG = LoggerFactory.getLogger(DepositAccountUtils.class);
public static final int GENERATE_MINIMUM_NUMBER_OF_FUTURE_INSTALMENTS = 5;
public static LocalDate calculateNextDepositDate(final LocalDate lastDepositDate, final PeriodFrequencyType frequency,
final int recurringEvery) {
LocalDate nextDepositDate = lastDepositDate;
switch (frequency) {
case DAYS:
nextDepositDate = lastDepositDate.plusDays(recurringEvery);
break;
case WEEKS:
nextDepositDate = lastDepositDate.plusWeeks(recurringEvery);
break;
case MONTHS:
nextDepositDate = lastDepositDate.plusMonths(recurringEvery);
break;
case YEARS:
nextDepositDate = lastDepositDate.plusYears(recurringEvery);
break;
case INVALID:
break;
case WHOLE_TERM:
LOG.error("TODO Implement calculateNextDepositDate for WHOLE_TERM");
break;
}
return nextDepositDate;
}
public static LocalDate calculateNextDepositDate(final LocalDate lastDepositDate, final String recurrence) {
final PeriodFrequencyType frequencyType = CalendarFrequencyType.from(CalendarUtils.getFrequency(recurrence));
Integer frequency = CalendarUtils.getInterval(recurrence);
frequency = frequency == -1 ? 1 : frequency;
return calculateNextDepositDate(lastDepositDate, frequencyType, frequency);
}
}
@@ -1,59 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings;
public class SavingsTransactionBooleanValues {
private final boolean isAccountTransfer;
private final boolean isRegularTransaction;
private final boolean isApplyWithdrawFee;
private final boolean isInterestTransfer;
private final boolean isExceptionForBalanceCheck;
public SavingsTransactionBooleanValues(final boolean isAccountTransfer, final boolean isRegularTransaction,
final boolean isApplyWithdrawFee, final boolean isInterestTransfer, final boolean isExceptionForBalanceCheck) {
this.isAccountTransfer = isAccountTransfer;
this.isRegularTransaction = isRegularTransaction;
this.isApplyWithdrawFee = isApplyWithdrawFee;
this.isInterestTransfer = isInterestTransfer;
this.isExceptionForBalanceCheck = isExceptionForBalanceCheck;
}
public boolean isAccountTransfer() {
return this.isAccountTransfer;
}
public boolean isRegularTransaction() {
return this.isRegularTransaction;
}
public boolean isApplyWithdrawFee() {
return this.isApplyWithdrawFee;
}
public boolean isInterestTransfer() {
return this.isInterestTransfer;
}
public boolean isExceptionForBalanceCheck() {
return this.isExceptionForBalanceCheck;
}
}
@@ -1,74 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.api;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.apache.fineract.portfolio.savings.SavingsApiConstants;
import org.apache.fineract.portfolio.savings.data.SavingsAccountData;
import org.apache.fineract.portfolio.savings.data.SavingsProductData;
public class SavingsApiSetConstants extends SavingsApiConstants {
/**
* These parameters will match the class level parameters of {@link SavingsProductData}. Where possible, we try to
* get response parameters to match those of request parameters.
*/
protected static final Set<String> SAVINGS_PRODUCT_RESPONSE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(idParamName, nameParamName, shortNameParamName, descriptionParamName, "currency", digitsAfterDecimalParamName,
inMultiplesOfParamName, nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName,
interestPostingPeriodTypeParamName, interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName,
minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName,
withdrawalFeeAmountParamName, withdrawalFeeTypeParamName, withdrawalFeeForTransfersParamName, feeAmountParamName,
feeOnMonthDayParamName, "currencyOptions", "interestCompoundingPeriodTypeOptions", "interestPostingPeriodTypeOptions",
"interestCalculationTypeOptions", "interestCalculationDaysInYearTypeOptions", "lockinPeriodFrequencyTypeOptions",
"withdrawalFeeTypeOptions", nominalAnnualInterestRateOverdraftParamName, minOverdraftForInterestCalculationParamName,
withHoldTaxParamName, taxGroupIdParamName, isDormancyTrackingActiveParamName, daysToInactiveParamName,
daysToDormancyParamName, daysToInactiveParamName, accountMappingForPaymentParamName));
/**
* These parameters will match the class level parameters of {@link SavingsAccountData}. Where possible, we try to
* get response parameters to match those of request parameters.
*/
protected static final Set<String> SAVINGS_ACCOUNT_RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList(idParamName,
accountNoParamName, externalIdParamName, statusParamName, activatedOnDateParamName, staffIdParamName, clientIdParamName,
"clientName", groupIdParamName, "groupName", "savingsProductId", "savingsProductName", "currency",
nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName, interestCalculationTypeParamName,
interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName, lockinPeriodFrequencyParamName,
lockinPeriodFrequencyTypeParamName, withdrawalFeeAmountParamName, withdrawalFeeTypeParamName,
withdrawalFeeForTransfersParamName, feeAmountParamName, feeOnMonthDayParamName, "summary", "transactions", "productOptions",
"interestCompoundingPeriodTypeOptions", "interestPostingPeriodTypeOptions", "interestCalculationTypeOptions",
"interestCalculationDaysInYearTypeOptions", "lockinPeriodFrequencyTypeOptions", "withdrawalFeeTypeOptions", "withdrawalFee",
"annualFee", onHoldFundsParamName, nominalAnnualInterestRateOverdraftParamName, minOverdraftForInterestCalculationParamName,
datatables, savingsAmountOnHold, accountMappingForPaymentParamName, interestPostedTillDate));
protected static final Set<String> SAVINGS_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(idParamName, "accountId", accountNoParamName, "currency", "amount", dateParamName, paymentDetailDataParamName,
runningBalanceParamName, reversedParamName, noteParamName));
protected static final Set<String> SAVINGS_ACCOUNT_CHARGES_RESPONSE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(chargeIdParamName, savingsAccountChargeIdParamName, chargeNameParamName, penaltyParamName,
chargeTimeTypeParamName, dueAsOfDateParamName, chargeCalculationTypeParamName, percentageParamName,
amountPercentageAppliedToParamName, currencyParamName, amountWaivedParamName, amountWrittenOffParamName,
amountOutstandingParamName, amountOrPercentageParamName, amountParamName, amountPaidParamName, chargeOptionsParamName));
protected static final Set<String> SAVINGS_ACCOUNT_ON_HOLD_RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList(idParamName,
amountParamName, onHoldTransactionTypeParamName, onHoldTransactionDateParamName, onHoldReversedParamName));
}
@@ -1,97 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.time.LocalDate;
public final class ClosingOfSavingsAccounts {
private final transient Integer rowIndex;
private final transient Long accountId;
private final LocalDate closedOnDate;
private final Long onAccountClosureId;
private final Long toSavingsAccountId;
private final String dateFormat;
private final String accountType;
private final String locale;
private final String note;
public static ClosingOfSavingsAccounts importInstance(Long accountId, LocalDate closedOnDate, Long onAccountClosureId,
Long toSavingsAccountId, String accountType, Integer rowIndex, String locale, String dateFormat) {
return new ClosingOfSavingsAccounts(accountId, closedOnDate, onAccountClosureId, toSavingsAccountId, accountType, rowIndex, locale,
dateFormat);
}
private ClosingOfSavingsAccounts(Long accountId, LocalDate closedOnDate, Long onAccountClosureId, Long toSavingsAccountId,
String accountType, Integer rowIndex, String locale, String dateFormat) {
this.accountId = accountId;
this.closedOnDate = closedOnDate;
this.onAccountClosureId = onAccountClosureId;
this.toSavingsAccountId = toSavingsAccountId;
this.accountType = accountType;
this.rowIndex = rowIndex;
this.dateFormat = dateFormat;
this.locale = locale;
this.note = "";
}
public Integer getRowIndex() {
return rowIndex;
}
public Long getAccountId() {
return accountId;
}
public LocalDate getClosedOnDate() {
return closedOnDate;
}
public Long getOnAccountClosureId() {
return onAccountClosureId;
}
public Long getToSavingsAccountId() {
return toSavingsAccountId;
}
public String getDateFormat() {
return dateFormat;
}
public String getAccountType() {
return accountType;
}
public String getLocale() {
return locale;
}
public String getNote() {
return note;
}
}
@@ -1,338 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.HashSet;
import lombok.Getter;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.organisation.staff.data.StaffData;
import org.apache.fineract.portfolio.charge.data.ChargeData;
import org.apache.fineract.portfolio.tax.data.TaxGroupData;
/**
* Immutable data object representing abstract for Fixed and Recurring Deposit Accounts Accounts.
*/
@Getter
public class DepositAccountData {
protected final Long id;
protected final String accountNo;
protected final String externalId;
protected final Long groupId;
protected final String groupName;
protected final Long clientId;
protected final String clientName;
protected final Long depositProductId;
protected final String depositProductName;
protected final Long fieldOfficerId;
protected final String fieldOfficerName;
protected final SavingsAccountStatusEnumData status;
protected final SavingsAccountApplicationTimelineData timeline;
protected final CurrencyData currency;
protected final BigDecimal nominalAnnualInterestRate;
protected final EnumOptionData interestCompoundingPeriodType;
protected final EnumOptionData interestPostingPeriodType;
protected final EnumOptionData interestCalculationType;
protected final EnumOptionData interestCalculationDaysInYearType;
protected final BigDecimal minRequiredOpeningBalance;
protected final Integer lockinPeriodFrequency;
protected final EnumOptionData lockinPeriodFrequencyType;
protected final boolean withdrawalFeeForTransfers;
protected final EnumOptionData depositType;
protected final BigDecimal minBalanceForInterestCalculation;
protected final boolean withHoldTax;
protected final TaxGroupData taxGroup;
// associations
protected final SavingsAccountSummaryData summary;
protected final Collection<SavingsAccountTransactionData> transactions;
protected final Collection<SavingsAccountChargeData> charges;
protected final DepositAccountInterestRateChartData accountChart;
// template
protected final Collection<DepositProductData> productOptions;
protected final Collection<StaffData> fieldOfficerOptions;
protected final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions;
protected final Collection<EnumOptionData> interestPostingPeriodTypeOptions;
protected final Collection<EnumOptionData> interestCalculationTypeOptions;
protected final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions;
protected final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
protected final Collection<EnumOptionData> withdrawalFeeTypeOptions;
protected final Collection<ChargeData> chargeOptions;
protected final SavingsAccountChargeData withdrawalFee;
protected final SavingsAccountChargeData annualFee;
protected final DepositAccountInterestRateChartData chartTemplate;
// import fields
private Long productId;
public DepositAccountData(Long clientId, Long productId, Long fieldOfficerId, EnumOptionData interestCompoundingPeriodType,
EnumOptionData interestPostingPeriodType, EnumOptionData interestCalculationType,
EnumOptionData interestCalculationDaysInYearType, Integer lockinPeriodFrequency, EnumOptionData lockinPeriodFrequencyType,
String externalId, Collection<SavingsAccountChargeData> charges) {
this.id = null;
this.accountNo = null;
this.externalId = externalId;
this.groupId = null;
this.groupName = null;
this.clientId = clientId;
this.clientName = null;
this.depositProductId = null;
this.depositProductName = null;
this.fieldOfficerId = fieldOfficerId;
this.fieldOfficerName = null;
this.status = null;
this.timeline = null;
this.currency = null;
this.nominalAnnualInterestRate = null;
this.interestCompoundingPeriodType = interestCompoundingPeriodType;
this.interestPostingPeriodType = interestPostingPeriodType;
this.interestCalculationType = interestCalculationType;
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
this.minRequiredOpeningBalance = null;
this.lockinPeriodFrequency = lockinPeriodFrequency;
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
this.withdrawalFeeForTransfers = false;
this.depositType = null;
this.minBalanceForInterestCalculation = null;
this.withHoldTax = false;
this.taxGroup = null;
this.summary = null;
this.transactions = null;
this.charges = charges;
this.accountChart = null;
this.productOptions = null;
this.fieldOfficerOptions = null;
this.interestCompoundingPeriodTypeOptions = null;
this.interestPostingPeriodTypeOptions = null;
this.interestCalculationTypeOptions = null;
this.interestCalculationDaysInYearTypeOptions = null;
this.lockinPeriodFrequencyTypeOptions = null;
this.withdrawalFeeTypeOptions = null;
this.chargeOptions = null;
this.withdrawalFee = null;
this.annualFee = null;
this.chartTemplate = null;
this.productId = productId;
}
public static DepositAccountData instance(final Long id, final String accountNo, final String externalId, final Long groupId,
final String groupName, final Long clientId, final String clientName, final Long productId, final String productName,
final Long fieldOfficerId, final String fieldOfficerName, final SavingsAccountStatusEnumData status,
final SavingsAccountApplicationTimelineData timeline, final CurrencyData currency, final BigDecimal interestRate,
final EnumOptionData interestCompoundingPeriodType, final EnumOptionData interestPostingPeriodType,
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType,
final boolean withdrawalFeeForTransfers, final SavingsAccountSummaryData summary, final EnumOptionData depositType,
final BigDecimal minBalanceForInterestCalculation, final boolean withHoldTax, final TaxGroupData taxGroup) {
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<SavingsAccountChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final DepositAccountInterestRateChartData accountChart = null;
final DepositAccountInterestRateChartData chartTemplate = null;
return new DepositAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
fieldOfficerId, fieldOfficerName, status, timeline, currency, interestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions, productOptions,
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, charges,
chargeOptions, accountChart, chartTemplate, depositType, minBalanceForInterestCalculation, withHoldTax, taxGroup);
}
public static DepositAccountData lookup(final Long id, final String accountNo, final EnumOptionData depositType) {
final String externalId = null;
final Long groupId = null;
final String groupName = null;
final Long clientId = null;
final String clientName = null;
final Long productId = null;
final String productName = null;
final Long fieldOfficerId = null;
final String fieldOfficerName = null;
final SavingsAccountStatusEnumData status = null;
final SavingsAccountApplicationTimelineData timeline = null;
final CurrencyData currency = null;
final BigDecimal interestRate = null;
final EnumOptionData interestCompoundingPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final BigDecimal minRequiredOpeningBalance = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final boolean withdrawalFeeForTransfers = false;
final SavingsAccountSummaryData summary = null;
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<SavingsAccountChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final DepositAccountInterestRateChartData accountChart = null;
final DepositAccountInterestRateChartData chartTemplate = null;
final BigDecimal minBalanceForInterestCalculation = null;
final boolean withHoldTax = false;
final TaxGroupData taxGroup = null;
return new DepositAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
fieldOfficerId, fieldOfficerName, status, timeline, currency, interestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions, productOptions,
fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, charges,
chargeOptions, accountChart, chartTemplate, depositType, minBalanceForInterestCalculation, withHoldTax, taxGroup);
}
protected DepositAccountData(final Long id, final String accountNo, final String externalId, final Long groupId, final String groupName,
final Long clientId, final String clientName, final Long productId, final String productName, final Long fieldOfficerId,
final String fieldOfficerName, final SavingsAccountStatusEnumData status, final SavingsAccountApplicationTimelineData timeline,
final CurrencyData currency, final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType, final boolean withdrawalFeeForTransfers,
final SavingsAccountSummaryData summary, final Collection<SavingsAccountTransactionData> transactions,
final Collection<DepositProductData> productOptions, final Collection<StaffData> fieldOfficerOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<SavingsAccountChargeData> charges, final Collection<ChargeData> chargeOptions,
final DepositAccountInterestRateChartData accountChart, final DepositAccountInterestRateChartData chartTemplate,
final EnumOptionData depositType, final BigDecimal minBalanceForInterestCalculation, final boolean withHoldTax,
final TaxGroupData taxGroup) {
this.id = id;
this.accountNo = accountNo;
this.externalId = externalId;
this.groupId = groupId;
this.groupName = groupName;
this.clientId = clientId;
this.clientName = clientName;
this.depositProductId = productId;
this.depositProductName = productName;
this.fieldOfficerId = fieldOfficerId;
this.fieldOfficerName = fieldOfficerName;
this.status = status;
this.timeline = timeline;
this.currency = currency;
this.nominalAnnualInterestRate = nominalAnnualInterestRate;
this.interestCompoundingPeriodType = interestPeriodType;
this.interestPostingPeriodType = interestPostingPeriodType;
this.interestCalculationType = interestCalculationType;
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
this.minRequiredOpeningBalance = minRequiredOpeningBalance;
this.lockinPeriodFrequency = lockinPeriodFrequency;
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
this.withdrawalFeeForTransfers = withdrawalFeeForTransfers;
this.summary = summary;
this.transactions = transactions;
this.productOptions = productOptions;
this.fieldOfficerOptions = fieldOfficerOptions;
this.interestCompoundingPeriodTypeOptions = interestCompoundingPeriodTypeOptions;
this.interestPostingPeriodTypeOptions = interestPostingPeriodTypeOptions;
this.interestCalculationTypeOptions = interestCalculationTypeOptions;
this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions;
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
this.withdrawalFeeTypeOptions = withdrawalFeeTypeOptions;
this.charges = charges;// charges associated with Savings account
// charges available for adding to Savings account
this.chargeOptions = chargeOptions;
this.withdrawalFee = getWithdrawalFee();
this.annualFee = getAnnualFee();
this.accountChart = accountChart;
this.chartTemplate = chartTemplate;
this.depositType = depositType;
this.minBalanceForInterestCalculation = minBalanceForInterestCalculation;
this.taxGroup = taxGroup;
this.withHoldTax = withHoldTax;
}
private SavingsAccountChargeData getWithdrawalFee() {
for (SavingsAccountChargeData charge : this.charges()) {
if (charge.isWithdrawalFee()) {
return charge;
}
}
return null;
}
private SavingsAccountChargeData getAnnualFee() {
for (SavingsAccountChargeData charge : this.charges()) {
if (charge.isAnnualFee()) {
return charge;
}
}
return null;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof DepositAccountData)) {
return false;
}
final DepositAccountData rhs = (DepositAccountData) obj;
return new EqualsBuilder().append(this.id, rhs.id).append(this.accountNo, rhs.accountNo).isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37).append(this.id).append(this.accountNo).toHashCode();
}
public Collection<SavingsAccountChargeData> charges() {
return (this.charges == null) ? new HashSet<SavingsAccountChargeData>() : this.charges;
}
}
@@ -1,74 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.math.BigDecimal;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.portfolio.interestratechart.data.InterestIncentiveData;
public final class DepositAccountInterestIncentiveData {
@SuppressWarnings("unused")
private final Long id;
@SuppressWarnings("unused")
private final EnumOptionData entityType;
@SuppressWarnings("unused")
private final EnumOptionData attributeName;
@SuppressWarnings("unused")
private final EnumOptionData conditionType;
@SuppressWarnings("unused")
private final String attributeValue;
@SuppressWarnings("unused")
private final String attributeValueDesc;
@SuppressWarnings("unused")
private final EnumOptionData incentiveType;
@SuppressWarnings("unused")
private final BigDecimal amount;
public static DepositAccountInterestIncentiveData instance(final Long id, final EnumOptionData entityType,
final EnumOptionData attributeName, final EnumOptionData conditionType, final String attributeValue,
final String attributeValueDesc, final EnumOptionData incentiveType, final BigDecimal amount) {
return new DepositAccountInterestIncentiveData(id, entityType, attributeName, conditionType, attributeValue, attributeValueDesc,
incentiveType, amount);
}
public static DepositAccountInterestIncentiveData from(final InterestIncentiveData incentiveData) {
final Long id = null;
return new DepositAccountInterestIncentiveData(id, incentiveData.entityType(), incentiveData.attributeName(),
incentiveData.conditionType(), incentiveData.attributeValue(), incentiveData.attributeValueDesc(),
incentiveData.incentiveType(), incentiveData.amount());
}
private DepositAccountInterestIncentiveData(final Long id, final EnumOptionData entityType, final EnumOptionData attributeName,
final EnumOptionData conditionType, final String attributeValue, final String attributeValueDesc,
final EnumOptionData incentiveType, final BigDecimal amount) {
this.id = id;
this.entityType = entityType;
this.attributeName = attributeName;
this.conditionType = conditionType;
this.attributeValue = attributeValue;
this.attributeValueDesc = attributeValueDesc;
this.incentiveType = incentiveType;
this.amount = amount;
}
}
@@ -1,177 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.portfolio.interestratechart.data.InterestRateChartData;
import org.apache.fineract.portfolio.interestratechart.data.InterestRateChartSlabData;
/**
* Immutable data object representing a deposit account interest rate chart.
*/
public final class DepositAccountInterestRateChartData {
private final Long id;
private final String name;
private final String description;
private final LocalDate fromDate;
private final LocalDate endDate;
private final boolean isPrimaryGroupingByAmount;
private final Long accountId;
private final String accountNumber;
// associations
private Collection<DepositAccountInterestRateChartSlabData> chartSlabs;
// template
private final Collection<EnumOptionData> periodTypes;
private final Collection<EnumOptionData> entityTypeOptions;
private final Collection<EnumOptionData> attributeNameOptions;
private final Collection<EnumOptionData> conditionTypeOptions;
private final Collection<EnumOptionData> incentiveTypeOptions;
private final Collection<CodeValueData> genderOptions;
private final Collection<CodeValueData> clientTypeOptions;
private final Collection<CodeValueData> clientClassificationOptions;
public static DepositAccountInterestRateChartData instance(Long id, String name, String description, LocalDate fromDate,
LocalDate endDate, boolean isPrimaryGroupingByAmount, Long accountId, String accountNumber,
Collection<DepositAccountInterestRateChartSlabData> chartSlabs, Collection<EnumOptionData> periodTypes) {
final Collection<EnumOptionData> entityTypeOptions = null;
final Collection<EnumOptionData> attributeNameOptions = null;
final Collection<EnumOptionData> conditionTypeOptions = null;
final Collection<EnumOptionData> incentiveTypeOptions = null;
final Collection<CodeValueData> genderOptions = null;
final Collection<CodeValueData> clientTypeOptions = null;
final Collection<CodeValueData> clientClassificationOptions = null;
return new DepositAccountInterestRateChartData(id, name, description, fromDate, endDate, isPrimaryGroupingByAmount, accountId,
accountNumber, chartSlabs, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions, incentiveTypeOptions,
genderOptions, clientTypeOptions, clientClassificationOptions);
}
public static DepositAccountInterestRateChartData from(InterestRateChartData productChartData) {
final Long id = null;
final Long accountId = null;
final String accountNumber = null;
Collection<DepositAccountInterestRateChartSlabData> fromProdChartSlabs = new ArrayList<>();
Collection<InterestRateChartSlabData> productChartSlabDatas = productChartData.chartSlabs();
if (productChartSlabDatas != null) {
for (InterestRateChartSlabData productChartSlabData : productChartSlabDatas) {
fromProdChartSlabs.add(DepositAccountInterestRateChartSlabData.from(productChartSlabData));
}
}
return new DepositAccountInterestRateChartData(id, productChartData.name(), productChartData.description(),
productChartData.fromDate(), productChartData.endDate(), productChartData.isPrimaryGroupingByAmount(), accountId,
accountNumber, fromProdChartSlabs, productChartData.periodTypes(), productChartData.entityTypeOptions(),
productChartData.attributeNameOptions(), productChartData.conditionTypeOptions(), productChartData.incentiveTypeOptions(),
productChartData.genderOptions(), productChartData.clientTypeOptions(), productChartData.clientClassificationOptions());
}
public static DepositAccountInterestRateChartData withSlabs(DepositAccountInterestRateChartData interestRateChartData,
Collection<DepositAccountInterestRateChartSlabData> chartSlabs) {
return new DepositAccountInterestRateChartData(interestRateChartData.id, interestRateChartData.name,
interestRateChartData.description, interestRateChartData.fromDate, interestRateChartData.endDate,
interestRateChartData.isPrimaryGroupingByAmount, interestRateChartData.accountId, interestRateChartData.accountNumber,
chartSlabs, interestRateChartData.periodTypes, interestRateChartData.entityTypeOptions,
interestRateChartData.attributeNameOptions, interestRateChartData.conditionTypeOptions,
interestRateChartData.incentiveTypeOptions, interestRateChartData.genderOptions, interestRateChartData.clientTypeOptions,
interestRateChartData.clientClassificationOptions);
}
public static DepositAccountInterestRateChartData withTemplate(DepositAccountInterestRateChartData interestRateChartData,
Collection<EnumOptionData> periodTypes, final Collection<EnumOptionData> entityTypeOptions,
final Collection<EnumOptionData> attributeNameOptions, final Collection<EnumOptionData> conditionTypeOptions,
final Collection<EnumOptionData> incentiveTypeOptions, final Collection<CodeValueData> genderOptions,
final Collection<CodeValueData> clientTypeOptions, final Collection<CodeValueData> clientClassificationOptions) {
return new DepositAccountInterestRateChartData(interestRateChartData.id, interestRateChartData.name,
interestRateChartData.description, interestRateChartData.fromDate, interestRateChartData.endDate,
interestRateChartData.isPrimaryGroupingByAmount, interestRateChartData.accountId, interestRateChartData.accountNumber,
interestRateChartData.chartSlabs, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions,
incentiveTypeOptions, genderOptions, clientTypeOptions, clientClassificationOptions);
}
public static DepositAccountInterestRateChartData template(Collection<EnumOptionData> periodTypes,
final Collection<EnumOptionData> entityTypeOptions, final Collection<EnumOptionData> attributeNameOptions,
final Collection<EnumOptionData> conditionTypeOptions, final Collection<EnumOptionData> incentiveTypeOptions,
final Collection<CodeValueData> genderOptions, final Collection<CodeValueData> clientTypeOptions,
final Collection<CodeValueData> clientClassificationOptions) {
final Long id = null;
final String name = null;
final String description = null;
final LocalDate fromDate = null;
final LocalDate endDate = null;
final Long accountId = null;
final String accountNumber = null;
final boolean isPrimaryGroupingByAmount = false;
final Collection<DepositAccountInterestRateChartSlabData> chartSlabs = null;
return new DepositAccountInterestRateChartData(id, name, description, fromDate, endDate, isPrimaryGroupingByAmount, accountId,
accountNumber, chartSlabs, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions, incentiveTypeOptions,
genderOptions, clientTypeOptions, clientClassificationOptions);
}
private DepositAccountInterestRateChartData(Long id, String name, String description, LocalDate fromDate, LocalDate endDate,
final boolean isPrimaryGroupingByAmount, Long accountId, String accountNumber,
Collection<DepositAccountInterestRateChartSlabData> chartSlabs, Collection<EnumOptionData> periodTypes,
final Collection<EnumOptionData> entityTypeOptions, final Collection<EnumOptionData> attributeNameOptions,
final Collection<EnumOptionData> conditionTypeOptions, final Collection<EnumOptionData> incentiveTypeOptions,
final Collection<CodeValueData> genderOptions, final Collection<CodeValueData> clientTypeOptions,
final Collection<CodeValueData> clientClassificationOptions) {
this.id = id;
this.name = name;
this.description = description;
this.fromDate = fromDate;
this.endDate = endDate;
this.isPrimaryGroupingByAmount = isPrimaryGroupingByAmount;
this.chartSlabs = chartSlabs;
this.accountId = accountId;
this.accountNumber = accountNumber;
this.periodTypes = periodTypes;
this.attributeNameOptions = attributeNameOptions;
this.entityTypeOptions = entityTypeOptions;
this.conditionTypeOptions = conditionTypeOptions;
this.incentiveTypeOptions = incentiveTypeOptions;
this.genderOptions = genderOptions;
this.clientTypeOptions = clientTypeOptions;
this.clientClassificationOptions = clientClassificationOptions;
}
public void addChartSlab(final DepositAccountInterestRateChartSlabData chartSlab) {
if (this.chartSlabs == null) {
this.chartSlabs = new ArrayList<>();
}
this.chartSlabs.add(chartSlab);
}
public boolean isFromDateAfter(final LocalDate compareDate) {
return compareDate != null && DateUtils.isAfter(this.fromDate, compareDate);
}
public LocalDate endDate() {
return this.endDate;
}
public LocalDate fromDate() {
return this.fromDate;
}
}
@@ -1,146 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.portfolio.interestratechart.data.InterestIncentiveData;
import org.apache.fineract.portfolio.interestratechart.data.InterestRateChartSlabData;
/**
* Immutable data object representing deposit accounts Interest rate Slabs.
*/
public final class DepositAccountInterestRateChartSlabData {
private final Long id;
private final String description;
private final EnumOptionData periodType;
private final Integer fromPeriod;
private final Integer toPeriod;
private final BigDecimal amountRangeFrom;
private final BigDecimal amountRangeTo;
private final BigDecimal annualInterestRate;
private final CurrencyData currency;
// associations
private Collection<DepositAccountInterestIncentiveData> incentives;
// template
@SuppressWarnings("unused")
private final Collection<EnumOptionData> periodTypes;
@SuppressWarnings("unused")
private final Collection<EnumOptionData> entityTypeOptions;
@SuppressWarnings("unused")
private final Collection<EnumOptionData> attributeNameOptions;
@SuppressWarnings("unused")
private final Collection<EnumOptionData> conditionTypeOptions;
@SuppressWarnings("unused")
private final Collection<EnumOptionData> incentiveTypeOptions;
@SuppressWarnings("unused")
private final Collection<CodeValueData> genderOptions;
@SuppressWarnings("unused")
private final Collection<CodeValueData> clientTypeOptions;
@SuppressWarnings("unused")
private final Collection<CodeValueData> clientClassificationOptions;
public static DepositAccountInterestRateChartSlabData instance(final Long id, final String description, final EnumOptionData periodType,
final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo,
final BigDecimal annualInterestRate, final CurrencyData currency) {
final Collection<EnumOptionData> periodTypes = null;
final Collection<EnumOptionData> entityTypeOptions = null;
final Collection<EnumOptionData> attributeNameOptions = null;
final Collection<EnumOptionData> conditionTypeOptions = null;
final Collection<EnumOptionData> incentiveTypeOptions = null;
final Collection<CodeValueData> genderOptions = null;
final Collection<CodeValueData> clientTypeOptions = null;
final Collection<CodeValueData> clientClassificationOptions = null;
final Collection<DepositAccountInterestIncentiveData> incentives = null;
return new DepositAccountInterestRateChartSlabData(id, description, periodType, fromPeriod, toPeriod, amountRangeFrom,
amountRangeTo, annualInterestRate, incentives, currency, periodTypes, entityTypeOptions, attributeNameOptions,
conditionTypeOptions, incentiveTypeOptions, genderOptions, clientTypeOptions, clientClassificationOptions);
}
public static DepositAccountInterestRateChartSlabData from(final InterestRateChartSlabData chartSlabData) {
final Long id = null;
Set<DepositAccountInterestIncentiveData> fromProdIncentives = new HashSet<>();
Set<InterestIncentiveData> productIncentiveData = chartSlabData.incentives();
if (productIncentiveData != null) {
for (InterestIncentiveData incentive : productIncentiveData) {
fromProdIncentives.add(DepositAccountInterestIncentiveData.from(incentive));
}
}
return new DepositAccountInterestRateChartSlabData(id, chartSlabData.description(), chartSlabData.periodType(),
chartSlabData.fromPeriod(), chartSlabData.toPeriod(), chartSlabData.amountRangeFrom(), chartSlabData.amountRangeTo(),
chartSlabData.annualInterestRate(), fromProdIncentives, chartSlabData.currency(), chartSlabData.periodTypes(),
chartSlabData.entityTypeOptions(), chartSlabData.attributeNameOptions(), chartSlabData.conditionTypeOptions(),
chartSlabData.incentiveTypeOptions(), chartSlabData.genderOptions(), chartSlabData.clientTypeOptions(),
chartSlabData.clientClassificationOptions());
}
public static DepositAccountInterestRateChartSlabData withTemplate(final DepositAccountInterestRateChartSlabData chartSlab,
final Collection<EnumOptionData> periodTypes, final Collection<EnumOptionData> entityTypeOptions,
final Collection<EnumOptionData> attributeNameOptions, final Collection<EnumOptionData> conditionTypeOptions,
final Collection<EnumOptionData> incentiveTypeOptions, final Collection<CodeValueData> genderOptions,
final Collection<CodeValueData> clientTypeOptions, final Collection<CodeValueData> clientClassificationOptions) {
return new DepositAccountInterestRateChartSlabData(chartSlab.id, chartSlab.description, chartSlab.periodType, chartSlab.fromPeriod,
chartSlab.toPeriod, chartSlab.amountRangeFrom, chartSlab.amountRangeTo, chartSlab.annualInterestRate, chartSlab.incentives,
chartSlab.currency, periodTypes, entityTypeOptions, attributeNameOptions, conditionTypeOptions, incentiveTypeOptions,
genderOptions, clientTypeOptions, clientClassificationOptions);
}
private DepositAccountInterestRateChartSlabData(final Long id, final String description, final EnumOptionData periodType,
final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo,
final BigDecimal annualInterestRate, final Collection<DepositAccountInterestIncentiveData> incentivesData,
final CurrencyData currency, final Collection<EnumOptionData> periodTypes, final Collection<EnumOptionData> entityTypeOptions,
final Collection<EnumOptionData> attributeNameOptions, final Collection<EnumOptionData> conditionTypeOptions,
final Collection<EnumOptionData> incentiveTypeOptions, final Collection<CodeValueData> genderOptions,
final Collection<CodeValueData> clientTypeOptions, final Collection<CodeValueData> clientClassificationOptions) {
this.id = id;
this.description = description;
this.periodType = periodType;
this.fromPeriod = fromPeriod;
this.toPeriod = toPeriod;
this.amountRangeFrom = amountRangeFrom;
this.amountRangeTo = amountRangeTo;
this.annualInterestRate = annualInterestRate;
this.currency = currency;
this.periodTypes = periodTypes;
this.incentives = incentivesData;
this.attributeNameOptions = attributeNameOptions;
this.entityTypeOptions = entityTypeOptions;
this.conditionTypeOptions = conditionTypeOptions;
this.incentiveTypeOptions = incentiveTypeOptions;
this.genderOptions = genderOptions;
this.clientTypeOptions = clientTypeOptions;
this.clientClassificationOptions = clientClassificationOptions;
}
public void addIncentives(final DepositAccountInterestIncentiveData incentive) {
if (this.incentives == null) {
this.incentives = new HashSet<>();
}
this.incentives.add(incentive);
}
}
@@ -1,92 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.math.BigDecimal;
import java.time.LocalDate;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
public final class DepositAccountOnHoldTransactionData {
@SuppressWarnings("unused")
private final Long id;
@SuppressWarnings("unused")
private final BigDecimal amount;
@SuppressWarnings("unused")
private EnumOptionData transactionType;
@SuppressWarnings("unused")
private final LocalDate transactionDate;
@SuppressWarnings("unused")
private final boolean reversed;
@SuppressWarnings("unused")
private final Long savingsId;
@SuppressWarnings("unused")
private final String savingsAccountNo;
@SuppressWarnings("unused")
private final String savingsClientName;
@SuppressWarnings("unused")
private final Long loanId;
@SuppressWarnings("unused")
private final String loanAccountNo;
@SuppressWarnings("unused")
private final String loanClientName;
private DepositAccountOnHoldTransactionData(final Long id, final BigDecimal amount, final EnumOptionData transactionType,
final LocalDate transactionDate, final boolean reversed, final Long savingsId, final String savingsAccNo,
final String savingsClientName, final Long loanId, final String loanAccNo, final String loanClientName) {
this.id = id;
this.amount = amount;
this.transactionType = transactionType;
this.transactionDate = transactionDate;
this.reversed = reversed;
this.savingsId = savingsId;
this.savingsAccountNo = savingsAccNo;
this.savingsClientName = savingsClientName;
this.loanId = loanId;
this.loanAccountNo = loanAccNo;
this.loanClientName = loanClientName;
}
private DepositAccountOnHoldTransactionData(final Long id, final BigDecimal amount, final EnumOptionData transactionType,
final LocalDate transactionDate, final boolean reversed) {
this.id = id;
this.amount = amount;
this.transactionType = transactionType;
this.transactionDate = transactionDate;
this.reversed = reversed;
this.savingsAccountNo = null;
this.savingsId = 0L;
this.savingsClientName = null;
this.loanId = 0L;
this.loanAccountNo = null;
this.loanClientName = null;
}
public static DepositAccountOnHoldTransactionData instance(final Long id, final BigDecimal amount, final EnumOptionData transactionType,
final LocalDate transactionDate, final boolean reversed, final Long savingsId, final String savingsAccountNo,
final String savingsClientName, final Long loanId, final String loanAccountNo, final String loanClientName) {
return new DepositAccountOnHoldTransactionData(id, amount, transactionType, transactionDate, reversed, savingsId, savingsAccountNo,
savingsClientName, loanId, loanAccountNo, loanClientName);
}
public static DepositAccountOnHoldTransactionData instance(Long transactionId, BigDecimal amount, EnumOptionData transactionType,
LocalDate date, boolean transactionReversed) {
return new DepositAccountOnHoldTransactionData(transactionId, amount, transactionType, date, transactionReversed);
}
}
@@ -1,456 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.fineract.accounting.common.AccountingRuleType;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.portfolio.charge.data.ChargeData;
import org.apache.fineract.portfolio.interestratechart.data.InterestRateChartData;
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
import org.apache.fineract.portfolio.tax.data.TaxGroupData;
/**
* Immutable data object represents a partial data of Deposit Proucts.
*/
public class DepositProductData {
protected final Long id;
protected final String name;
protected final String shortName;
protected final String description;
protected final CurrencyData currency;
protected final BigDecimal nominalAnnualInterestRate;
protected final EnumOptionData interestCompoundingPeriodType;
protected final EnumOptionData interestPostingPeriodType;
protected final EnumOptionData interestCalculationType;
protected final EnumOptionData interestCalculationDaysInYearType;
// protected final BigDecimal minRequiredOpeningBalance;
protected final Integer lockinPeriodFrequency;
protected final EnumOptionData lockinPeriodFrequencyType;
// protected final boolean withdrawalFeeForTransfers;
protected final BigDecimal minBalanceForInterestCalculation;
protected final boolean withHoldTax;
protected final TaxGroupData taxGroup;
// accounting
protected final EnumOptionData accountingRule;
protected final Map<String, Object> accountingMappings;
protected final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings;
protected final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings;
protected final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings;
// charges
protected final Collection<ChargeData> charges;
// interest rate charts
protected final Collection<InterestRateChartData> interestRateCharts;
protected final InterestRateChartData activeChart;
// template
protected final Collection<CurrencyData> currencyOptions;
protected final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions;
protected final Collection<EnumOptionData> interestPostingPeriodTypeOptions;
protected final Collection<EnumOptionData> interestCalculationTypeOptions;
protected final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions;
protected final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions;
protected final Collection<EnumOptionData> withdrawalFeeTypeOptions;
protected final Collection<PaymentTypeData> paymentTypeOptions;
protected final Collection<EnumOptionData> accountingRuleOptions;
protected final Map<String, List<GLAccountData>> accountingMappingOptions;
protected final Collection<ChargeData> chargeOptions;
protected final Collection<ChargeData> penaltyOptions;
protected final InterestRateChartData chartTemplate;
protected final Collection<TaxGroupData> taxGroupOptions;
public static DepositProductData template(final CurrencyData currency, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final EnumOptionData accountingRule,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<PaymentTypeData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> chargeOptions,
final Collection<ChargeData> penaltyOptions, final InterestRateChartData chartTemplate,
final Collection<TaxGroupData> taxGroupOptions) {
final Long id = null;
final String name = null;
final String shortName = null;
final String description = null;
final BigDecimal nominalAnnualInterestRate = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final BigDecimal minBalanceForInterestCalculation = null;
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final boolean withHoldTax = false;
final TaxGroupData taxGroup = null;
return new DepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency,
lockinPeriodFrequencyType, accountingRule, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, minBalanceForInterestCalculation, withHoldTax, taxGroup,
taxGroupOptions);
}
public static DepositProductData withCharges(final DepositProductData existingProduct, final Collection<ChargeData> charges) {
return new DepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName, existingProduct.description,
existingProduct.currency, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.interestCalculationDaysInYearType, existingProduct.lockinPeriodFrequency,
existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule, existingProduct.accountingMappings,
existingProduct.paymentChannelToFundSourceMappings, existingProduct.currencyOptions,
existingProduct.interestCompoundingPeriodTypeOptions, existingProduct.interestPostingPeriodTypeOptions,
existingProduct.interestCalculationTypeOptions, existingProduct.interestCalculationDaysInYearTypeOptions,
existingProduct.lockinPeriodFrequencyTypeOptions, existingProduct.withdrawalFeeTypeOptions,
existingProduct.paymentTypeOptions, existingProduct.accountingRuleOptions, existingProduct.accountingMappingOptions,
charges, existingProduct.chargeOptions, existingProduct.penaltyOptions, existingProduct.feeToIncomeAccountMappings,
existingProduct.penaltyToIncomeAccountMappings, existingProduct.interestRateCharts, existingProduct.chartTemplate,
existingProduct.minBalanceForInterestCalculation, existingProduct.withHoldTax, existingProduct.taxGroup,
existingProduct.taxGroupOptions);
}
/**
* Returns a {@link DepositProductData} that contains and exist {@link DepositProductData} data with further
* template data for dropdowns.
*
* @param taxGroupOptions
* TODO
*/
public static DepositProductData withTemplate(final DepositProductData existingProduct, final Collection<CurrencyData> currencyOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<PaymentTypeData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> chargeOptions,
final Collection<ChargeData> penaltyOptions, final InterestRateChartData chartTemplate,
Collection<TaxGroupData> taxGroupOptions) {
return new DepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName, existingProduct.description,
existingProduct.currency, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.interestCalculationDaysInYearType, existingProduct.lockinPeriodFrequency,
existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule, existingProduct.accountingMappings,
existingProduct.paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions,
accountingMappingOptions, existingProduct.charges, chargeOptions, penaltyOptions,
existingProduct.feeToIncomeAccountMappings, existingProduct.penaltyToIncomeAccountMappings,
existingProduct.interestRateCharts, chartTemplate, existingProduct.minBalanceForInterestCalculation,
existingProduct.withHoldTax, existingProduct.taxGroup, taxGroupOptions);
}
public static DepositProductData withAccountingDetails(final DepositProductData existingProduct,
final Map<String, Object> accountingMappings, final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings) {
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<TaxGroupData> taxGroupOptions = null;
return new DepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName, existingProduct.description,
existingProduct.currency, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.interestCalculationDaysInYearType, existingProduct.lockinPeriodFrequency,
existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule, accountingMappings,
paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions, accountingMappingOptions, existingProduct.charges,
chargeOptions, penaltyOptions, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings,
existingProduct.interestRateCharts, existingProduct.chartTemplate, existingProduct.minBalanceForInterestCalculation,
existingProduct.withHoldTax, existingProduct.taxGroup, taxGroupOptions);
}
public static DepositProductData instance(final Long id, final String name, final String shortName, final String description,
final CurrencyData currency, final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final EnumOptionData accountingType,
final BigDecimal minBalanceForInterestCalculation, boolean withHoldTax, TaxGroupData taxGroup) {
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final InterestRateChartData chartTemplate = null;
final Collection<TaxGroupData> taxGroupOptions = null;
return new DepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency,
lockinPeriodFrequencyType, accountingType, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, minBalanceForInterestCalculation, withHoldTax, taxGroup,
taxGroupOptions);
}
public static DepositProductData lookup(final Long id, final String name) {
final String shortName = null;
final CurrencyData currency = null;
final String description = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestCompoundingPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final BigDecimal minBalanceForInterestCalculation = null;
final EnumOptionData accountingType = null;
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final InterestRateChartData chartTemplate = null;
final boolean withHoldTax = false;
final TaxGroupData taxGroup = null;
final Collection<TaxGroupData> taxGroupOptions = null;
return new DepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency,
lockinPeriodFrequencyType, accountingType, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, minBalanceForInterestCalculation, withHoldTax, taxGroup,
taxGroupOptions);
}
public static DepositProductData withInterestChart(final DepositProductData existingProduct,
final Collection<InterestRateChartData> interestRateCharts) {
return new DepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName, existingProduct.description,
existingProduct.currency, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.interestCalculationDaysInYearType, existingProduct.lockinPeriodFrequency,
existingProduct.lockinPeriodFrequencyType, existingProduct.accountingRule, existingProduct.accountingMappings,
existingProduct.paymentChannelToFundSourceMappings, existingProduct.currencyOptions,
existingProduct.interestCompoundingPeriodTypeOptions, existingProduct.interestPostingPeriodTypeOptions,
existingProduct.interestCalculationTypeOptions, existingProduct.interestCalculationDaysInYearTypeOptions,
existingProduct.lockinPeriodFrequencyTypeOptions, existingProduct.withdrawalFeeTypeOptions,
existingProduct.paymentTypeOptions, existingProduct.accountingRuleOptions, existingProduct.accountingMappingOptions,
existingProduct.charges, existingProduct.chargeOptions, existingProduct.penaltyOptions,
existingProduct.feeToIncomeAccountMappings, existingProduct.penaltyToIncomeAccountMappings, interestRateCharts,
existingProduct.chartTemplate, existingProduct.minBalanceForInterestCalculation, existingProduct.withHoldTax,
existingProduct.taxGroup, existingProduct.taxGroupOptions);
}
protected DepositProductData(final Long id, final String name, final String shortName, final String description,
final CurrencyData currency, final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final EnumOptionData accountingType,
final Map<String, Object> accountingMappings, final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<PaymentTypeData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> charges,
final Collection<ChargeData> chargeOptions, final Collection<ChargeData> penaltyOptions,
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings,
final Collection<InterestRateChartData> interestRateCharts, final InterestRateChartData chartTemplate,
final BigDecimal minBalanceForInterestCalculation, final boolean withHoldTax, final TaxGroupData taxGroup,
final Collection<TaxGroupData> taxGroupOptions) {
this.id = id;
this.name = name;
this.shortName = shortName;
this.description = description;
this.currency = currency;
this.nominalAnnualInterestRate = nominalAnnualInterestRate;
this.interestCompoundingPeriodType = interestCompoundingPeriodType;
this.interestPostingPeriodType = interestPostingPeriodType;
this.interestCalculationType = interestCalculationType;
this.interestCalculationDaysInYearType = interestCalculationDaysInYearType;
this.accountingRule = accountingType;
this.lockinPeriodFrequency = lockinPeriodFrequency;
this.lockinPeriodFrequencyType = lockinPeriodFrequencyType;
this.currencyOptions = currencyOptions;
this.interestCompoundingPeriodTypeOptions = interestCompoundingPeriodTypeOptions;
this.interestPostingPeriodTypeOptions = interestPostingPeriodTypeOptions;
this.interestCalculationTypeOptions = interestCalculationTypeOptions;
this.interestCalculationDaysInYearTypeOptions = interestCalculationDaysInYearTypeOptions;
this.lockinPeriodFrequencyTypeOptions = lockinPeriodFrequencyTypeOptions;
this.withdrawalFeeTypeOptions = withdrawalFeeTypeOptions;
this.paymentTypeOptions = paymentTypeOptions;
this.accountingMappingOptions = accountingMappingOptions;
this.accountingRuleOptions = accountingRuleOptions;
if (accountingMappings == null || accountingMappings.isEmpty()) {
this.accountingMappings = null;
} else {
this.accountingMappings = accountingMappings;
}
this.paymentChannelToFundSourceMappings = paymentChannelToFundSourceMappings;
this.charges = charges;// charges associated with Savings product
this.chargeOptions = chargeOptions;// charges available for adding to
// Savings product
this.penaltyOptions = penaltyOptions;// penalties available for adding
// to Savings product
this.feeToIncomeAccountMappings = feeToIncomeAccountMappings;
this.penaltyToIncomeAccountMappings = penaltyToIncomeAccountMappings;
this.interestRateCharts = interestRateCharts;
this.activeChart = activeChart(this.interestRateCharts);
this.chartTemplate = chartTemplate;
this.minBalanceForInterestCalculation = minBalanceForInterestCalculation;
this.taxGroup = taxGroup;
this.withHoldTax = withHoldTax;
this.taxGroupOptions = taxGroupOptions;
}
public static InterestRateChartData activeChart(Collection<InterestRateChartData> interestRateCharts) {
InterestRateChartData activeChart = null;
if (interestRateCharts != null) {
for (InterestRateChartData chartData : interestRateCharts) {
if (activeChart == null) {
activeChart = chartData;
} else {
if (!activeChart.isFromDateAfter(chartData.endDate())) {
activeChart = chartData;
}
}
}
}
return activeChart;
}
public boolean hasAccountingEnabled() {
return this.accountingRule.getId() > AccountingRuleType.NONE.getValue();
}
public int accountingRuleTypeId() {
return this.accountingRule.getId().intValue();
}
public String getName() {
return this.name;
}
public EnumOptionData getLockinPeriodFrequencyType() {
return lockinPeriodFrequencyType;
}
public Integer getLockinPeriodFrequency() {
return lockinPeriodFrequency;
}
public Long getId() {
return id;
}
public BigDecimal getNominalAnnualInterestRate() {
return nominalAnnualInterestRate;
}
public EnumOptionData getInterestPostingPeriodType() {
return interestPostingPeriodType;
}
public EnumOptionData getInterestCalculationType() {
return interestCalculationType;
}
public EnumOptionData getInterestCalculationDaysInYearType() {
return interestCalculationDaysInYearType;
}
public BigDecimal getMinBalanceForInterestCalculation() {
return minBalanceForInterestCalculation;
}
public String getShortName() {
return shortName;
}
public CurrencyData getCurrency() {
return currency;
}
public EnumOptionData getInterestCompoundingPeriodType() {
return interestCompoundingPeriodType;
}
}
@@ -1,544 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Collection;
import lombok.Getter;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.organisation.staff.data.StaffData;
import org.apache.fineract.portfolio.account.data.PortfolioAccountData;
import org.apache.fineract.portfolio.charge.data.ChargeData;
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
import org.apache.fineract.portfolio.savings.DepositAccountType;
import org.apache.fineract.portfolio.savings.service.SavingsEnumerations;
import org.apache.fineract.portfolio.tax.data.TaxGroupData;
/**
* Immutable data object representing a Fixed Deposit account.
*/
@Getter
public final class FixedDepositAccountData extends DepositAccountData {
private boolean preClosurePenalApplicable;
private BigDecimal preClosurePenalInterest;
private EnumOptionData preClosurePenalInterestOnType;
private Integer minDepositTerm;
private Integer maxDepositTerm;
private EnumOptionData minDepositTermType;
private EnumOptionData maxDepositTermType;
private Integer inMultiplesOfDepositTerm;
private EnumOptionData inMultiplesOfDepositTermType;
private BigDecimal depositAmount;
private BigDecimal maturityAmount;
private LocalDate maturityDate;
private Integer depositPeriod;
private EnumOptionData depositPeriodFrequency;
private BigDecimal activationCharge;
private Long transferToSavingsId;
// used for account close
private EnumOptionData onAccountClosure;
private final PortfolioAccountData linkedAccount;
private final Boolean transferInterestToSavings;
private final PortfolioAccountData transferToSavingsAccount;
private Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
private Collection<EnumOptionData> periodFrequencyTypeOptions;
private Collection<SavingsAccountData> savingsAccounts;
// for account close
private Collection<EnumOptionData> onAccountClosureOptions;
private Collection<PaymentTypeData> paymentTypeOptions;
private final Collection<EnumOptionData> maturityInstructionOptions;
// import fields
private transient Integer rowIndex;
private String dateFormat;
private String locale;
private LocalDate submittedOnDate;
private Long depositPeriodFrequencyId;
public static FixedDepositAccountData importInstance(Long clientId, Long productId, Long fieldOfficerId, LocalDate submittedOnDate,
EnumOptionData interestCompoundingPeriodTypeEnum, EnumOptionData interestPostingPeriodTypeEnum,
EnumOptionData interestCalculationTypeEnum, EnumOptionData interestCalculationDaysInYearTypeEnum, Integer lockinPeriodFrequency,
EnumOptionData lockinPeriodFrequencyTypeEnum, BigDecimal depositAmount, Integer depositPeriod, Long depositPeriodFrequencyId,
String externalId, Collection<SavingsAccountChargeData> charges, Integer rowIndex, String locale, String dateFormat) {
return new FixedDepositAccountData(clientId, productId, fieldOfficerId, submittedOnDate, interestCompoundingPeriodTypeEnum,
interestPostingPeriodTypeEnum, interestCalculationTypeEnum, interestCalculationDaysInYearTypeEnum, lockinPeriodFrequency,
lockinPeriodFrequencyTypeEnum, depositAmount, depositPeriod, depositPeriodFrequencyId, externalId, charges, rowIndex,
locale, dateFormat);
}
private FixedDepositAccountData(Long clientId, Long productId, Long fieldofficerId, LocalDate submittedOnDate,
EnumOptionData interestCompoundingPeriodType, EnumOptionData interestPostingPeriodType, EnumOptionData interestCalculationType,
EnumOptionData interestCalculationDaysInYearType, Integer lockinPeriodFrequency, EnumOptionData lockinPeriodFrequencyType,
BigDecimal depositAmount, Integer depositPeriod, Long depositPeriodFrequencyId, String externalId,
Collection<SavingsAccountChargeData> charges, Integer rowIndex, String locale, String dateFormat) {
super(clientId, productId, fieldofficerId, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
interestCalculationDaysInYearType, lockinPeriodFrequency, lockinPeriodFrequencyType, externalId, charges);
this.preClosurePenalApplicable = false;
this.preClosurePenalInterest = null;
this.preClosurePenalInterestOnType = null;
this.minDepositTerm = null;
this.maxDepositTerm = null;
this.minDepositTermType = null;
this.maxDepositTermType = null;
this.inMultiplesOfDepositTerm = null;
this.inMultiplesOfDepositTermType = null;
this.depositAmount = depositAmount;
this.maturityAmount = null;
this.maturityDate = null;
this.depositPeriod = depositPeriod;
this.depositPeriodFrequency = null;
this.activationCharge = null;
this.onAccountClosure = null;
this.linkedAccount = null;
this.transferToSavingsAccount = null;
this.transferInterestToSavings = null;
this.preClosurePenalInterestOnTypeOptions = null;
this.periodFrequencyTypeOptions = null;
this.savingsAccounts = null;
this.onAccountClosureOptions = null;
this.paymentTypeOptions = null;
this.rowIndex = rowIndex;
this.dateFormat = dateFormat;
this.locale = locale;
this.submittedOnDate = submittedOnDate;
this.depositPeriodFrequencyId = depositPeriodFrequencyId;
this.maturityInstructionOptions = null;
}
public static FixedDepositAccountData instance(final DepositAccountData depositAccountData, final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest, final EnumOptionData preClosurePenalInterestOnType, final Integer minDepositTerm,
final Integer maxDepositTerm, final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final EnumOptionData inMultiplesOfDepositTermType, final BigDecimal depositAmount,
final BigDecimal maturityAmount, final LocalDate maturityDate, final Integer depositPeriod,
final EnumOptionData depositPeriodFrequency, final EnumOptionData onAccountClosure, final Boolean transferInterestToSavings,
final Long transferToSavingsId) {
final PortfolioAccountData linkedAccount = null;
final PortfolioAccountData transferToSavingsAccount = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
final Collection<EnumOptionData> maturityInstructionOptions = null;
final EnumOptionData depositType = SavingsEnumerations.depositType(DepositAccountType.FIXED_DEPOSIT.getValue());
final Collection<EnumOptionData> onAccountClosureOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<SavingsAccountData> savingsAccountDatas = null;
return new FixedDepositAccountData(depositAccountData.id, depositAccountData.accountNo, depositAccountData.externalId,
depositAccountData.groupId, depositAccountData.groupName, depositAccountData.clientId, depositAccountData.clientName,
depositAccountData.depositProductId, depositAccountData.depositProductName, depositAccountData.fieldOfficerId,
depositAccountData.fieldOfficerName, depositAccountData.status, depositAccountData.timeline, depositAccountData.currency,
depositAccountData.nominalAnnualInterestRate, depositAccountData.interestCompoundingPeriodType,
depositAccountData.interestPostingPeriodType, depositAccountData.interestCalculationType,
depositAccountData.interestCalculationDaysInYearType, depositAccountData.minRequiredOpeningBalance,
depositAccountData.lockinPeriodFrequency, depositAccountData.lockinPeriodFrequencyType,
depositAccountData.withdrawalFeeForTransfers, depositAccountData.minBalanceForInterestCalculation,
depositAccountData.summary, depositAccountData.transactions, depositAccountData.productOptions,
depositAccountData.fieldOfficerOptions, depositAccountData.interestCompoundingPeriodTypeOptions,
depositAccountData.interestPostingPeriodTypeOptions, depositAccountData.interestCalculationTypeOptions,
depositAccountData.interestCalculationDaysInYearTypeOptions, depositAccountData.lockinPeriodFrequencyTypeOptions,
depositAccountData.withdrawalFeeTypeOptions, depositAccountData.charges, depositAccountData.chargeOptions,
depositAccountData.accountChart, depositAccountData.chartTemplate, preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType,
maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate,
depositPeriod, depositPeriodFrequency, periodFrequencyTypeOptions, depositType, onAccountClosure, onAccountClosureOptions,
paymentTypeOptions, savingsAccountDatas, linkedAccount, transferInterestToSavings, depositAccountData.withHoldTax,
depositAccountData.taxGroup, maturityInstructionOptions, transferToSavingsId, transferToSavingsAccount);
}
public static FixedDepositAccountData withInterestChart(final FixedDepositAccountData account,
final DepositAccountInterestRateChartData accountChart) {
return new FixedDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.depositProductId, account.depositProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.minBalanceForInterestCalculation,
account.summary, account.transactions, account.productOptions, account.fieldOfficerOptions,
account.interestCompoundingPeriodTypeOptions, account.interestPostingPeriodTypeOptions,
account.interestCalculationTypeOptions, account.interestCalculationDaysInYearTypeOptions,
account.lockinPeriodFrequencyTypeOptions, account.withdrawalFeeTypeOptions, account.charges, account.chargeOptions,
accountChart, account.chartTemplate, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, account.preClosurePenalInterestOnTypeOptions, account.minDepositTerm,
account.maxDepositTerm, account.minDepositTermType, account.maxDepositTermType, account.inMultiplesOfDepositTerm,
account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount, account.maturityDate,
account.depositPeriod, account.depositPeriodFrequency, account.periodFrequencyTypeOptions, account.depositType,
account.onAccountClosure, account.onAccountClosureOptions, account.paymentTypeOptions, account.savingsAccounts,
account.linkedAccount, account.transferInterestToSavings, account.withHoldTax, account.taxGroup,
account.maturityInstructionOptions, account.transferToSavingsId, account.transferToSavingsAccount);
}
public static FixedDepositAccountData associationsAndTemplate(final FixedDepositAccountData account, FixedDepositAccountData template,
final Collection<SavingsAccountTransactionData> transactions, final Collection<SavingsAccountChargeData> charges,
final PortfolioAccountData linkedAccount, PortfolioAccountData transferToSavingsAccount) {
if (template == null) {
template = account;
}
return new FixedDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.depositProductId, account.depositProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.minBalanceForInterestCalculation,
account.summary, transactions, template.productOptions, template.fieldOfficerOptions,
template.interestCompoundingPeriodTypeOptions, template.interestPostingPeriodTypeOptions,
template.interestCalculationTypeOptions, template.interestCalculationDaysInYearTypeOptions,
template.lockinPeriodFrequencyTypeOptions, template.withdrawalFeeTypeOptions, charges, template.chargeOptions,
account.accountChart, account.chartTemplate, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, template.preClosurePenalInterestOnTypeOptions, account.minDepositTerm,
account.maxDepositTerm, account.minDepositTermType, account.maxDepositTermType, account.inMultiplesOfDepositTerm,
account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount, account.maturityDate,
account.depositPeriod, account.depositPeriodFrequency, template.periodFrequencyTypeOptions, account.depositType,
account.onAccountClosure, account.onAccountClosureOptions, account.paymentTypeOptions, template.savingsAccounts,
linkedAccount, account.transferInterestToSavings, account.withHoldTax, account.taxGroup, account.maturityInstructionOptions,
account.transferToSavingsId, transferToSavingsAccount);
}
public static FixedDepositAccountData withTemplateOptions(final FixedDepositAccountData account,
final Collection<DepositProductData> productOptions, final Collection<StaffData> fieldOfficerOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<SavingsAccountTransactionData> transactions, final Collection<SavingsAccountChargeData> charges,
final Collection<ChargeData> chargeOptions, final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
final Collection<EnumOptionData> periodFrequencyTypeOptions, final Collection<SavingsAccountData> savingsAccounts,
final Collection<EnumOptionData> maturityInstructionOptions) {
return new FixedDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.depositProductId, account.depositProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.minBalanceForInterestCalculation,
account.summary, transactions, productOptions, fieldOfficerOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, charges, chargeOptions, account.accountChart,
account.chartTemplate, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions, account.minDepositTerm, account.maxDepositTerm,
account.minDepositTermType, account.maxDepositTermType, account.inMultiplesOfDepositTerm,
account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount, account.maturityDate,
account.depositPeriod, account.depositPeriodFrequency, periodFrequencyTypeOptions, account.depositType,
account.onAccountClosure, account.onAccountClosureOptions, account.paymentTypeOptions, savingsAccounts,
account.linkedAccount, account.transferInterestToSavings, account.withHoldTax, account.taxGroup, maturityInstructionOptions,
account.transferToSavingsId, account.transferToSavingsAccount);
}
public static FixedDepositAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId,
final String groupName) {
final Long id = null;
final String accountNo = null;
final String externalId = null;
final Long productId = null;
final String productName = null;
final Long fieldOfficerId = null;
final String fieldOfficerName = null;
final SavingsAccountStatusEnumData status = null;
final SavingsAccountApplicationTimelineData timeline = null;
final CurrencyData currency = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final BigDecimal minRequiredOpeningBalance = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final boolean withdrawalFeeForTransfers = false;
final BigDecimal minBalanceForInterestCalculation = null;
final SavingsAccountSummaryData summary = null;
final Collection<SavingsAccountTransactionData> transactions = null;
final boolean withHoldTax = false;
final TaxGroupData taxGroup = null;
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<SavingsAccountChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final DepositAccountInterestRateChartData accountChart = null;
final DepositAccountInterestRateChartData chartTemplate = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final BigDecimal depositAmount = null;
final BigDecimal maturityAmount = null;
final LocalDate maturityDate = null;
final Integer depositPeriod = null;
final EnumOptionData depositPeriodFrequency = null;
final EnumOptionData onAccountClosure = null;
final PortfolioAccountData linkedAccount = null;
final PortfolioAccountData transferToSavingsAccount = null;
final Boolean transferInterestToSavings = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
final EnumOptionData depositType = SavingsEnumerations.depositType(DepositAccountType.FIXED_DEPOSIT.getValue());
final Collection<EnumOptionData> onAccountClosureOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<SavingsAccountData> savingsAccountDatas = null;
final Collection<EnumOptionData> maturityInstructionOptions = null;
final Long transferToSavingsId = null;
return new FixedDepositAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
fieldOfficerId, fieldOfficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, minBalanceForInterestCalculation, summary,
transactions, productOptions, fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, charges, chargeOptions, accountChart, chartTemplate, preClosurePenalApplicable,
preClosurePenalInterest, preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions, minDepositTerm,
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
depositAmount, maturityAmount, maturityDate, depositPeriod, depositPeriodFrequency, periodFrequencyTypeOptions, depositType,
onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, linkedAccount,
transferInterestToSavings, withHoldTax, taxGroup, maturityInstructionOptions, transferToSavingsId,
transferToSavingsAccount);
}
public static FixedDepositAccountData preClosureDetails(final Long accountId, BigDecimal maturityAmount,
final Collection<EnumOptionData> onAccountClosureOptions, final Collection<PaymentTypeData> paymentTypeOptions,
final Collection<SavingsAccountData> savingsAccountDatas) {
final Long groupId = null;
final String groupName = null;
final Long clientId = null;
final String clientName = null;
final String accountNo = null;
final String externalId = null;
final Long productId = null;
final String productName = null;
final Long fieldOfficerId = null;
final String fieldOfficerName = null;
final SavingsAccountStatusEnumData status = null;
final SavingsAccountApplicationTimelineData timeline = null;
final CurrencyData currency = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final BigDecimal minRequiredOpeningBalance = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final boolean withdrawalFeeForTransfers = false;
final BigDecimal minBalanceForInterestCalculation = null;
final SavingsAccountSummaryData summary = null;
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<SavingsAccountChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final DepositAccountInterestRateChartData accountChart = null;
final DepositAccountInterestRateChartData chartTemplate = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final BigDecimal depositAmount = null;
final LocalDate maturityDate = null;
final Integer depositPeriod = null;
final EnumOptionData depositPeriodFrequency = null;
final EnumOptionData onAccountClosure = null;
final Boolean transferInterestToSavings = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
final EnumOptionData depositType = SavingsEnumerations.depositType(DepositAccountType.FIXED_DEPOSIT.getValue());
final PortfolioAccountData linkedAccount = null;
final boolean withHoldTax = false;
final TaxGroupData taxGroup = null;
final Collection<EnumOptionData> maturityInstructionOptions = null;
final Long transferToSavingsId = null;
final PortfolioAccountData transferToSavingsAccount = null;
return new FixedDepositAccountData(accountId, accountNo, externalId, groupId, groupName, clientId, clientName, productId,
productName, fieldOfficerId, fieldOfficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, minBalanceForInterestCalculation, summary,
transactions, productOptions, fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, charges, chargeOptions, accountChart, chartTemplate, preClosurePenalApplicable,
preClosurePenalInterest, preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions, minDepositTerm,
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
depositAmount, maturityAmount, maturityDate, depositPeriod, depositPeriodFrequency, periodFrequencyTypeOptions, depositType,
onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, linkedAccount,
transferInterestToSavings, withHoldTax, taxGroup, maturityInstructionOptions, transferToSavingsId,
transferToSavingsAccount);
}
public static FixedDepositAccountData withClosureTemplateDetails(final FixedDepositAccountData account,
final Collection<EnumOptionData> onAccountClosureOptions, final Collection<PaymentTypeData> paymentTypeOptions,
final Collection<SavingsAccountData> savingsAccountDatas) {
return new FixedDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.depositProductId, account.depositProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.minBalanceForInterestCalculation,
account.summary, account.transactions, account.productOptions, account.fieldOfficerOptions,
account.interestCompoundingPeriodTypeOptions, account.interestPostingPeriodTypeOptions,
account.interestCalculationTypeOptions, account.interestCalculationDaysInYearTypeOptions,
account.lockinPeriodFrequencyTypeOptions, account.withdrawalFeeTypeOptions, account.charges, account.chargeOptions,
account.accountChart, account.chartTemplate, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, account.preClosurePenalInterestOnTypeOptions, account.minDepositTerm,
account.maxDepositTerm, account.minDepositTermType, account.maxDepositTermType, account.inMultiplesOfDepositTerm,
account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount, account.maturityDate,
account.depositPeriod, account.depositPeriodFrequency, account.periodFrequencyTypeOptions, account.depositType,
account.onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, account.linkedAccount,
account.transferInterestToSavings, account.withHoldTax, account.taxGroup, account.maturityInstructionOptions,
account.transferToSavingsId, account.transferToSavingsAccount);
}
private FixedDepositAccountData(final Long id, final String accountNo, final String externalId, final Long groupId,
final String groupName, final Long clientId, final String clientName, final Long productId, final String productName,
final Long fieldofficerId, final String fieldofficerName, final SavingsAccountStatusEnumData status,
final SavingsAccountApplicationTimelineData timeline, final CurrencyData currency, final BigDecimal nominalAnnualInterestRate,
final EnumOptionData interestPeriodType, final EnumOptionData interestPostingPeriodType,
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType,
final boolean withdrawalFeeForTransfers, final BigDecimal minBalanceForInterestCalculation,
final SavingsAccountSummaryData summary, final Collection<SavingsAccountTransactionData> transactions,
final Collection<DepositProductData> productOptions, final Collection<StaffData> fieldOfficerOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<SavingsAccountChargeData> charges, final Collection<ChargeData> chargeOptions,
final DepositAccountInterestRateChartData accountChart, final DepositAccountInterestRateChartData chartTemplate,
final boolean preClosurePenalApplicable, final BigDecimal preClosurePenalInterest,
final EnumOptionData preClosurePenalInterestOnType, final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
final Integer minDepositTerm, final Integer maxDepositTerm, final EnumOptionData minDepositTermType,
final EnumOptionData maxDepositTermType, final Integer inMultiplesOfDepositTerm,
final EnumOptionData inMultiplesOfDepositTermType, final BigDecimal depositAmount, final BigDecimal maturityAmount,
final LocalDate maturityDate, final Integer depositPeriod, final EnumOptionData depositPeriodFrequency,
final Collection<EnumOptionData> periodFrequencyTypeOptions, final EnumOptionData depositType,
final EnumOptionData onAccountClosure, final Collection<EnumOptionData> onAccountClosureOptions,
final Collection<PaymentTypeData> paymentTypeOptions, final Collection<SavingsAccountData> savingsAccountDatas,
final PortfolioAccountData linkedAccount, final Boolean transferInterestToSavings, final boolean withHoldTax,
final TaxGroupData taxGroup, final Collection<EnumOptionData> maturityInstructionOptions, final Long transferToSavingsId,
final PortfolioAccountData transferToSavingsAccount) {
super(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName, fieldofficerId, fieldofficerName,
status, timeline, currency, nominalAnnualInterestRate, interestPeriodType, interestPostingPeriodType,
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions, productOptions, fieldOfficerOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, charges,
chargeOptions, accountChart, chartTemplate, depositType, minBalanceForInterestCalculation, withHoldTax, taxGroup);
this.preClosurePenalApplicable = preClosurePenalApplicable;
this.preClosurePenalInterest = preClosurePenalInterest;
this.preClosurePenalInterestOnType = preClosurePenalInterestOnType;
this.minDepositTerm = minDepositTerm;
this.maxDepositTerm = maxDepositTerm;
this.minDepositTermType = minDepositTermType;
this.maxDepositTermType = maxDepositTermType;
this.inMultiplesOfDepositTerm = inMultiplesOfDepositTerm;
this.inMultiplesOfDepositTermType = inMultiplesOfDepositTermType;
this.depositAmount = depositAmount;
this.maturityAmount = maturityAmount;
this.maturityDate = maturityDate;
this.depositPeriod = depositPeriod;
this.depositPeriodFrequency = depositPeriodFrequency;
this.onAccountClosure = onAccountClosure;
this.linkedAccount = linkedAccount;
this.transferToSavingsAccount = transferToSavingsAccount;
this.transferInterestToSavings = transferInterestToSavings;
// template
this.preClosurePenalInterestOnTypeOptions = preClosurePenalInterestOnTypeOptions;
this.periodFrequencyTypeOptions = periodFrequencyTypeOptions;
// account close template options
this.onAccountClosureOptions = onAccountClosureOptions;
this.paymentTypeOptions = paymentTypeOptions;
this.savingsAccounts = savingsAccountDatas;
this.maturityInstructionOptions = maturityInstructionOptions;
this.transferToSavingsId = transferToSavingsId;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof FixedDepositAccountData)) {
return false;
}
final FixedDepositAccountData rhs = (FixedDepositAccountData) obj;
return new EqualsBuilder().append(this.id, rhs.id).append(this.accountNo, rhs.accountNo).isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37).append(this.id).append(this.accountNo).toHashCode();
}
public void setActivationCharge(BigDecimal activationCharge) {
this.activationCharge = activationCharge;
}
}
@@ -1,448 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.portfolio.charge.data.ChargeData;
import org.apache.fineract.portfolio.interestratechart.data.InterestRateChartData;
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
import org.apache.fineract.portfolio.tax.data.TaxGroupData;
/**
* Immutable data object representing a Fixed Deposit product.
*/
public final class FixedDepositProductData extends DepositProductData {
// additional fields
private boolean preClosurePenalApplicable;
private BigDecimal preClosurePenalInterest;
private EnumOptionData preClosurePenalInterestOnType;
private Integer minDepositTerm;
private Integer maxDepositTerm;
private EnumOptionData minDepositTermType;
private EnumOptionData maxDepositTermType;
private Integer inMultiplesOfDepositTerm;
private EnumOptionData inMultiplesOfDepositTermType;
private BigDecimal minDepositAmount;
private BigDecimal depositAmount;
private BigDecimal maxDepositAmount;
private Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
private Collection<EnumOptionData> periodFrequencyTypeOptions;
public static FixedDepositProductData template(final CurrencyData currency, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final EnumOptionData accountingRule,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<PaymentTypeData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> chargeOptions,
final Collection<ChargeData> penaltyOptions, final InterestRateChartData chartTemplate,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
final Collection<EnumOptionData> periodFrequencyTypeOptions, final Collection<TaxGroupData> taxGroupOptions) {
final Long id = null;
final String name = null;
final String shortName = null;
final String description = null;
final BigDecimal nominalAnnualInterestRate = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final BigDecimal minBalanceForInterestCalculation = null;
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final BigDecimal minDepositAmount = null;
final BigDecimal depositAmount = null;
final BigDecimal maxDepositAmount = null;
final boolean withHoldTax = false;
final TaxGroupData taxGroup = null;
return new FixedDepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate,
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
lockinPeriodFrequency, lockinPeriodFrequencyType, minBalanceForInterestCalculation, accountingRule, accountingMappings,
paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions, accountingMappingOptions, charges, chargeOptions,
penaltyOptions, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate,
preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions,
minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm,
inMultiplesOfDepositTermType, minDepositAmount, depositAmount, maxDepositAmount, periodFrequencyTypeOptions, withHoldTax,
taxGroup, taxGroupOptions);
}
public static FixedDepositProductData withCharges(final FixedDepositProductData existingProduct, final Collection<ChargeData> charges) {
return new FixedDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName, existingProduct.description,
existingProduct.currency, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.interestCalculationDaysInYearType, existingProduct.lockinPeriodFrequency,
existingProduct.lockinPeriodFrequencyType, existingProduct.minBalanceForInterestCalculation, existingProduct.accountingRule,
existingProduct.accountingMappings, existingProduct.paymentChannelToFundSourceMappings, existingProduct.currencyOptions,
existingProduct.interestCompoundingPeriodTypeOptions, existingProduct.interestPostingPeriodTypeOptions,
existingProduct.interestCalculationTypeOptions, existingProduct.interestCalculationDaysInYearTypeOptions,
existingProduct.lockinPeriodFrequencyTypeOptions, existingProduct.withdrawalFeeTypeOptions,
existingProduct.paymentTypeOptions, existingProduct.accountingRuleOptions, existingProduct.accountingMappingOptions,
charges, existingProduct.chargeOptions, existingProduct.penaltyOptions, existingProduct.feeToIncomeAccountMappings,
existingProduct.penaltyToIncomeAccountMappings, existingProduct.interestRateCharts, existingProduct.chartTemplate,
existingProduct.preClosurePenalApplicable, existingProduct.preClosurePenalInterest,
existingProduct.preClosurePenalInterestOnType, existingProduct.preClosurePenalInterestOnTypeOptions,
existingProduct.minDepositTerm, existingProduct.maxDepositTerm, existingProduct.minDepositTermType,
existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm, existingProduct.inMultiplesOfDepositTermType,
existingProduct.minDepositAmount, existingProduct.depositAmount, existingProduct.maxDepositAmount,
existingProduct.periodFrequencyTypeOptions, existingProduct.withHoldTax, existingProduct.taxGroup,
existingProduct.taxGroupOptions);
}
/**
* Returns a {@link FixedDepositProductData} that contains and exist {@link FixedDepositProductData} data with
* further template data for dropdowns.
*
* @param taxGroupOptions
* TODO
*/
public static FixedDepositProductData withTemplate(final FixedDepositProductData existingProduct,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<PaymentTypeData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> chargeOptions,
final Collection<ChargeData> penaltyOptions, final InterestRateChartData chartTemplate,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
final Collection<EnumOptionData> periodFrequencyTypeOptions, final Collection<TaxGroupData> taxGroupOptions) {
return new FixedDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName, existingProduct.description,
existingProduct.currency, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.interestCalculationDaysInYearType, existingProduct.lockinPeriodFrequency,
existingProduct.lockinPeriodFrequencyType, existingProduct.minBalanceForInterestCalculation, existingProduct.accountingRule,
existingProduct.accountingMappings, existingProduct.paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, existingProduct.charges, chargeOptions, penaltyOptions,
existingProduct.feeToIncomeAccountMappings, existingProduct.penaltyToIncomeAccountMappings,
existingProduct.interestRateCharts, chartTemplate, existingProduct.preClosurePenalApplicable,
existingProduct.preClosurePenalInterest, existingProduct.preClosurePenalInterestOnType,
preClosurePenalInterestOnTypeOptions, existingProduct.minDepositTerm, existingProduct.maxDepositTerm,
existingProduct.minDepositTermType, existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm,
existingProduct.inMultiplesOfDepositTermType, existingProduct.minDepositAmount, existingProduct.depositAmount,
existingProduct.maxDepositAmount, periodFrequencyTypeOptions, existingProduct.withHoldTax, existingProduct.taxGroup,
taxGroupOptions);
}
public static FixedDepositProductData withAccountingDetails(final FixedDepositProductData existingProduct,
final Map<String, Object> accountingMappings, final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings) {
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
return new FixedDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName, existingProduct.description,
existingProduct.currency, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.interestCalculationDaysInYearType, existingProduct.lockinPeriodFrequency,
existingProduct.lockinPeriodFrequencyType, existingProduct.minBalanceForInterestCalculation, existingProduct.accountingRule,
accountingMappings, paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions,
accountingMappingOptions, existingProduct.charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, existingProduct.interestRateCharts, existingProduct.chartTemplate,
existingProduct.preClosurePenalApplicable, existingProduct.preClosurePenalInterest,
existingProduct.preClosurePenalInterestOnType, existingProduct.preClosurePenalInterestOnTypeOptions,
existingProduct.minDepositTerm, existingProduct.maxDepositTerm, existingProduct.minDepositTermType,
existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm, existingProduct.inMultiplesOfDepositTermType,
existingProduct.minDepositAmount, existingProduct.depositAmount, existingProduct.maxDepositAmount,
existingProduct.periodFrequencyTypeOptions, existingProduct.withHoldTax, existingProduct.taxGroup,
existingProduct.taxGroupOptions);
}
public static FixedDepositProductData instance(final DepositProductData depositProductData, final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest, final EnumOptionData preClosurePenalInterestOnType, final Integer minDepositTerm,
final Integer maxDepositTerm, final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final EnumOptionData inMultiplesOfDepositTermType, final BigDecimal minDepositAmount,
final BigDecimal depositAmount, final BigDecimal maxDepositAmount) {
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final InterestRateChartData chartTemplate = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
final Collection<TaxGroupData> taxGroupOptions = null;
return new FixedDepositProductData(depositProductData.id, depositProductData.name, depositProductData.shortName,
depositProductData.description, depositProductData.currency, depositProductData.nominalAnnualInterestRate,
depositProductData.interestCompoundingPeriodType, depositProductData.interestPostingPeriodType,
depositProductData.interestCalculationType, depositProductData.interestCalculationDaysInYearType,
depositProductData.lockinPeriodFrequency, depositProductData.lockinPeriodFrequencyType,
depositProductData.minBalanceForInterestCalculation, depositProductData.accountingRule, accountingMappings,
paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions, accountingMappingOptions, charges, chargeOptions,
penaltyOptions, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate,
preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions,
minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm,
inMultiplesOfDepositTermType, minDepositAmount, depositAmount, maxDepositAmount, periodFrequencyTypeOptions,
depositProductData.withHoldTax, depositProductData.taxGroup, taxGroupOptions);
}
public static FixedDepositProductData lookup(final Long id, final String name) {
final String shortName = null;
final CurrencyData currency = null;
final String description = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestCompoundingPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final BigDecimal minBalanceForInterestCalculation = null;
final EnumOptionData accountingType = null;
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final InterestRateChartData chartTemplate = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final BigDecimal minDepositAmount = null;
final BigDecimal depositAmount = null;
final BigDecimal maxDepositAmount = null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
final boolean withHoldTax = false;
final TaxGroupData taxGroup = null;
final Collection<TaxGroupData> taxGroupOptions = null;
return new FixedDepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate,
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
lockinPeriodFrequency, lockinPeriodFrequencyType, minBalanceForInterestCalculation, accountingType, accountingMappings,
paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions, accountingMappingOptions, charges, chargeOptions,
penaltyOptions, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate,
preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions,
minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm,
inMultiplesOfDepositTermType, minDepositAmount, depositAmount, maxDepositAmount, periodFrequencyTypeOptions, withHoldTax,
taxGroup, taxGroupOptions);
}
public static FixedDepositProductData withInterestChart(final FixedDepositProductData existingProduct,
final Collection<InterestRateChartData> interestRateCharts) {
return new FixedDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName, existingProduct.description,
existingProduct.currency, existingProduct.nominalAnnualInterestRate, existingProduct.interestCompoundingPeriodType,
existingProduct.interestPostingPeriodType, existingProduct.interestCalculationType,
existingProduct.interestCalculationDaysInYearType, existingProduct.lockinPeriodFrequency,
existingProduct.lockinPeriodFrequencyType, existingProduct.minBalanceForInterestCalculation, existingProduct.accountingRule,
existingProduct.accountingMappings, existingProduct.paymentChannelToFundSourceMappings, existingProduct.currencyOptions,
existingProduct.interestCompoundingPeriodTypeOptions, existingProduct.interestPostingPeriodTypeOptions,
existingProduct.interestCalculationTypeOptions, existingProduct.interestCalculationDaysInYearTypeOptions,
existingProduct.lockinPeriodFrequencyTypeOptions, existingProduct.withdrawalFeeTypeOptions,
existingProduct.paymentTypeOptions, existingProduct.accountingRuleOptions, existingProduct.accountingMappingOptions,
existingProduct.charges, existingProduct.chargeOptions, existingProduct.penaltyOptions,
existingProduct.feeToIncomeAccountMappings, existingProduct.penaltyToIncomeAccountMappings, interestRateCharts,
existingProduct.chartTemplate, existingProduct.preClosurePenalApplicable, existingProduct.preClosurePenalInterest,
existingProduct.preClosurePenalInterestOnType, existingProduct.preClosurePenalInterestOnTypeOptions,
existingProduct.minDepositTerm, existingProduct.maxDepositTerm, existingProduct.minDepositTermType,
existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm, existingProduct.inMultiplesOfDepositTermType,
existingProduct.minDepositAmount, existingProduct.depositAmount, existingProduct.maxDepositAmount,
existingProduct.periodFrequencyTypeOptions, existingProduct.withHoldTax, existingProduct.taxGroup,
existingProduct.taxGroupOptions);
}
private FixedDepositProductData(final Long id, final String name, final String shortName, final String description,
final CurrencyData currency, final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final BigDecimal minBalanceForInterestCalculation,
final EnumOptionData accountingType, final Map<String, Object> accountingMappings,
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<PaymentTypeData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> charges,
final Collection<ChargeData> chargeOptions, final Collection<ChargeData> penaltyOptions,
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings,
final Collection<InterestRateChartData> interestRateCharts, final InterestRateChartData chartTemplate,
final boolean preClosurePenalApplicable, final BigDecimal preClosurePenalInterest,
final EnumOptionData preClosurePenalInterestOnType, final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
final Integer minDepositTerm, final Integer maxDepositTerm, final EnumOptionData minDepositTermType,
final EnumOptionData maxDepositTermType, final Integer inMultiplesOfDepositTerm,
final EnumOptionData inMultiplesOfDepositTermType, final BigDecimal minDepositAmount, final BigDecimal depositAmount,
final BigDecimal maxDepositAmount, final Collection<EnumOptionData> periodFrequencyTypeOptions, final boolean withHoldTax,
final TaxGroupData taxGroup, final Collection<TaxGroupData> taxGroupOptions) {
super(id, name, shortName, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency,
lockinPeriodFrequencyType, accountingType, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, minBalanceForInterestCalculation, withHoldTax, taxGroup,
taxGroupOptions);
// fixed deposit additional fields
this.preClosurePenalApplicable = preClosurePenalApplicable;
this.preClosurePenalInterest = preClosurePenalInterest;
this.preClosurePenalInterestOnType = preClosurePenalInterestOnType;
this.minDepositTerm = minDepositTerm;
this.maxDepositTerm = maxDepositTerm;
this.minDepositTermType = minDepositTermType;
this.maxDepositTermType = maxDepositTermType;
this.inMultiplesOfDepositTerm = inMultiplesOfDepositTerm;
this.inMultiplesOfDepositTermType = inMultiplesOfDepositTermType;
this.minDepositAmount = minDepositAmount;
this.depositAmount = depositAmount;
this.maxDepositAmount = maxDepositAmount;
// template
this.preClosurePenalInterestOnTypeOptions = preClosurePenalInterestOnTypeOptions;
this.periodFrequencyTypeOptions = periodFrequencyTypeOptions;
}
public Integer getMinDepositTerm() {
return minDepositTerm;
}
public EnumOptionData getMinDepositTermType() {
return minDepositTermType;
}
public EnumOptionData getMaxDepositTermType() {
return maxDepositTermType;
}
public Integer getMaxDepositTerm() {
return maxDepositTerm;
}
public Integer getInMultiplesOfDepositTerm() {
return inMultiplesOfDepositTerm;
}
public EnumOptionData getInMultiplesOfDepositTermType() {
return inMultiplesOfDepositTermType;
}
public BigDecimal getMinDepositAmount() {
return minDepositAmount;
}
public BigDecimal getDepositAmount() {
return depositAmount;
}
public BigDecimal getMaxDepositAmount() {
return maxDepositAmount;
}
public EnumOptionData getPreClosurePenalInterestOnType() {
return preClosurePenalInterestOnType;
}
public BigDecimal getPreClosurePenalInterest() {
return preClosurePenalInterest;
}
public boolean isPreClosurePenalApplicable() {
return preClosurePenalApplicable;
}
}
@@ -1,74 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.List;
import org.apache.fineract.portfolio.accountdetails.data.SavingsSummaryCustom;
public class GSIMContainer {
private final BigDecimal gsimId;
private final BigDecimal groupId;
private final String accountNumber;
private final List<SavingsSummaryCustom> childGSIMAccounts;
private final BigDecimal parentBalance;
private final String savingsStatus;
public GSIMContainer(final BigDecimal gsimId, final BigDecimal groupId, final String accountNumber,
final List<SavingsSummaryCustom> childGSIMAccounts, final BigDecimal parentBalance, final String savingsStatus) {
this.gsimId = gsimId;
this.groupId = groupId;
this.accountNumber = accountNumber;
this.childGSIMAccounts = childGSIMAccounts;
this.parentBalance = parentBalance;
this.savingsStatus = savingsStatus;
}
public BigDecimal getGsimId() {
return gsimId;
}
public BigDecimal getGroupId() {
return groupId;
}
public String getAccountNumber() {
return accountNumber;
}
public List<SavingsSummaryCustom> getChildGSIMAccounts() {
return childGSIMAccounts;
}
public BigDecimal getparentBalance() {
return parentBalance;
}
public String getSavingsStatus() {
return savingsStatus;
}
}
@@ -1,121 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.math.BigDecimal;
public final class GroupSavingsIndividualMonitoringAccountData {
private final BigDecimal gsimId;
private final BigDecimal groupId;
private final BigDecimal clientId;
private final String accountNumber;
private final BigDecimal childAccountId;
private final String childAccountNumber;
private final BigDecimal childDeposit;
private final BigDecimal parentDeposit;
private final Long childAccountsCount;
private final String savingsStatus;
private GroupSavingsIndividualMonitoringAccountData(final BigDecimal glimId, final BigDecimal groupId, final BigDecimal clientId,
final String accountNumber, final BigDecimal childAccountId, final String childAccountNumber, final BigDecimal childDeposit,
final BigDecimal parentDeposit, final Long childAccountsCount, final String savingsStatus) {
this.gsimId = glimId;
this.groupId = groupId;
this.clientId = clientId;
this.accountNumber = accountNumber;
this.childAccountId = childAccountId;
this.childAccountNumber = childAccountNumber;
this.childDeposit = childDeposit;
this.parentDeposit = parentDeposit;
this.childAccountsCount = childAccountsCount;
this.savingsStatus = savingsStatus;
}
public static GroupSavingsIndividualMonitoringAccountData getInstance(final BigDecimal glimId, final BigDecimal groupId,
final String accountNumber, final String childAccountNumber, final BigDecimal childDeposit, final BigDecimal parentDeposit,
final Long childAccountsCount, final String savingsStatus) {
return new GroupSavingsIndividualMonitoringAccountData(glimId, groupId, null, accountNumber, null, childAccountNumber, childDeposit,
parentDeposit, childAccountsCount, savingsStatus);
}
public static GroupSavingsIndividualMonitoringAccountData getInstance1(final BigDecimal glimId, final BigDecimal groupId,
final String accountNumber, final BigDecimal parentDeposit, final String savingsStatus) {
return new GroupSavingsIndividualMonitoringAccountData(glimId, groupId, null, accountNumber, null, null, null, parentDeposit, null,
savingsStatus);
}
public static GroupSavingsIndividualMonitoringAccountData getInstance2(final BigDecimal glimId, final BigDecimal groupId,
final BigDecimal clientId, final String accountNumber, final BigDecimal childAccountId, final String childAccountNumber,
final BigDecimal childDeposit, final BigDecimal parentDeposit, final Long childAccountsCount, final String savingsStatus) {
return new GroupSavingsIndividualMonitoringAccountData(glimId, groupId, clientId, accountNumber, childAccountId, childAccountNumber,
childDeposit, parentDeposit, childAccountsCount, savingsStatus);
}
public BigDecimal getGsimId() {
return gsimId;
}
public BigDecimal getGroupId() {
return groupId;
}
public BigDecimal getClientId() {
return clientId;
}
public String getAccountNumber() {
return accountNumber;
}
public BigDecimal getChildAccountId() {
return childAccountId;
}
public String getChildAccountNumber() {
return childAccountNumber;
}
public BigDecimal getChildDeposit() {
return childDeposit;
}
public BigDecimal getParentDeposit() {
return parentDeposit;
}
public Long getChildAccountsCount() {
return childAccountsCount;
}
public String getSavingsStatus() {
return savingsStatus;
}
}
@@ -1,614 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Collection;
import lombok.Getter;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.organisation.staff.data.StaffData;
import org.apache.fineract.portfolio.charge.data.ChargeData;
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
import org.apache.fineract.portfolio.savings.DepositAccountType;
import org.apache.fineract.portfolio.savings.service.SavingsEnumerations;
import org.apache.fineract.portfolio.tax.data.TaxGroupData;
/**
* Immutable data object representing a Recurring Deposit account.
*/
@Getter
public final class RecurringDepositAccountData extends DepositAccountData {
// additional fields
private final boolean preClosurePenalApplicable;
private final BigDecimal preClosurePenalInterest;
private final EnumOptionData preClosurePenalInterestOnType;
private final Integer minDepositTerm;
private final Integer maxDepositTerm;
private final EnumOptionData minDepositTermType;
private final EnumOptionData maxDepositTermType;
private final Integer inMultiplesOfDepositTerm;
private final EnumOptionData inMultiplesOfDepositTermType;
private final BigDecimal depositAmount;
private final BigDecimal maturityAmount;
private final LocalDate maturityDate;
private final Integer depositPeriod;
private final EnumOptionData depositPeriodFrequency;
private final BigDecimal mandatoryRecommendedDepositAmount;
private final BigDecimal totalOverdueAmount;
private final Integer noOfOverdueInstallments;
private final boolean isMandatoryDeposit;
private final boolean allowWithdrawal;
private final boolean adjustAdvanceTowardsFuturePayments;
private final LocalDate expectedFirstDepositOnDate;
private final boolean isCalendarInherited;
private final Integer recurringFrequency;
private final EnumOptionData recurringFrequencyType;
// used for account close
private final EnumOptionData onAccountClosure;
private final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
private final Collection<EnumOptionData> periodFrequencyTypeOptions;
private final Collection<SavingsAccountData> savingsAccounts;
// for account close
private final Collection<EnumOptionData> onAccountClosureOptions;
private final Collection<PaymentTypeData> paymentTypeOptions;
// import fields
private transient Integer rowIndex;
private String dateFormat;
private String locale;
private LocalDate submittedOnDate;
private Long depositPeriodFrequencyId;
public static RecurringDepositAccountData importInstance(Long clientId, Long productId, Long fieldOfficerId, LocalDate submittedOnDate,
EnumOptionData interestCompoundingPeriodTypeEnum, EnumOptionData interestPostingPeriodTypeEnum,
EnumOptionData interestCalculationTypeEnum, EnumOptionData interestCalculationDaysInYearTypeEnum, Integer lockinPeriodFrequency,
EnumOptionData lockinPeriodFrequencyTypeEnum, BigDecimal depositAmount, Integer depositPeriod, Long depositPeriodFrequencyId,
LocalDate expectedFirstDepositOnDate, Integer recurringFrequency, EnumOptionData recurringFrequencyTypeEnum,
boolean isCalendarInherited, boolean isMandatoryDeposit, boolean allowWithdrawal, boolean adjustAdvanceTowardsFuturePayments,
String externalId, Collection<SavingsAccountChargeData> charges, Integer rowIndex, String locale, String dateFormat) {
return new RecurringDepositAccountData(clientId, productId, fieldOfficerId, submittedOnDate, interestCompoundingPeriodTypeEnum,
interestPostingPeriodTypeEnum, interestCalculationTypeEnum, interestCalculationDaysInYearTypeEnum, lockinPeriodFrequency,
lockinPeriodFrequencyTypeEnum, depositAmount, depositPeriod, depositPeriodFrequencyId, expectedFirstDepositOnDate,
recurringFrequency, recurringFrequencyTypeEnum, isCalendarInherited, isMandatoryDeposit, allowWithdrawal,
adjustAdvanceTowardsFuturePayments, externalId, charges, rowIndex, locale, dateFormat);
}
private RecurringDepositAccountData(Long clientId, Long productId, Long fieldofficerId, LocalDate submittedOnDate,
EnumOptionData interestCompoundingPeriodType, EnumOptionData interestPostingPeriodType, EnumOptionData interestCalculationType,
EnumOptionData interestCalculationDaysInYearType, Integer lockinPeriodFrequency, EnumOptionData lockinPeriodFrequencyType,
BigDecimal depositAmount, Integer depositPeriod, Long depositPeriodFrequencyId, LocalDate expectedFirstDepositOnDate,
Integer recurringFrequency, EnumOptionData recurringFrequencyType, boolean isCalendarInherited, boolean isMandatoryDeposit,
boolean allowWithdrawal, boolean adjustAdvanceTowardsFuturePayments, String externalId,
Collection<SavingsAccountChargeData> charges, Integer rowIndex, String locale, String dateFormat) {
super(clientId, productId, fieldofficerId, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
interestCalculationDaysInYearType, lockinPeriodFrequency, lockinPeriodFrequencyType, externalId, charges);
this.preClosurePenalApplicable = false;
this.preClosurePenalInterest = null;
this.preClosurePenalInterestOnType = null;
this.minDepositTerm = null;
this.maxDepositTerm = null;
this.minDepositTermType = null;
this.maxDepositTermType = null;
this.inMultiplesOfDepositTerm = null;
this.inMultiplesOfDepositTermType = null;
this.depositAmount = null;
this.maturityAmount = null;
this.maturityDate = null;
this.depositPeriod = depositPeriod;
this.depositPeriodFrequency = null;
this.mandatoryRecommendedDepositAmount = depositAmount;
this.totalOverdueAmount = null;
this.noOfOverdueInstallments = null;
this.isMandatoryDeposit = isMandatoryDeposit;
this.allowWithdrawal = allowWithdrawal;
this.adjustAdvanceTowardsFuturePayments = adjustAdvanceTowardsFuturePayments;
this.expectedFirstDepositOnDate = expectedFirstDepositOnDate;
this.isCalendarInherited = isCalendarInherited;
this.recurringFrequency = recurringFrequency;
this.recurringFrequencyType = recurringFrequencyType;
this.onAccountClosure = null;
this.preClosurePenalInterestOnTypeOptions = null;
this.periodFrequencyTypeOptions = null;
this.savingsAccounts = null;
this.onAccountClosureOptions = null;
this.paymentTypeOptions = null;
this.rowIndex = rowIndex;
this.dateFormat = dateFormat;
this.locale = locale;
this.submittedOnDate = submittedOnDate;
this.depositPeriodFrequencyId = depositPeriodFrequencyId;
}
public Integer getRowIndex() {
return rowIndex;
}
public static RecurringDepositAccountData instance(final DepositAccountData depositAccountData, final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest, final EnumOptionData preClosurePenalInterestOnType, final Integer minDepositTerm,
final Integer maxDepositTerm, final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final EnumOptionData inMultiplesOfDepositTermType, final BigDecimal depositAmount,
final BigDecimal maturityAmount, final LocalDate maturityDate, final Integer depositPeriod,
final EnumOptionData depositPeriodFrequency, final BigDecimal mandatoryRecommendedDepositAmount,
final EnumOptionData onAccountClosure, final LocalDate expectedFirstDepositOnDate, final BigDecimal totalOverdueAmount,
final Integer noOfOverdueInstallments, final boolean isMandatoryDeposit, final boolean allowWithdrawal,
final boolean adjustAdvanceTowardsFuturePayments, final boolean isCalendarInherited) {
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
final EnumOptionData depositType = SavingsEnumerations.depositType(DepositAccountType.FIXED_DEPOSIT.getValue());
final Collection<EnumOptionData> onAccountClosureOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<SavingsAccountData> savingsAccountDatas = null;
final Integer recurringFrequency = null;
final EnumOptionData recurringFrequencyType = null;
return new RecurringDepositAccountData(depositAccountData.id, depositAccountData.accountNo, depositAccountData.externalId,
depositAccountData.groupId, depositAccountData.groupName, depositAccountData.clientId, depositAccountData.clientName,
depositAccountData.depositProductId, depositAccountData.depositProductName, depositAccountData.fieldOfficerId,
depositAccountData.fieldOfficerName, depositAccountData.status, depositAccountData.timeline, depositAccountData.currency,
depositAccountData.nominalAnnualInterestRate, depositAccountData.interestCompoundingPeriodType,
depositAccountData.interestPostingPeriodType, depositAccountData.interestCalculationType,
depositAccountData.interestCalculationDaysInYearType, depositAccountData.minRequiredOpeningBalance,
depositAccountData.lockinPeriodFrequency, depositAccountData.lockinPeriodFrequencyType,
depositAccountData.withdrawalFeeForTransfers, depositAccountData.minBalanceForInterestCalculation,
depositAccountData.summary, depositAccountData.transactions, depositAccountData.productOptions,
depositAccountData.fieldOfficerOptions, depositAccountData.interestCompoundingPeriodTypeOptions,
depositAccountData.interestPostingPeriodTypeOptions, depositAccountData.interestCalculationTypeOptions,
depositAccountData.interestCalculationDaysInYearTypeOptions, depositAccountData.lockinPeriodFrequencyTypeOptions,
depositAccountData.withdrawalFeeTypeOptions, depositAccountData.charges, depositAccountData.chargeOptions,
depositAccountData.accountChart, depositAccountData.chartTemplate, preClosurePenalApplicable, preClosurePenalInterest,
preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions, minDepositTerm, maxDepositTerm, minDepositTermType,
maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate,
depositPeriod, depositPeriodFrequency, mandatoryRecommendedDepositAmount, periodFrequencyTypeOptions, depositType,
onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, expectedFirstDepositOnDate,
totalOverdueAmount, noOfOverdueInstallments, isMandatoryDeposit, allowWithdrawal, adjustAdvanceTowardsFuturePayments,
isCalendarInherited, recurringFrequency, recurringFrequencyType, depositAccountData.withHoldTax,
depositAccountData.taxGroup);
}
public static RecurringDepositAccountData withInterestChartAndRecurringDetails(final RecurringDepositAccountData account,
final DepositAccountInterestRateChartData accountChart, final Integer recurringFrequency,
final EnumOptionData recurringFrequencyType) {
return new RecurringDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.depositProductId, account.depositProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.minBalanceForInterestCalculation,
account.summary, account.transactions, account.productOptions, account.fieldOfficerOptions,
account.interestCompoundingPeriodTypeOptions, account.interestPostingPeriodTypeOptions,
account.interestCalculationTypeOptions, account.interestCalculationDaysInYearTypeOptions,
account.lockinPeriodFrequencyTypeOptions, account.withdrawalFeeTypeOptions, account.charges, account.chargeOptions,
accountChart, account.chartTemplate, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, account.preClosurePenalInterestOnTypeOptions, account.minDepositTerm,
account.maxDepositTerm, account.minDepositTermType, account.maxDepositTermType, account.inMultiplesOfDepositTerm,
account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount, account.maturityDate,
account.depositPeriod, account.depositPeriodFrequency, account.mandatoryRecommendedDepositAmount,
account.periodFrequencyTypeOptions, account.depositType, account.onAccountClosure, account.onAccountClosureOptions,
account.paymentTypeOptions, account.savingsAccounts, account.expectedFirstDepositOnDate, account.totalOverdueAmount,
account.noOfOverdueInstallments, account.isMandatoryDeposit, account.allowWithdrawal,
account.adjustAdvanceTowardsFuturePayments, account.isCalendarInherited, recurringFrequency, recurringFrequencyType,
account.withHoldTax, account.taxGroup);
}
public static RecurringDepositAccountData withTemplateOptions(final RecurringDepositAccountData account,
final RecurringDepositAccountData template, final Collection<SavingsAccountTransactionData> transactions,
final Collection<SavingsAccountChargeData> charges) {
if (template == null) {
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
return withTemplateOptions(account, productOptions, fieldOfficerOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions, charges, chargeOptions,
preClosurePenalInterestOnTypeOptions, periodFrequencyTypeOptions);
}
return new RecurringDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.depositProductId, account.depositProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.minBalanceForInterestCalculation,
account.summary, transactions, template.productOptions, template.fieldOfficerOptions,
template.interestCompoundingPeriodTypeOptions, template.interestPostingPeriodTypeOptions,
template.interestCalculationTypeOptions, template.interestCalculationDaysInYearTypeOptions,
template.lockinPeriodFrequencyTypeOptions, template.withdrawalFeeTypeOptions, charges, template.chargeOptions,
account.accountChart, account.chartTemplate, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, template.preClosurePenalInterestOnTypeOptions, account.minDepositTerm,
account.maxDepositTerm, account.minDepositTermType, account.maxDepositTermType, account.inMultiplesOfDepositTerm,
account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount, account.maturityDate,
account.depositPeriod, account.depositPeriodFrequency, account.mandatoryRecommendedDepositAmount,
template.periodFrequencyTypeOptions, account.depositType, account.onAccountClosure, account.onAccountClosureOptions,
account.paymentTypeOptions, account.savingsAccounts, account.expectedFirstDepositOnDate, account.totalOverdueAmount,
account.noOfOverdueInstallments, account.isMandatoryDeposit, account.allowWithdrawal,
account.adjustAdvanceTowardsFuturePayments, account.isCalendarInherited, account.recurringFrequency,
account.recurringFrequencyType, account.withHoldTax, account.taxGroup);
}
public static RecurringDepositAccountData withTemplateOptions(final RecurringDepositAccountData account,
final Collection<DepositProductData> productOptions, final Collection<StaffData> fieldOfficerOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<SavingsAccountTransactionData> transactions, final Collection<SavingsAccountChargeData> charges,
final Collection<ChargeData> chargeOptions, final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
final Collection<EnumOptionData> periodFrequencyTypeOptions) {
return new RecurringDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.depositProductId, account.depositProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.minBalanceForInterestCalculation,
account.summary, transactions, productOptions, fieldOfficerOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, charges, chargeOptions, account.accountChart,
account.chartTemplate, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions, account.minDepositTerm, account.maxDepositTerm,
account.minDepositTermType, account.maxDepositTermType, account.inMultiplesOfDepositTerm,
account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount, account.maturityDate,
account.depositPeriod, account.depositPeriodFrequency, account.mandatoryRecommendedDepositAmount,
periodFrequencyTypeOptions, account.depositType, account.onAccountClosure, account.onAccountClosureOptions,
account.paymentTypeOptions, account.savingsAccounts, account.expectedFirstDepositOnDate, account.totalOverdueAmount,
account.noOfOverdueInstallments, account.isMandatoryDeposit, account.allowWithdrawal,
account.adjustAdvanceTowardsFuturePayments, account.isCalendarInherited, account.recurringFrequency,
account.recurringFrequencyType, account.withHoldTax, account.taxGroup);
}
public static RecurringDepositAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId,
final String groupName) {
final Long id = null;
final String accountNo = null;
final String externalId = null;
final Long productId = null;
final String productName = null;
final Long fieldOfficerId = null;
final String fieldOfficerName = null;
final SavingsAccountStatusEnumData status = null;
final SavingsAccountApplicationTimelineData timeline = null;
final CurrencyData currency = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final BigDecimal minRequiredOpeningBalance = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final boolean withdrawalFeeForTransfers = false;
final BigDecimal minBalanceForInterestCalculation = null;
final SavingsAccountSummaryData summary = null;
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<SavingsAccountChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final DepositAccountInterestRateChartData accountChart = null;
final DepositAccountInterestRateChartData chartTemplate = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final BigDecimal depositAmount = null;
final BigDecimal maturityAmount = null;
final LocalDate maturityDate = null;
final Integer depositPeriod = null;
final EnumOptionData depositPeriodFrequency = null;
final BigDecimal mandatoryRecommendedDepositAmount = null;
final EnumOptionData onAccountClosure = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
final EnumOptionData depositType = SavingsEnumerations.depositType(DepositAccountType.RECURRING_DEPOSIT.getValue());
final Collection<EnumOptionData> onAccountClosureOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<SavingsAccountData> savingsAccountDatas = null;
final LocalDate expectedFirstDepositOnDate = null;
final BigDecimal totalOverdueAmount = null;
final Integer noOfOverdueInstallments = null;
final boolean isMandatoryDeposit = false;
final boolean allowWithdrawal = false;
final boolean adjustAdvanceTowardsFuturePayments = false;
final boolean isCalendarInherited = false;
final Integer recurringFrequency = null;
final EnumOptionData recurringFrequencyType = null;
final boolean withHoldTax = false;
final TaxGroupData taxGroup = null;
return new RecurringDepositAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
fieldOfficerId, fieldOfficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, minBalanceForInterestCalculation, summary,
transactions, productOptions, fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, charges, chargeOptions, accountChart, chartTemplate, preClosurePenalApplicable,
preClosurePenalInterest, preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions, minDepositTerm,
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
depositAmount, maturityAmount, maturityDate, depositPeriod, depositPeriodFrequency, mandatoryRecommendedDepositAmount,
periodFrequencyTypeOptions, depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas,
expectedFirstDepositOnDate, totalOverdueAmount, noOfOverdueInstallments, isMandatoryDeposit, allowWithdrawal,
adjustAdvanceTowardsFuturePayments, isCalendarInherited, recurringFrequency, recurringFrequencyType, withHoldTax, taxGroup);
}
public static RecurringDepositAccountData preClosureDetails(final Long accountId, final BigDecimal maturityAmount,
final Collection<EnumOptionData> onAccountClosureOptions, final Collection<PaymentTypeData> paymentTypeOptions,
final Collection<SavingsAccountData> savingsAccountDatas) {
final String accountNo = null;
final String externalId = null;
final Long productId = null;
final String productName = null;
final Long fieldOfficerId = null;
final String fieldOfficerName = null;
final SavingsAccountStatusEnumData status = null;
final SavingsAccountApplicationTimelineData timeline = null;
final CurrencyData currency = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final BigDecimal minRequiredOpeningBalance = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final boolean withdrawalFeeForTransfers = false;
final BigDecimal minBalanceForInterestCalculation = null;
final SavingsAccountSummaryData summary = null;
final Collection<SavingsAccountTransactionData> transactions = null;
final Collection<DepositProductData> productOptions = null;
final Collection<StaffData> fieldOfficerOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<SavingsAccountChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final DepositAccountInterestRateChartData accountChart = null;
final DepositAccountInterestRateChartData chartTemplate = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final BigDecimal depositAmount = null;
final LocalDate maturityDate = null;
final Integer depositPeriod = null;
final EnumOptionData depositPeriodFrequency = null;
final BigDecimal mandatoryRecommendedDepositAmount = null;
final EnumOptionData onAccountClosure = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
final EnumOptionData depositType = SavingsEnumerations.depositType(DepositAccountType.RECURRING_DEPOSIT.getValue());
final Long groupId = null;
final String groupName = null;
final Long clientId = null;
final String clientName = null;
final LocalDate expectedFirstDepositOnDate = null;
final BigDecimal totalOverdueAmount = null;
final Integer noOfOverdueInstallments = null;
final boolean isMandatoryDeposit = false;
final boolean allowWithdrawal = false;
final boolean adjustAdvanceTowardsFuturePayments = false;
final boolean isCalendarInherited = false;
final Integer recurringFrequency = null;
final EnumOptionData recurringFrequencyType = null;
final boolean withHoldTax = false;
final TaxGroupData taxGroup = null;
return new RecurringDepositAccountData(accountId, accountNo, externalId, groupId, groupName, clientId, clientName, productId,
productName, fieldOfficerId, fieldOfficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance,
lockinPeriodFrequency, lockinPeriodFrequencyType, withdrawalFeeForTransfers, minBalanceForInterestCalculation, summary,
transactions, productOptions, fieldOfficerOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, charges, chargeOptions, accountChart, chartTemplate, preClosurePenalApplicable,
preClosurePenalInterest, preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions, minDepositTerm,
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
depositAmount, maturityAmount, maturityDate, depositPeriod, depositPeriodFrequency, mandatoryRecommendedDepositAmount,
periodFrequencyTypeOptions, depositType, onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas,
expectedFirstDepositOnDate, totalOverdueAmount, noOfOverdueInstallments, isMandatoryDeposit, allowWithdrawal,
adjustAdvanceTowardsFuturePayments, isCalendarInherited, recurringFrequency, recurringFrequencyType, withHoldTax, taxGroup);
}
public static RecurringDepositAccountData withClosureTemplateDetails(final RecurringDepositAccountData account,
final Collection<EnumOptionData> onAccountClosureOptions, final Collection<PaymentTypeData> paymentTypeOptions,
final Collection<SavingsAccountData> savingsAccountDatas) {
return new RecurringDepositAccountData(account.id, account.accountNo, account.externalId, account.groupId, account.groupName,
account.clientId, account.clientName, account.depositProductId, account.depositProductName, account.fieldOfficerId,
account.fieldOfficerName, account.status, account.timeline, account.currency, account.nominalAnnualInterestRate,
account.interestCompoundingPeriodType, account.interestPostingPeriodType, account.interestCalculationType,
account.interestCalculationDaysInYearType, account.minRequiredOpeningBalance, account.lockinPeriodFrequency,
account.lockinPeriodFrequencyType, account.withdrawalFeeForTransfers, account.minBalanceForInterestCalculation,
account.summary, account.transactions, account.productOptions, account.fieldOfficerOptions,
account.interestCompoundingPeriodTypeOptions, account.interestPostingPeriodTypeOptions,
account.interestCalculationTypeOptions, account.interestCalculationDaysInYearTypeOptions,
account.lockinPeriodFrequencyTypeOptions, account.withdrawalFeeTypeOptions, account.charges, account.chargeOptions,
account.accountChart, account.chartTemplate, account.preClosurePenalApplicable, account.preClosurePenalInterest,
account.preClosurePenalInterestOnType, account.preClosurePenalInterestOnTypeOptions, account.minDepositTerm,
account.maxDepositTerm, account.minDepositTermType, account.maxDepositTermType, account.inMultiplesOfDepositTerm,
account.inMultiplesOfDepositTermType, account.depositAmount, account.maturityAmount, account.maturityDate,
account.depositPeriod, account.depositPeriodFrequency, account.mandatoryRecommendedDepositAmount,
account.periodFrequencyTypeOptions, account.depositType, account.onAccountClosure, onAccountClosureOptions,
paymentTypeOptions, savingsAccountDatas, account.expectedFirstDepositOnDate, account.totalOverdueAmount,
account.noOfOverdueInstallments, account.isMandatoryDeposit, account.allowWithdrawal,
account.adjustAdvanceTowardsFuturePayments, account.isCalendarInherited, account.recurringFrequency,
account.recurringFrequencyType, account.withHoldTax, account.taxGroup);
}
private RecurringDepositAccountData(final Long id, final String accountNo, final String externalId, final Long groupId,
final String groupName, final Long clientId, final String clientName, final Long productId, final String productName,
final Long fieldofficerId, final String fieldofficerName, final SavingsAccountStatusEnumData status,
final SavingsAccountApplicationTimelineData timeline, final CurrencyData currency, final BigDecimal nominalAnnualInterestRate,
final EnumOptionData interestPeriodType, final EnumOptionData interestPostingPeriodType,
final EnumOptionData interestCalculationType, final EnumOptionData interestCalculationDaysInYearType,
final BigDecimal minRequiredOpeningBalance, final Integer lockinPeriodFrequency, final EnumOptionData lockinPeriodFrequencyType,
final boolean withdrawalFeeForTransfers, final BigDecimal minBalanceForInterestCalculation,
final SavingsAccountSummaryData summary, final Collection<SavingsAccountTransactionData> transactions,
final Collection<DepositProductData> productOptions, final Collection<StaffData> fieldOfficerOptions,
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<SavingsAccountChargeData> charges, final Collection<ChargeData> chargeOptions,
final DepositAccountInterestRateChartData accountChart, final DepositAccountInterestRateChartData chartTemplate,
final boolean preClosurePenalApplicable, final BigDecimal preClosurePenalInterest,
final EnumOptionData preClosurePenalInterestOnType, final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
final Integer minDepositTerm, final Integer maxDepositTerm, final EnumOptionData minDepositTermType,
final EnumOptionData maxDepositTermType, final Integer inMultiplesOfDepositTerm,
final EnumOptionData inMultiplesOfDepositTermType, final BigDecimal depositAmount, final BigDecimal maturityAmount,
final LocalDate maturityDate, final Integer depositPeriod, final EnumOptionData depositPeriodFrequency,
final BigDecimal mandatoryRecommendedDepositAmount, final Collection<EnumOptionData> periodFrequencyTypeOptions,
final EnumOptionData depositType, final EnumOptionData onAccountClosure,
final Collection<EnumOptionData> onAccountClosureOptions, final Collection<PaymentTypeData> paymentTypeOptions,
final Collection<SavingsAccountData> savingsAccountDatas, final LocalDate expectedFirstDepositOnDate,
final BigDecimal totalOverdueAmount, final Integer noOfOverdueInstallments, final boolean isMandatoryDeposit,
final boolean allowWithdrawal, final boolean adjustAdvanceTowardsFuturePayments, final boolean isCalendarInherited,
final Integer recurringFrequency, final EnumOptionData recurringFrequencyType, final boolean withHoldTax,
final TaxGroupData taxGroup) {
super(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName, fieldofficerId, fieldofficerName,
status, timeline, currency, nominalAnnualInterestRate, interestPeriodType, interestPostingPeriodType,
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
lockinPeriodFrequencyType, withdrawalFeeForTransfers, summary, transactions, productOptions, fieldOfficerOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, charges,
chargeOptions, accountChart, chartTemplate, depositType, minBalanceForInterestCalculation, withHoldTax, taxGroup);
this.preClosurePenalApplicable = preClosurePenalApplicable;
this.preClosurePenalInterest = preClosurePenalInterest;
this.preClosurePenalInterestOnType = preClosurePenalInterestOnType;
this.minDepositTerm = minDepositTerm;
this.maxDepositTerm = maxDepositTerm;
this.minDepositTermType = minDepositTermType;
this.maxDepositTermType = maxDepositTermType;
this.inMultiplesOfDepositTerm = inMultiplesOfDepositTerm;
this.inMultiplesOfDepositTermType = inMultiplesOfDepositTermType;
this.depositAmount = depositAmount;
this.maturityAmount = maturityAmount;
this.maturityDate = maturityDate;
this.depositPeriod = depositPeriod;
this.depositPeriodFrequency = depositPeriodFrequency;
this.expectedFirstDepositOnDate = expectedFirstDepositOnDate;
this.mandatoryRecommendedDepositAmount = mandatoryRecommendedDepositAmount;
this.totalOverdueAmount = totalOverdueAmount;
this.noOfOverdueInstallments = noOfOverdueInstallments;
this.isMandatoryDeposit = isMandatoryDeposit;
this.allowWithdrawal = allowWithdrawal;
this.adjustAdvanceTowardsFuturePayments = adjustAdvanceTowardsFuturePayments;
this.isCalendarInherited = isCalendarInherited;
this.recurringFrequency = recurringFrequency;
this.recurringFrequencyType = recurringFrequencyType;
this.preClosurePenalInterestOnTypeOptions = preClosurePenalInterestOnTypeOptions;
this.periodFrequencyTypeOptions = periodFrequencyTypeOptions;
this.onAccountClosure = onAccountClosure;
this.savingsAccounts = savingsAccountDatas;
// account close template options
this.onAccountClosureOptions = onAccountClosureOptions;
this.paymentTypeOptions = paymentTypeOptions;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof RecurringDepositAccountData)) {
return false;
}
final RecurringDepositAccountData rhs = (RecurringDepositAccountData) obj;
return new EqualsBuilder().append(this.id, rhs.id).append(this.accountNo, rhs.accountNo).isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37).append(this.id).append(this.accountNo).toHashCode();
}
public boolean isIsMandatoryDeposit() {
return this.isMandatoryDeposit;
}
public boolean isIsCalendarInherited() {
return this.isCalendarInherited;
}
}
@@ -1,478 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.fineract.accounting.glaccount.data.GLAccountData;
import org.apache.fineract.accounting.producttoaccountmapping.data.ChargeToGLAccountMapper;
import org.apache.fineract.accounting.producttoaccountmapping.data.PaymentTypeToGLAccountMapper;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
import org.apache.fineract.portfolio.charge.data.ChargeData;
import org.apache.fineract.portfolio.interestratechart.data.InterestRateChartData;
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
import org.apache.fineract.portfolio.tax.data.TaxGroupData;
/**
* Immutable data object represent a Recurring Deposit product.
*/
public final class RecurringDepositProductData extends DepositProductData {
private boolean preClosurePenalApplicable;
private BigDecimal preClosurePenalInterest;
private EnumOptionData preClosurePenalInterestOnType;
private Integer minDepositTerm;
private Integer maxDepositTerm;
private EnumOptionData minDepositTermType;
private EnumOptionData maxDepositTermType;
private Integer inMultiplesOfDepositTerm;
private EnumOptionData inMultiplesOfDepositTermType;
private BigDecimal minDepositAmount;
private BigDecimal depositAmount;
private BigDecimal maxDepositAmount;
private boolean isMandatoryDeposit;
private boolean allowWithdrawal;
private boolean adjustAdvanceTowardsFuturePayments;
private Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
private Collection<EnumOptionData> periodFrequencyTypeOptions;
public static RecurringDepositProductData template(final CurrencyData currency, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final EnumOptionData accountingRule,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<PaymentTypeData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> chargeOptions,
final Collection<ChargeData> penaltyOptions, final InterestRateChartData chartTemplate,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
final Collection<EnumOptionData> periodFrequencyTypeOptions, final Collection<TaxGroupData> taxGroupOptions) {
final Long id = null;
final String name = null;
final String shortName = null;
final String description = null;
final BigDecimal nominalAnnualInterestRate = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final BigDecimal minBalanceForInterestCalculation = null;
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final boolean isMandatoryDeposit = false;
final boolean allowWithdrawal = false;
final boolean adjustAdvanceTowardsFuturePayments = false;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final BigDecimal minDepositAmount = null;
final BigDecimal depositAmount = null;
final BigDecimal maxDepositAmount = null;
final boolean withHoldTax = false;
final TaxGroupData taxGroup = null;
return new RecurringDepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate,
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
lockinPeriodFrequency, lockinPeriodFrequencyType, minBalanceForInterestCalculation, accountingRule, accountingMappings,
paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions, accountingMappingOptions, charges, chargeOptions,
penaltyOptions, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate,
preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions,
minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm,
inMultiplesOfDepositTermType, isMandatoryDeposit, allowWithdrawal, adjustAdvanceTowardsFuturePayments,
periodFrequencyTypeOptions, minDepositAmount, depositAmount, maxDepositAmount, withHoldTax, taxGroup, taxGroupOptions);
}
public static RecurringDepositProductData withCharges(final RecurringDepositProductData existingProduct,
final Collection<ChargeData> charges) {
return new RecurringDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName,
existingProduct.description, existingProduct.currency, existingProduct.nominalAnnualInterestRate,
existingProduct.interestCompoundingPeriodType, existingProduct.interestPostingPeriodType,
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType,
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType,
existingProduct.minBalanceForInterestCalculation, existingProduct.accountingRule, existingProduct.accountingMappings,
existingProduct.paymentChannelToFundSourceMappings, existingProduct.currencyOptions,
existingProduct.interestCompoundingPeriodTypeOptions, existingProduct.interestPostingPeriodTypeOptions,
existingProduct.interestCalculationTypeOptions, existingProduct.interestCalculationDaysInYearTypeOptions,
existingProduct.lockinPeriodFrequencyTypeOptions, existingProduct.withdrawalFeeTypeOptions,
existingProduct.paymentTypeOptions, existingProduct.accountingRuleOptions, existingProduct.accountingMappingOptions,
charges, existingProduct.chargeOptions, existingProduct.penaltyOptions, existingProduct.feeToIncomeAccountMappings,
existingProduct.penaltyToIncomeAccountMappings, existingProduct.interestRateCharts, existingProduct.chartTemplate,
existingProduct.preClosurePenalApplicable, existingProduct.preClosurePenalInterest,
existingProduct.preClosurePenalInterestOnType, existingProduct.preClosurePenalInterestOnTypeOptions,
existingProduct.minDepositTerm, existingProduct.maxDepositTerm, existingProduct.minDepositTermType,
existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm, existingProduct.inMultiplesOfDepositTermType,
existingProduct.isMandatoryDeposit, existingProduct.allowWithdrawal, existingProduct.adjustAdvanceTowardsFuturePayments,
existingProduct.periodFrequencyTypeOptions, existingProduct.minDepositAmount, existingProduct.depositAmount,
existingProduct.maxDepositAmount, existingProduct.withHoldTax, existingProduct.taxGroup, existingProduct.taxGroupOptions);
}
/**
* Returns a {@link RecurringDepositProductData} that contains and exist {@link RecurringDepositProductData} data
* with further template data for dropdowns.
*
* @param taxGroupOptions
* TODO
*/
public static RecurringDepositProductData withTemplate(final RecurringDepositProductData existingProduct,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<PaymentTypeData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> chargeOptions,
final Collection<ChargeData> penaltyOptions, final InterestRateChartData chartTemplate,
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
final Collection<EnumOptionData> periodFrequencyTypeOptions, final Collection<TaxGroupData> taxGroupOptions) {
return new RecurringDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName,
existingProduct.description, existingProduct.currency, existingProduct.nominalAnnualInterestRate,
existingProduct.interestCompoundingPeriodType, existingProduct.interestPostingPeriodType,
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType,
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType,
existingProduct.minBalanceForInterestCalculation, existingProduct.accountingRule, existingProduct.accountingMappings,
existingProduct.paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions,
interestPostingPeriodTypeOptions, interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions,
lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions,
accountingMappingOptions, existingProduct.charges, chargeOptions, penaltyOptions,
existingProduct.feeToIncomeAccountMappings, existingProduct.penaltyToIncomeAccountMappings,
existingProduct.interestRateCharts, chartTemplate, existingProduct.preClosurePenalApplicable,
existingProduct.preClosurePenalInterest, existingProduct.preClosurePenalInterestOnType,
preClosurePenalInterestOnTypeOptions, existingProduct.minDepositTerm, existingProduct.maxDepositTerm,
existingProduct.minDepositTermType, existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm,
existingProduct.inMultiplesOfDepositTermType, existingProduct.isMandatoryDeposit, existingProduct.allowWithdrawal,
existingProduct.adjustAdvanceTowardsFuturePayments, periodFrequencyTypeOptions, existingProduct.minDepositAmount,
existingProduct.depositAmount, existingProduct.maxDepositAmount, existingProduct.withHoldTax, existingProduct.taxGroup,
taxGroupOptions);
}
public static RecurringDepositProductData withAccountingDetails(final RecurringDepositProductData existingProduct,
final Map<String, Object> accountingMappings, final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings) {
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
return new RecurringDepositProductData(existingProduct.id, existingProduct.name, existingProduct.shortName,
existingProduct.description, existingProduct.currency, existingProduct.nominalAnnualInterestRate,
existingProduct.interestCompoundingPeriodType, existingProduct.interestPostingPeriodType,
existingProduct.interestCalculationType, existingProduct.interestCalculationDaysInYearType,
existingProduct.lockinPeriodFrequency, existingProduct.lockinPeriodFrequencyType,
existingProduct.minBalanceForInterestCalculation, existingProduct.accountingRule, accountingMappings,
paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions, accountingMappingOptions, existingProduct.charges,
chargeOptions, penaltyOptions, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings,
existingProduct.interestRateCharts, existingProduct.chartTemplate, existingProduct.preClosurePenalApplicable,
existingProduct.preClosurePenalInterest, existingProduct.preClosurePenalInterestOnType,
existingProduct.preClosurePenalInterestOnTypeOptions, existingProduct.minDepositTerm, existingProduct.maxDepositTerm,
existingProduct.minDepositTermType, existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm,
existingProduct.inMultiplesOfDepositTermType, existingProduct.isMandatoryDeposit, existingProduct.allowWithdrawal,
existingProduct.adjustAdvanceTowardsFuturePayments, existingProduct.periodFrequencyTypeOptions,
existingProduct.minDepositAmount, existingProduct.depositAmount, existingProduct.maxDepositAmount,
existingProduct.withHoldTax, existingProduct.taxGroup, existingProduct.taxGroupOptions);
}
public static RecurringDepositProductData instance(final DepositProductData depositProductData, final boolean preClosurePenalApplicable,
final BigDecimal preClosurePenalInterest, final EnumOptionData preClosurePenalInterestOnType, final Integer minDepositTerm,
final Integer maxDepositTerm, final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType,
final Integer inMultiplesOfDepositTerm, final EnumOptionData inMultiplesOfDepositTermType, final boolean isMandatoryDeposit,
boolean allowWithdrawal, boolean adjustAdvanceTowardsFuturePayments, final BigDecimal minDepositAmount,
final BigDecimal depositAmount, final BigDecimal maxDepositAmount) {
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final InterestRateChartData chartTemplate = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
final Collection<TaxGroupData> taxGroupOptions = null;
return new RecurringDepositProductData(depositProductData.id, depositProductData.name, depositProductData.shortName,
depositProductData.description, depositProductData.currency, depositProductData.nominalAnnualInterestRate,
depositProductData.interestCompoundingPeriodType, depositProductData.interestPostingPeriodType,
depositProductData.interestCalculationType, depositProductData.interestCalculationDaysInYearType,
depositProductData.lockinPeriodFrequency, depositProductData.lockinPeriodFrequencyType,
depositProductData.minBalanceForInterestCalculation, depositProductData.accountingRule, accountingMappings,
paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions, accountingMappingOptions, charges, chargeOptions,
penaltyOptions, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate,
preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions,
minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm,
inMultiplesOfDepositTermType, isMandatoryDeposit, allowWithdrawal, adjustAdvanceTowardsFuturePayments,
periodFrequencyTypeOptions, minDepositAmount, depositAmount, maxDepositAmount, depositProductData.withHoldTax,
depositProductData.taxGroup, taxGroupOptions);
}
public static RecurringDepositProductData lookup(final Long id, final String name) {
final String shortName = null;
final CurrencyData currency = null;
final String description = null;
final BigDecimal nominalAnnualInterestRate = null;
final EnumOptionData interestCompoundingPeriodType = null;
final EnumOptionData interestPostingPeriodType = null;
final EnumOptionData interestCalculationType = null;
final EnumOptionData interestCalculationDaysInYearType = null;
final Integer lockinPeriodFrequency = null;
final EnumOptionData lockinPeriodFrequencyType = null;
final BigDecimal minBalanceForInterestCalculation = null;
final EnumOptionData accountingType = null;
final Map<String, Object> accountingMappings = null;
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
final Collection<CurrencyData> currencyOptions = null;
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = null;
final Collection<EnumOptionData> interestCalculationTypeOptions = null;
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = null;
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = null;
final Collection<EnumOptionData> withdrawalFeeTypeOptions = null;
final Collection<PaymentTypeData> paymentTypeOptions = null;
final Collection<EnumOptionData> accountingRuleOptions = null;
final Map<String, List<GLAccountData>> accountingMappingOptions = null;
final Collection<ChargeData> charges = null;
final Collection<ChargeData> chargeOptions = null;
final Collection<ChargeData> penaltyOptions = null;
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings = null;
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings = null;
final Collection<InterestRateChartData> interestRateCharts = null;
final InterestRateChartData chartTemplate = null;
final boolean preClosurePenalApplicable = false;
final BigDecimal preClosurePenalInterest = null;
final EnumOptionData preClosurePenalInterestOnType = null;
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
final boolean isMandatoryDeposit = false;
final boolean allowWithdrawal = false;
final boolean adjustAdvanceTowardsFuturePayments = false;
final Integer minDepositTerm = null;
final Integer maxDepositTerm = null;
final EnumOptionData minDepositTermType = null;
final EnumOptionData maxDepositTermType = null;
final Integer inMultiplesOfDepositTerm = null;
final EnumOptionData inMultiplesOfDepositTermType = null;
final Collection<EnumOptionData> periodFrequencyTypeOptions = null;
final BigDecimal minDepositAmount = null;
final BigDecimal depositAmount = null;
final BigDecimal maxDepositAmount = null;
final boolean withHoldTax = false;
final TaxGroupData taxGroup = null;
final Collection<TaxGroupData> taxGroupOptions = null;
return new RecurringDepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate,
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
lockinPeriodFrequency, lockinPeriodFrequencyType, minBalanceForInterestCalculation, accountingType, accountingMappings,
paymentChannelToFundSourceMappings, currencyOptions, interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions,
interestCalculationTypeOptions, interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions,
withdrawalFeeTypeOptions, paymentTypeOptions, accountingRuleOptions, accountingMappingOptions, charges, chargeOptions,
penaltyOptions, feeToIncomeAccountMappings, penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate,
preClosurePenalApplicable, preClosurePenalInterest, preClosurePenalInterestOnType, preClosurePenalInterestOnTypeOptions,
minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm,
inMultiplesOfDepositTermType, isMandatoryDeposit, allowWithdrawal, adjustAdvanceTowardsFuturePayments,
periodFrequencyTypeOptions, minDepositAmount, depositAmount, maxDepositAmount, withHoldTax, taxGroup, taxGroupOptions);
}
public static RecurringDepositProductData withInterestChart(final RecurringDepositProductData product,
final Collection<InterestRateChartData> interestRateCharts) {
return new RecurringDepositProductData(product.id, product.name, product.shortName, product.description, product.currency,
product.nominalAnnualInterestRate, product.interestCompoundingPeriodType, product.interestPostingPeriodType,
product.interestCalculationType, product.interestCalculationDaysInYearType, product.lockinPeriodFrequency,
product.lockinPeriodFrequencyType, product.minBalanceForInterestCalculation, product.accountingRule,
product.accountingMappings, product.paymentChannelToFundSourceMappings, product.currencyOptions,
product.interestCompoundingPeriodTypeOptions, product.interestPostingPeriodTypeOptions,
product.interestCalculationTypeOptions, product.interestCalculationDaysInYearTypeOptions,
product.lockinPeriodFrequencyTypeOptions, product.withdrawalFeeTypeOptions, product.paymentTypeOptions,
product.accountingRuleOptions, product.accountingMappingOptions, product.charges, product.chargeOptions,
product.penaltyOptions, product.feeToIncomeAccountMappings, product.penaltyToIncomeAccountMappings, interestRateCharts,
product.chartTemplate, product.preClosurePenalApplicable, product.preClosurePenalInterest,
product.preClosurePenalInterestOnType, product.preClosurePenalInterestOnTypeOptions, product.minDepositTerm,
product.maxDepositTerm, product.minDepositTermType, product.maxDepositTermType, product.inMultiplesOfDepositTerm,
product.inMultiplesOfDepositTermType, product.isMandatoryDeposit, product.allowWithdrawal,
product.adjustAdvanceTowardsFuturePayments, product.periodFrequencyTypeOptions, product.minDepositAmount,
product.depositAmount, product.maxDepositAmount, product.withHoldTax, product.taxGroup, product.taxGroupOptions);
}
private RecurringDepositProductData(final Long id, final String name, final String shortName, final String description,
final CurrencyData currency, final BigDecimal nominalAnnualInterestRate, final EnumOptionData interestCompoundingPeriodType,
final EnumOptionData interestPostingPeriodType, final EnumOptionData interestCalculationType,
final EnumOptionData interestCalculationDaysInYearType, final Integer lockinPeriodFrequency,
final EnumOptionData lockinPeriodFrequencyType, final BigDecimal minBalanceForInterestCalculation,
final EnumOptionData accountingType, final Map<String, Object> accountingMappings,
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings,
final Collection<CurrencyData> currencyOptions, final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions,
final Collection<EnumOptionData> interestPostingPeriodTypeOptions,
final Collection<EnumOptionData> interestCalculationTypeOptions,
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions,
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions, final Collection<EnumOptionData> withdrawalFeeTypeOptions,
final Collection<PaymentTypeData> paymentTypeOptions, final Collection<EnumOptionData> accountingRuleOptions,
final Map<String, List<GLAccountData>> accountingMappingOptions, final Collection<ChargeData> charges,
final Collection<ChargeData> chargeOptions, final Collection<ChargeData> penaltyOptions,
final Collection<ChargeToGLAccountMapper> feeToIncomeAccountMappings,
final Collection<ChargeToGLAccountMapper> penaltyToIncomeAccountMappings,
final Collection<InterestRateChartData> interestRateCharts, final InterestRateChartData chartTemplate,
final boolean preClosurePenalApplicable, final BigDecimal preClosurePenalInterest,
final EnumOptionData preClosurePenalInterestOnType, final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions,
final Integer minDepositTerm, final Integer maxDepositTerm, final EnumOptionData minDepositTermType,
final EnumOptionData maxDepositTermType, final Integer inMultiplesOfDepositTerm,
final EnumOptionData inMultiplesOfDepositTermType, final boolean isMandatoryDeposit, boolean allowWithdrawal,
boolean adjustAdvanceTowardsFuturePayments, final Collection<EnumOptionData> periodFrequencyTypeOptions,
final BigDecimal minDepositAmount, final BigDecimal depositAmount, final BigDecimal maxDepositAmount, final boolean withHoldTax,
final TaxGroupData taxGroup, final Collection<TaxGroupData> taxGroupOptions) {
super(id, name, shortName, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency,
lockinPeriodFrequencyType, accountingType, accountingMappings, paymentChannelToFundSourceMappings, currencyOptions,
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, paymentTypeOptions,
accountingRuleOptions, accountingMappingOptions, charges, chargeOptions, penaltyOptions, feeToIncomeAccountMappings,
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, minBalanceForInterestCalculation, withHoldTax, taxGroup,
taxGroupOptions);
this.preClosurePenalApplicable = preClosurePenalApplicable;
this.preClosurePenalInterest = preClosurePenalInterest;
this.preClosurePenalInterestOnType = preClosurePenalInterestOnType;
this.minDepositTerm = minDepositTerm;
this.maxDepositTerm = maxDepositTerm;
this.minDepositTermType = minDepositTermType;
this.maxDepositTermType = maxDepositTermType;
this.inMultiplesOfDepositTerm = inMultiplesOfDepositTerm;
this.inMultiplesOfDepositTermType = inMultiplesOfDepositTermType;
this.minDepositAmount = minDepositAmount;
this.depositAmount = depositAmount;
this.maxDepositAmount = maxDepositAmount;
this.isMandatoryDeposit = isMandatoryDeposit;
this.allowWithdrawal = allowWithdrawal;
this.adjustAdvanceTowardsFuturePayments = adjustAdvanceTowardsFuturePayments;
// template data
this.preClosurePenalInterestOnTypeOptions = preClosurePenalInterestOnTypeOptions;
this.periodFrequencyTypeOptions = periodFrequencyTypeOptions;
}
public EnumOptionData getMinDepositTermType() {
return minDepositTermType;
}
public boolean isPreClosurePenalApplicable() {
return preClosurePenalApplicable;
}
public BigDecimal getPreClosurePenalInterest() {
return preClosurePenalInterest;
}
public EnumOptionData getPreClosurePenalInterestOnType() {
return preClosurePenalInterestOnType;
}
public Integer getMinDepositTerm() {
return minDepositTerm;
}
public Integer getMaxDepositTerm() {
return maxDepositTerm;
}
public EnumOptionData getMaxDepositTermType() {
return maxDepositTermType;
}
public BigDecimal getMinDepositAmount() {
return minDepositAmount;
}
public BigDecimal getDepositAmount() {
return depositAmount;
}
public BigDecimal getMaxDepositAmount() {
return maxDepositAmount;
}
public Integer getInMultiplesOfDepositTerm() {
return inMultiplesOfDepositTerm;
}
public EnumOptionData getInMultiplesOfDepositTermType() {
return inMultiplesOfDepositTermType;
}
public boolean isMandatoryDeposit() {
return isMandatoryDeposit;
}
public boolean isAllowWithdrawal() {
return allowWithdrawal;
}
public boolean isAdjustAdvanceTowardsFuturePayments() {
return adjustAdvanceTowardsFuturePayments;
}
}
@@ -1,57 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.time.LocalDate;
public final class SavingsAccountAnnualFeeData {
private final Long id;
private final Long accountId;
private final String accountNo;
private final LocalDate nextAnnualFeeDueDate;
public static SavingsAccountAnnualFeeData instance(final Long id, final Long accountId, final String accountNo,
final LocalDate nextAnnualFeeDueDate) {
return new SavingsAccountAnnualFeeData(id, accountId, accountNo, nextAnnualFeeDueDate);
}
private SavingsAccountAnnualFeeData(final Long id, final Long accountId, final String accountNo, final LocalDate nextAnnualFeeDueDate) {
this.id = id;
this.accountId = accountId;
this.accountNo = accountNo;
this.nextAnnualFeeDueDate = nextAnnualFeeDueDate;
}
public Long getId() {
return this.id;
}
public Long getAccountId() {
return this.accountId;
}
public LocalDate getNextAnnualFeeDueDate() {
return this.nextAnnualFeeDueDate;
}
public String getAccountNo() {
return this.accountNo;
}
}
@@ -1,158 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_CHARGE_RESOURCE_NAME;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.amountParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.chargeIdParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.feeIntervalParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.feeOnMonthDayParamName;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.MonthDay;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class SavingsAccountChargeDataValidator {
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public SavingsAccountChargeDataValidator(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public void validateAdd(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
SavingsAccountConstant.SAVINGS_ACCOUNT_CHARGES_ADD_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(SAVINGS_ACCOUNT_CHARGE_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final Long chargeId = this.fromApiJsonHelper.extractLongNamed(chargeIdParamName, element);
baseDataValidator.reset().parameter(chargeIdParamName).value(chargeId).notNull().integerGreaterThanZero();
final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(amountParamName, element);
baseDataValidator.reset().parameter(amountParamName).value(amount).notNull().positiveAmount();
if (this.fromApiJsonHelper.parameterExists(dueAsOfDateParamName, element)) {
final LocalDate transactionDate = this.fromApiJsonHelper.extractLocalDateNamed(dueAsOfDateParamName, element);
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(transactionDate).notNull();
}
if (this.fromApiJsonHelper.parameterExists(feeOnMonthDayParamName, element)) {
final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed(feeOnMonthDayParamName, element);
baseDataValidator.reset().parameter(feeOnMonthDayParamName).value(monthDay).notNull();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateUpdate(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
SavingsAccountConstant.SAVINGS_ACCOUNT_CHARGES_ADD_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(SAVINGS_ACCOUNT_CHARGE_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(amountParamName, element);
baseDataValidator.reset().parameter(amountParamName).value(amount).notNull().positiveAmount();
if (this.fromApiJsonHelper.parameterExists(dueAsOfDateParamName, element)) {
final LocalDate transactionDate = this.fromApiJsonHelper.extractLocalDateNamed(dueAsOfDateParamName, element);
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(transactionDate).notNull();
}
if (this.fromApiJsonHelper.parameterExists(feeOnMonthDayParamName, element)) {
final String monthDayFormat = this.fromApiJsonHelper.extractMonthDayFormatParameter(element.getAsJsonObject());
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(element.getAsJsonObject());
final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed(feeOnMonthDayParamName, element.getAsJsonObject(),
monthDayFormat, locale);
baseDataValidator.reset().parameter(feeOnMonthDayParamName).value(monthDay).notNull();
}
if (this.fromApiJsonHelper.parameterExists(feeIntervalParamName, element)) {
final Integer feeInterval = this.fromApiJsonHelper.extractIntegerNamed(feeIntervalParamName, element, Locale.getDefault());
baseDataValidator.reset().parameter(feeIntervalParamName).value(feeInterval).notNull().inMinMaxRange(1, 12);
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validatePayCharge(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
SavingsAccountConstant.SAVINGS_ACCOUNT_CHARGES_PAY_CHARGE_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(SAVINGS_ACCOUNT_CHARGE_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(amountParamName, element);
baseDataValidator.reset().parameter(amountParamName).value(amount).notNull().positiveAmount();
final LocalDate transactionDate = this.fromApiJsonHelper.extractLocalDateNamed(dueAsOfDateParamName, element);
baseDataValidator.reset().parameter(dueAsOfDateParamName).value(transactionDate).notNull();
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
}
}
@@ -1,72 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.apache.fineract.portfolio.savings.SavingsApiConstants;
public class SavingsAccountConstant extends SavingsApiConstants {
/**
* These parameters will match the class level parameters of {@link SavingsProductData}. Where possible, we try to
* get response parameters to match those of request parameters.
*/
protected static final Set<String> SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(localeParamName,
dateFormatParamName, monthDayFormatParamName, staffIdParamName, isGSIM, isParentAccount, accountNoParamName,
externalIdParamName, clientIdParamName, groupIdParamName, productIdParamName, fieldOfficerIdParamName, submittedOnDateParamName,
nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName,
interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName,
lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName,
// withdrawalFeeAmountParamName, withdrawalFeeTypeParamName,
withdrawalFeeForTransfersParamName, feeAmountParamName, feeOnMonthDayParamName, chargesParamName, allowOverdraftParamName,
overdraftLimitParamName, minRequiredBalanceParamName, enforceMinRequiredBalanceParamName, lienAllowedParamName,
maxAllowedLienLimitParamName, nominalAnnualInterestRateOverdraftParamName, minOverdraftForInterestCalculationParamName,
withHoldTaxParamName, datatables, gsimApplicationId, gsimLastApplication));
/**
* These parameters will match the class level parameters of {@link SavingsAccountData}. Where possible, we try to
* get response parameters to match those of request parameters.
*/
protected static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_REQUEST_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(localeParamName, dateFormatParamName, transactionDateParamName, transactionAmountParamName,
paymentTypeIdParamName, transactionAccountNumberParamName, checkNumberParamName, routingCodeParamName,
receiptNumberParamName, bankNumberParamName, retailEntriesParamName, childAccountIdParamName, noteParamName));
protected static final Set<String> SAVINGS_ACCOUNT_TRANSACTION_RESPONSE_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(idParamName, accountNoParamName));
protected static final Set<String> SAVINGS_ACCOUNT_ACTIVATION_REQUEST_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(localeParamName, dateFormatParamName, activatedOnDateParamName));
protected static final Set<String> SAVINGS_ACCOUNT_CLOSE_REQUEST_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(localeParamName, dateFormatParamName, closedOnDateParamName, noteParamName, paymentTypeIdParamName,
withdrawBalanceParamName, transactionAccountNumberParamName, checkNumberParamName, routingCodeParamName,
receiptNumberParamName, bankNumberParamName, postInterestValidationOnClosure));
protected static final Set<String> SAVINGS_ACCOUNT_CHARGES_ADD_REQUEST_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(chargeIdParamName, amountParamName, dueAsOfDateParamName, dateFormatParamName, localeParamName,
feeOnMonthDayParamName, monthDayFormatParamName, feeIntervalParamName));
protected static final Set<String> SAVINGS_ACCOUNT_CHARGES_PAY_CHARGE_REQUEST_DATA_PARAMETERS = new HashSet<>(
Arrays.asList(amountParamName, dueAsOfDateParamName, dateFormatParamName, localeParamName, noteParamName));
}
@@ -1,69 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import org.apache.fineract.portfolio.client.domain.Client;
import org.apache.fineract.portfolio.group.domain.Group;
import org.apache.fineract.useradministration.domain.AppUser;
public class SavingsAccountDataDTO {
private final Client client;
private final Group group;
private final Long savingsProductId;
private final LocalDate applicationDate;
private final AppUser appliedBy;
private final DateTimeFormatter fmt;
public SavingsAccountDataDTO(final Client client, final Group group, final Long savingsProductId, final LocalDate applicationDate,
final AppUser appliedBy, final DateTimeFormatter fmt) {
this.client = client;
this.group = group;
this.savingsProductId = savingsProductId;
this.applicationDate = applicationDate;
this.appliedBy = appliedBy;
this.fmt = fmt;
}
public Client getClient() {
return this.client;
}
public Group getGroup() {
return this.group;
}
public Long getSavingsProduct() {
return this.savingsProductId;
}
public LocalDate getApplicationDate() {
return this.applicationDate;
}
public AppUser getAppliedBy() {
return this.appliedBy;
}
public DateTimeFormatter getFmt() {
return this.fmt;
}
}
@@ -1,534 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountNoParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.allowOverdraftParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.amountParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.chargeIdParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.chargesParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.clientIdParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.externalIdParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.feeIntervalParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.feeOnMonthDayParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.fieldOfficerIdParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.groupIdParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculationTypeParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestPostingPeriodTypeParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lienAllowedParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.maxAllowedLienLimitParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minOverdraftForInterestCalculationParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minRequiredOpeningBalanceParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateOverdraftParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.overdraftLimitParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.productIdParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.submittedOnDateParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.MonthDay;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.savings.SavingsApiConstants;
import org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodType;
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationDaysInYearType;
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationType;
import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class SavingsAccountDataValidator {
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public SavingsAccountDataValidator(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public void validateForSubmit(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
SavingsAccountConstant.SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final Long clientId = this.fromApiJsonHelper.extractLongNamed(clientIdParamName, element);
if (clientId != null) {
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).longGreaterThanZero();
}
final Long groupId = this.fromApiJsonHelper.extractLongNamed(groupIdParamName, element);
if (groupId != null) {
baseDataValidator.reset().parameter(groupIdParamName).value(groupId).longGreaterThanZero();
}
if (clientId == null && groupId == null) {
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).notNull().integerGreaterThanZero();
}
final Long productId = this.fromApiJsonHelper.extractLongNamed(productIdParamName, element);
baseDataValidator.reset().parameter(productIdParamName).value(productId).notNull().integerGreaterThanZero();
if (this.fromApiJsonHelper.parameterExists(fieldOfficerIdParamName, element)) {
final Long fieldOfficerId = this.fromApiJsonHelper.extractLongNamed(fieldOfficerIdParamName, element);
baseDataValidator.reset().parameter(fieldOfficerIdParamName).value(fieldOfficerId).ignoreIfNull().integerGreaterThanZero();
}
final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed(submittedOnDateParamName, element);
baseDataValidator.reset().parameter(submittedOnDateParamName).value(submittedOnDate).notNull();
if (this.fromApiJsonHelper.parameterExists(accountNoParamName, element)) {
final String accountNo = this.fromApiJsonHelper.extractStringNamed(accountNoParamName, element);
baseDataValidator.reset().parameter(accountNoParamName).value(accountNo).notBlank().notExceedingLengthOf(20);
}
if (this.fromApiJsonHelper.parameterExists(externalIdParamName, element)) {
final String externalId = this.fromApiJsonHelper.extractStringNamed(externalIdParamName, element);
baseDataValidator.reset().parameter(externalIdParamName).value(externalId).notExceedingLengthOf(100);
}
if (this.fromApiJsonHelper.parameterExists(nominalAnnualInterestRateParamName, element)) {
final BigDecimal interestRate = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName,
element);
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
final Integer interestCompoundingPeriodType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestCompoundingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
.isOneOfTheseValues(SavingsCompoundingInterestPeriodType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestPostingPeriodTypeParamName, element)) {
final Integer interestPostingPeriodType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestPostingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestPostingPeriodTypeParamName).value(interestPostingPeriodType).notNull()
.isOneOfTheseValues(SavingsPostingInterestPeriodType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
final Integer interestCalculationType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName,
element);
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull()
.isOneOfTheseValues(SavingsInterestCalculationType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestCalculationDaysInYearTypeParamName, element)) {
final Integer interestCalculationDaysInYearType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestCalculationDaysInYearTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType)
.notNull().isOneOfTheseValues(SavingsInterestCalculationDaysInYearType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
final BigDecimal minOpeningBalance = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName,
element);
baseDataValidator.reset().parameter(minRequiredOpeningBalanceParamName).value(minOpeningBalance).zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
final Integer lockinPeriodFrequency = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).integerZeroOrGreater();
if (lockinPeriodFrequency != null) {
final Integer lockinPeriodFrequencyType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName, element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).notNull()
.inMinMaxRange(0, 3);
}
}
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
final Integer lockinPeriodFrequencyType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName, element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(0, 3);
if (lockinPeriodFrequencyType != null) {
final Integer lockinPeriodFrequency = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).notNull()
.integerZeroOrGreater();
}
}
if (this.fromApiJsonHelper.parameterExists(withdrawalFeeForTransfersParamName, element)) {
final Boolean isWithdrawalFeeApplicableForTransfers = this.fromApiJsonHelper
.extractBooleanNamed(withdrawalFeeForTransfersParamName, element);
baseDataValidator.reset().parameter(withdrawalFeeForTransfersParamName).value(isWithdrawalFeeApplicableForTransfers)
.ignoreIfNull().validateForBooleanValue();
}
if (this.fromApiJsonHelper.parameterExists(withHoldTaxParamName, element)) {
final String withHoldTax = this.fromApiJsonHelper.extractStringNamed(withHoldTaxParamName, element);
baseDataValidator.reset().parameter(withHoldTaxParamName).value(withHoldTax).ignoreIfNull().validateForBooleanValue();
}
if (this.fromApiJsonHelper.parameterExists(SavingsApiConstants.datatables, element)) {
final JsonArray datatables = this.fromApiJsonHelper.extractJsonArrayNamed(SavingsApiConstants.datatables, element);
baseDataValidator.reset().parameter(SavingsApiConstants.datatables).value(datatables).notNull().jsonArrayNotEmpty();
}
validateSavingsCharges(element, baseDataValidator);
validateOverdraftParams(baseDataValidator, element);
validateLienParams(baseDataValidator, element);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void validateSavingsCharges(final JsonElement element, final DataValidatorBuilder baseDataValidator) {
if (element.isJsonObject()) {
final JsonObject topLevelJsonElement = element.getAsJsonObject();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement);
final String monthDayFormat = this.fromApiJsonHelper.extractMonthDayFormatParameter(topLevelJsonElement);
if (topLevelJsonElement.has(chargesParamName) && topLevelJsonElement.get(chargesParamName).isJsonArray()) {
final JsonArray array = topLevelJsonElement.get(chargesParamName).getAsJsonArray();
for (int i = 0; i < array.size(); i++) {
final JsonObject savingsChargeElement = array.get(i).getAsJsonObject();
// final Long id =
// this.fromApiJsonHelper.extractLongNamed(idParamName,
// savingsChargeElement);
final Long chargeId = this.fromApiJsonHelper.extractLongNamed(chargeIdParamName, savingsChargeElement);
baseDataValidator.reset().parameter(chargeIdParamName).value(chargeId).longGreaterThanZero();
final BigDecimal amount = this.fromApiJsonHelper.extractBigDecimalNamed(amountParamName, savingsChargeElement, locale);
baseDataValidator.reset().parameter(amountParamName).value(amount).notNull().positiveAmount();
if (this.fromApiJsonHelper.parameterExists(feeOnMonthDayParamName, savingsChargeElement)) {
final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed(feeOnMonthDayParamName, savingsChargeElement,
monthDayFormat, locale);
baseDataValidator.reset().parameter(feeOnMonthDayParamName).value(monthDay).notNull();
}
if (this.fromApiJsonHelper.parameterExists(feeIntervalParamName, savingsChargeElement)) {
final Integer feeInterval = this.fromApiJsonHelper.extractIntegerNamed(feeIntervalParamName, savingsChargeElement,
Locale.getDefault());
baseDataValidator.reset().parameter(feeIntervalParamName).value(feeInterval).notNull().inMinMaxRange(1, 12);
}
}
}
}
}
public void validateForUpdate(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
SavingsAccountConstant.SAVINGS_ACCOUNT_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
Long clientId = null;
if (this.fromApiJsonHelper.parameterExists(clientIdParamName, element)) {
clientId = this.fromApiJsonHelper.extractLongNamed(clientIdParamName, element);
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).ignoreIfNull().longGreaterThanZero();
Long groupId = null;
if (this.fromApiJsonHelper.parameterExists(productIdParamName, element)) {
groupId = this.fromApiJsonHelper.extractLongNamed(groupIdParamName, element);
baseDataValidator.reset().parameter(groupIdParamName).value(groupId).ignoreIfNull().longGreaterThanZero();
}
if (clientId == null && groupId == null) {
// either clientId or groupId must exists if param passed for
// update.
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).notNull().integerGreaterThanZero();
}
}
Long groupId = null;
if (this.fromApiJsonHelper.parameterExists(groupIdParamName, element)) {
groupId = this.fromApiJsonHelper.extractLongNamed(groupIdParamName, element);
baseDataValidator.reset().parameter(groupIdParamName).value(groupId).ignoreIfNull().longGreaterThanZero();
if (this.fromApiJsonHelper.parameterExists(clientIdParamName, element)) {
clientId = this.fromApiJsonHelper.extractLongNamed(clientIdParamName, element);
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).ignoreIfNull().longGreaterThanZero();
}
if (clientId == null && groupId == null) {
// either clientId or groupId must exists if param passed for
// update.
baseDataValidator.reset().parameter(clientIdParamName).value(clientId).notNull().integerGreaterThanZero();
}
}
if (this.fromApiJsonHelper.parameterExists(productIdParamName, element)) {
final Long productId = this.fromApiJsonHelper.extractLongNamed(productIdParamName, element);
baseDataValidator.reset().parameter(productIdParamName).value(productId).notNull().integerGreaterThanZero();
}
if (this.fromApiJsonHelper.parameterExists(fieldOfficerIdParamName, element)) {
final Long fieldOfficerId = this.fromApiJsonHelper.extractLongNamed(fieldOfficerIdParamName, element);
baseDataValidator.reset().parameter(fieldOfficerIdParamName).value(fieldOfficerId).ignoreIfNull().integerGreaterThanZero();
}
if (this.fromApiJsonHelper.parameterExists(submittedOnDateParamName, element)) {
final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed(submittedOnDateParamName, element);
baseDataValidator.reset().parameter(submittedOnDateParamName).value(submittedOnDate).notNull();
}
if (this.fromApiJsonHelper.parameterExists(accountNoParamName, element)) {
final String accountNo = this.fromApiJsonHelper.extractStringNamed(accountNoParamName, element);
baseDataValidator.reset().parameter(accountNoParamName).value(accountNo).notBlank().notExceedingLengthOf(20);
}
if (this.fromApiJsonHelper.parameterExists(externalIdParamName, element)) {
final String externalId = this.fromApiJsonHelper.extractStringNamed(externalIdParamName, element);
baseDataValidator.reset().parameter(externalIdParamName).value(externalId).notExceedingLengthOf(100);
}
if (this.fromApiJsonHelper.parameterExists(nominalAnnualInterestRateParamName, element)) {
final BigDecimal interestRate = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName,
element);
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
final Integer interestCompoundingPeriodType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestCompoundingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
.isOneOfTheseValues(SavingsCompoundingInterestPeriodType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestPostingPeriodTypeParamName, element)) {
final Integer interestPostingPeriodType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestPostingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestPostingPeriodTypeParamName).value(interestPostingPeriodType).notNull()
.isOneOfTheseValues(SavingsPostingInterestPeriodType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
final Integer interestCalculationType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName,
element);
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull()
.isOneOfTheseValues(SavingsInterestCalculationType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestCalculationDaysInYearTypeParamName, element)) {
final Integer interestCalculationDaysInYearType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestCalculationDaysInYearTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType)
.notNull().isOneOfTheseValues(SavingsInterestCalculationDaysInYearType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
final BigDecimal minOpeningBalance = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName,
element);
baseDataValidator.reset().parameter(minRequiredOpeningBalanceParamName).value(minOpeningBalance).ignoreIfNull()
.zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
final Integer lockinPeriodFrequency = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).ignoreIfNull()
.integerZeroOrGreater();
}
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
final Integer lockinPeriodFrequencyType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName, element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(0, 3);
}
if (this.fromApiJsonHelper.parameterExists(withdrawalFeeForTransfersParamName, element)) {
final Boolean isWithdrawalFeeApplicableForTransfers = this.fromApiJsonHelper
.extractBooleanNamed(withdrawalFeeForTransfersParamName, element);
baseDataValidator.reset().parameter(withdrawalFeeForTransfersParamName).value(isWithdrawalFeeApplicableForTransfers)
.ignoreIfNull().validateForBooleanValue();
}
if (this.fromApiJsonHelper.parameterExists(withHoldTaxParamName, element)) {
final String withHoldTax = this.fromApiJsonHelper.extractStringNamed(withHoldTaxParamName, element);
baseDataValidator.reset().parameter(withHoldTaxParamName).value(withHoldTax).ignoreIfNull().validateForBooleanValue();
}
validateOverdraftParams(baseDataValidator, element);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
}
private void validateLienParams(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
if (this.fromApiJsonHelper.parameterExists(lienAllowedParamName, element)) {
final Boolean lienAllowed = this.fromApiJsonHelper.extractBooleanNamed(lienAllowedParamName, element);
baseDataValidator.reset().parameter(lienAllowedParamName).value(lienAllowed).ignoreIfNull().validateForBooleanValue();
}
if (BooleanUtils.isTrue(this.fromApiJsonHelper.extractBooleanNamed(lienAllowedParamName, element))) {
final BigDecimal maxAllowedLienLimit = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(maxAllowedLienLimitParamName,
element);
baseDataValidator.reset().parameter(maxAllowedLienLimitParamName).value(maxAllowedLienLimit).ignoreIfNull()
.zeroOrPositiveAmount();
}
if (BooleanUtils.isTrue(this.fromApiJsonHelper.extractBooleanNamed(lienAllowedParamName, element))
&& BooleanUtils.isTrue(this.fromApiJsonHelper.extractBooleanNamed(allowOverdraftParamName, element))) {
final BigDecimal maxAllowedLienLimit = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(maxAllowedLienLimitParamName,
element);
final BigDecimal overdraftLimit = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(overdraftLimitParamName, element);
if (overdraftLimit.compareTo(maxAllowedLienLimit) > 0) {
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("Overdraft.limit.can.not.be.greater.than.lien.limit");
}
}
}
private void validateOverdraftParams(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
if (this.fromApiJsonHelper.parameterExists(allowOverdraftParamName, element)) {
final Boolean allowOverdraft = this.fromApiJsonHelper.extractBooleanNamed(allowOverdraftParamName, element);
baseDataValidator.reset().parameter(allowOverdraftParamName).value(allowOverdraft).ignoreIfNull().validateForBooleanValue();
}
if (this.fromApiJsonHelper.parameterExists(overdraftLimitParamName, element)) {
final BigDecimal overdraftLimit = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(overdraftLimitParamName, element);
baseDataValidator.reset().parameter(overdraftLimitParamName).value(overdraftLimit).ignoreIfNull().zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(nominalAnnualInterestRateOverdraftParamName, element)) {
final BigDecimal nominalAnnualInterestRateOverdraft = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateOverdraftParamName, element);
baseDataValidator.reset().parameter(nominalAnnualInterestRateOverdraftParamName).value(nominalAnnualInterestRateOverdraft)
.ignoreIfNull().zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(minOverdraftForInterestCalculationParamName, element)) {
final BigDecimal minOverdraftForInterestCalculation = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(minOverdraftForInterestCalculationParamName, element);
baseDataValidator.reset().parameter(minOverdraftForInterestCalculationParamName).value(minOverdraftForInterestCalculation)
.ignoreIfNull().zeroOrPositiveAmount();
}
}
public void validateForAssignSavingsOfficer(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Set<String> supportedParameters = new HashSet<>(
Arrays.asList("fromSavingsOfficerId", "toSavingsOfficerId", "assignmentDate", "locale", "dateFormat"));
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final Long toSavingsOfficerId = this.fromApiJsonHelper.extractLongNamed("toSavingsOfficerId", element);
baseDataValidator.reset().parameter("toSavingsOfficerId").value(toSavingsOfficerId).notNull().integerGreaterThanZero();
final String assignmentDateStr = this.fromApiJsonHelper.extractStringNamed("assignmentDate", element);
baseDataValidator.reset().parameter("assignmentDate").value(assignmentDateStr).notBlank();
if (!StringUtils.isBlank(assignmentDateStr)) {
final LocalDate assignmentDate = this.fromApiJsonHelper.extractLocalDateNamed("assignmentDate", element);
baseDataValidator.reset().parameter("assignmentDate").value(assignmentDate).notNull();
}
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
public void validateForUnAssignSavingsOfficer(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Set<String> supportedParameters = new HashSet<>(Arrays.asList("unassignedDate", "locale", "dateFormat"));
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final String unassignedDateStr = this.fromApiJsonHelper.extractStringNamed("unassignedDate", element);
baseDataValidator.reset().parameter("unassignedDate").value(unassignedDateStr).notBlank();
if (!StringUtils.isBlank(unassignedDateStr)) {
final LocalDate unassignedDate = this.fromApiJsonHelper.extractLocalDateNamed("unassignedDate", element);
baseDataValidator.reset().parameter("unassignedDate").value(unassignedDate).notNull();
}
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
}
}
}
@@ -1,78 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
public class SavingsAccountTransactionDTO {
private final DateTimeFormatter formatter;
private final LocalDate transactionDate;
private final BigDecimal transactionAmount;
private final PaymentDetail paymentDetail;
private final Long savingsAccountId;
private final Integer depositAccountType;
/**
* This constructor is used for bulk deposit transactions
*
* @param formatter
* @param transactionDate
* @param transactionAmount
* @param paymentDetail
* @param savingsAccountId
*/
public SavingsAccountTransactionDTO(DateTimeFormatter formatter, LocalDate transactionDate, BigDecimal transactionAmount,
PaymentDetail paymentDetail, Long savingsAccountId, final Integer depositAccountType) {
this.formatter = formatter;
this.transactionDate = transactionDate;
this.transactionAmount = transactionAmount;
this.paymentDetail = paymentDetail;
this.savingsAccountId = savingsAccountId;
this.depositAccountType = depositAccountType;
}
public DateTimeFormatter getFormatter() {
return this.formatter;
}
public LocalDate getTransactionDate() {
return this.transactionDate;
}
public BigDecimal getTransactionAmount() {
return this.transactionAmount;
}
public PaymentDetail getPaymentDetail() {
return this.paymentDetail;
}
public Long getSavingsAccountId() {
return this.savingsAccountId;
}
public Integer getAccountType() {
return this.depositAccountType;
}
}
@@ -1,59 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.time.LocalDate;
public final class SavingsActivation {
private final transient Integer rowIndex;
private final LocalDate activatedOnDate;
private final String dateFormat;
private final String locale;
public static SavingsActivation importInstance(LocalDate activatedOnDate, Integer rowIndex, String locale, String dateFormat) {
return new SavingsActivation(activatedOnDate, rowIndex, locale, dateFormat);
}
private SavingsActivation(LocalDate activatedOnDate, Integer rowIndex, String locale, String dateFormat) {
this.activatedOnDate = activatedOnDate;
this.rowIndex = rowIndex;
this.dateFormat = dateFormat;
this.locale = locale;
}
public LocalDate getActivatedOnDate() {
return activatedOnDate;
}
public String getLocale() {
return locale;
}
public String getDateFormat() {
return dateFormat;
}
public Integer getRowIndex() {
return rowIndex;
}
}
@@ -1,66 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.time.LocalDate;
public final class SavingsApproval {
private final transient Integer rowIndex;
private final LocalDate approvedOnDate;
private final String dateFormat;
private final String locale;
private final String note;
public static SavingsApproval importInstance(LocalDate approvedOnDate, Integer rowIndex, String locale, String dateFormat) {
return new SavingsApproval(approvedOnDate, rowIndex, locale, dateFormat);
}
private SavingsApproval(LocalDate approvedOnDate, Integer rowIndex, String locale, String dateFormat) {
this.approvedOnDate = approvedOnDate;
this.rowIndex = rowIndex;
this.dateFormat = dateFormat;
this.locale = locale;
this.note = "";
}
public LocalDate getApprovedOnDate() {
return approvedOnDate;
}
public String getLocale() {
return locale;
}
public String getDateFormat() {
return dateFormat;
}
public Integer getRowIndex() {
return rowIndex;
}
public String getNote() {
return note;
}
}
@@ -1,704 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_PRODUCT_RESOURCE_NAME;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.allowOverdraftParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.currencyCodeParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToDormancyParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToEscheatParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToInactiveParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.descriptionParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.digitsAfterDecimalParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.feeAmountParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.feeOnMonthDayParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.inMultiplesOfParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculationDaysInYearTypeParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculationTypeParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCompoundingPeriodTypeParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestPostingPeriodTypeParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.isDormancyTrackingActiveParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lienAllowedParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.maxAllowedLienLimitParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minBalanceForInterestCalculationParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minOverdraftForInterestCalculationParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.minRequiredOpeningBalanceParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nameParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateOverdraftParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.overdraftLimitParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.shortNameParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.taxGroupIdParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName;
import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.time.MonthDay;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.accounting.common.AccountingConstants.SavingProductAccountingParams;
import org.apache.fineract.accounting.common.AccountingRuleType;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.savings.SavingsApiConstants;
import org.apache.fineract.portfolio.savings.SavingsCompoundingInterestPeriodType;
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationDaysInYearType;
import org.apache.fineract.portfolio.savings.SavingsInterestCalculationType;
import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
import org.apache.fineract.portfolio.savings.domain.SavingsProduct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class SavingsProductDataValidator {
private final FromJsonHelper fromApiJsonHelper;
private static final Set<String> SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(
SavingsApiConstants.localeParamName, SavingsApiConstants.monthDayFormatParamName, nameParamName, shortNameParamName,
descriptionParamName, currencyCodeParamName, digitsAfterDecimalParamName, inMultiplesOfParamName,
nominalAnnualInterestRateParamName, interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName,
interestCalculationTypeParamName, interestCalculationDaysInYearTypeParamName, minRequiredOpeningBalanceParamName,
lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName, SavingsApiConstants.withdrawalFeeAmountParamName,
SavingsApiConstants.withdrawalFeeTypeParamName, withdrawalFeeForTransfersParamName, feeAmountParamName, feeOnMonthDayParamName,
SavingsApiConstants.accountingRuleParamName, SavingsApiConstants.chargesParamName,
SavingProductAccountingParams.INCOME_FROM_FEES.getValue(), SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(),
SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(),
SavingProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(),
SavingProductAccountingParams.SAVINGS_CONTROL.getValue(), SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(),
SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), SavingProductAccountingParams.FEE_INCOME_ACCOUNT_MAPPING.getValue(),
SavingProductAccountingParams.PENALTY_INCOME_ACCOUNT_MAPPING.getValue(),
SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(),
SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(),
SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue(), isDormancyTrackingActiveParamName, daysToDormancyParamName,
daysToInactiveParamName, daysToEscheatParamName, allowOverdraftParamName, overdraftLimitParamName,
nominalAnnualInterestRateOverdraftParamName, minOverdraftForInterestCalculationParamName,
SavingsApiConstants.minRequiredBalanceParamName, SavingsApiConstants.enforceMinRequiredBalanceParamName,
SavingsApiConstants.maxAllowedLienLimitParamName, SavingsApiConstants.lienAllowedParamName,
minBalanceForInterestCalculationParamName, withHoldTaxParamName, taxGroupIdParamName));
@Autowired
public SavingsProductDataValidator(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public void validateForCreate(final String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(SAVINGS_PRODUCT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final String name = this.fromApiJsonHelper.extractStringNamed(nameParamName, element);
baseDataValidator.reset().parameter(nameParamName).value(name).notBlank().notExceedingLengthOf(100);
final String shortName = this.fromApiJsonHelper.extractStringNamed(shortNameParamName, element);
baseDataValidator.reset().parameter(shortNameParamName).value(shortName).notBlank().notExceedingLengthOf(4);
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(currencyCodeParamName, element);
baseDataValidator.reset().parameter(currencyCodeParamName).value(currencyCode).notBlank();
final Integer digitsAfterDecimal = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(digitsAfterDecimalParamName, element);
baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
if (this.fromApiJsonHelper.parameterExists(inMultiplesOfParamName, element)) {
final Integer inMultiplesOf = this.fromApiJsonHelper.extractIntegerNamed(inMultiplesOfParamName, element, Locale.getDefault());
baseDataValidator.reset().parameter(inMultiplesOfParamName).value(inMultiplesOf).ignoreIfNull().integerZeroOrGreater();
}
final BigDecimal nominalAnnualInterestRate = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName, element);
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(nominalAnnualInterestRate).notNull()
.zeroOrPositiveAmount();
final Integer interestCompoundingPeriodType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestCompoundingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
.isOneOfTheseValues(SavingsCompoundingInterestPeriodType.integerValues());
final Integer interestPostingPeriodType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestPostingPeriodTypeParamName,
element);
baseDataValidator.reset().parameter(interestPostingPeriodTypeParamName).value(interestPostingPeriodType).notNull()
.isOneOfTheseValues(SavingsPostingInterestPeriodType.integerValues());
final Integer interestCalculationType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName,
element);
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull()
.isOneOfTheseValues(SavingsInterestCalculationType.integerValues());
final Integer interestCalculationDaysInYearType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestCalculationDaysInYearTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType).notNull()
.isOneOfTheseValues(SavingsInterestCalculationDaysInYearType.integerValues());
if (this.fromApiJsonHelper.parameterExists(descriptionParamName, element)) {
final String description = this.fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
baseDataValidator.reset().parameter(descriptionParamName).value(description).ignoreIfNull().notExceedingLengthOf(500);
}
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
final BigDecimal minOpeningBalance = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName,
element);
baseDataValidator.reset().parameter(minRequiredOpeningBalanceParamName).value(minOpeningBalance).zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
final Integer lockinPeriodFrequency = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).integerZeroOrGreater();
if (lockinPeriodFrequency != null) {
final Integer lockinPeriodFrequencyType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName, element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).notNull()
.inMinMaxRange(0, 3);
}
}
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
final Integer lockinPeriodFrequencyType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName, element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(0, 3);
if (lockinPeriodFrequencyType != null) {
final Integer lockinPeriodFrequency = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).notNull()
.integerZeroOrGreater();
}
}
/*
* if (this.fromApiJsonHelper.parameterExists(withdrawalFeeAmountParamName, element)) {
*
* final BigDecimal withdrawalFeeAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed
* (withdrawalFeeAmountParamName, element); baseDataValidator.reset().parameter
* (withdrawalFeeAmountParamName).value (withdrawalFeeAmount).zeroOrPositiveAmount();
*
* if (withdrawalFeeAmount != null) { final Integer withdrawalFeeType =
* this.fromApiJsonHelper.extractIntegerSansLocaleNamed( withdrawalFeeTypeParamName, element);
* baseDataValidator.reset().parameter (withdrawalFeeTypeParamName).value(withdrawalFeeType)
* .isOneOfTheseValues(SavingsWithdrawalFeesType.integerValues()); } }
*
* if (this.fromApiJsonHelper.parameterExists(withdrawalFeeTypeParamName, element)) { final Integer
* withdrawalFeeType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed (withdrawalFeeTypeParamName,
* element); baseDataValidator.reset().parameter
* (withdrawalFeeTypeParamName).value(withdrawalFeeType).ignoreIfNull() .isOneOfTheseValues(1, 2);
*
* if (withdrawalFeeType != null) { final BigDecimal withdrawalFeeAmount =
* this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed( withdrawalFeeAmountParamName, element);
* baseDataValidator.reset().parameter (withdrawalFeeAmountParamName).value(withdrawalFeeAmount).notNull()
* .zeroOrPositiveAmount(); } }
*/
if (this.fromApiJsonHelper.parameterExists(withdrawalFeeForTransfersParamName, element)) {
final Boolean isWithdrawalFeeApplicableForTransfers = this.fromApiJsonHelper
.extractBooleanNamed(withdrawalFeeForTransfersParamName, element);
baseDataValidator.reset().parameter(withdrawalFeeForTransfersParamName).value(isWithdrawalFeeApplicableForTransfers)
.ignoreIfNull().validateForBooleanValue();
}
if (this.fromApiJsonHelper.parameterExists(feeAmountParamName, element)) {
final BigDecimal annualFeeAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(feeAmountParamName, element);
baseDataValidator.reset().parameter(feeAmountParamName).value(annualFeeAmount).zeroOrPositiveAmount();
if (annualFeeAmount != null) {
final MonthDay monthDayOfAnnualFee = this.fromApiJsonHelper.extractMonthDayNamed(feeOnMonthDayParamName, element);
baseDataValidator.reset().parameter(feeOnMonthDayParamName).value(monthDayOfAnnualFee).notNull();
}
}
if (this.fromApiJsonHelper.parameterExists(feeOnMonthDayParamName, element)) {
final MonthDay monthDayOfAnnualFee = this.fromApiJsonHelper.extractMonthDayNamed(feeOnMonthDayParamName, element);
if (monthDayOfAnnualFee != null) {
final BigDecimal annualFeeAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(feeAmountParamName, element);
baseDataValidator.reset().parameter(feeAmountParamName).value(annualFeeAmount).notNull().zeroOrPositiveAmount();
}
}
// dormancy
final Boolean isDormancyActive = this.fromApiJsonHelper.extractBooleanNamed(isDormancyTrackingActiveParamName, element);
if (null != isDormancyActive && isDormancyActive) {
final Long daysToInact = this.fromApiJsonHelper.extractLongNamed(daysToInactiveParamName, element);
baseDataValidator.reset().parameter(daysToInactiveParamName).value(daysToInact).notNull().longGreaterThanZero();
final Long daysToDor = this.fromApiJsonHelper.extractLongNamed(daysToDormancyParamName, element);
baseDataValidator.reset().parameter(daysToDormancyParamName).value(daysToDor).notNull().longGreaterThanZero();
final Long daysToEsc = this.fromApiJsonHelper.extractLongNamed(daysToEscheatParamName, element);
baseDataValidator.reset().parameter(daysToEscheatParamName).value(daysToEsc).notNull().longGreaterThanZero();
if (null != daysToInact && null != daysToDor && null != daysToEsc) {
baseDataValidator.reset().parameter(daysToDormancyParamName).value(daysToDor).longGreaterThanNumber(daysToInact);
baseDataValidator.reset().parameter(daysToEscheatParamName).value(daysToEsc).longGreaterThanNumber(daysToDor);
}
}
// accounting related data validation
final Integer accountingRuleType = this.fromApiJsonHelper.extractIntegerNamed("accountingRule", element, Locale.getDefault());
baseDataValidator.reset().parameter("accountingRule").value(accountingRuleType).notNull().inMinMaxRange(1, 3);
if (isCashBasedAccounting(accountingRuleType)) {
final Long savingsControlAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.SAVINGS_CONTROL.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_CONTROL.getValue()).value(savingsControlAccountId)
.notNull().integerGreaterThanZero();
final Long savingsReferenceAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue()).value(savingsReferenceAccountId)
.notNull().integerGreaterThanZero();
final Long transfersInSuspenseAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue())
.value(transfersInSuspenseAccountId).notNull().integerGreaterThanZero();
final Long interestOnSavingsAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue())
.value(interestOnSavingsAccountId).notNull().integerGreaterThanZero();
final Long incomeFromFeeId = this.fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_FEES.getValue(),
element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId).notNull()
.integerGreaterThanZero();
final Long incomeFromPenaltyId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue()).value(incomeFromPenaltyId)
.notNull().integerGreaterThanZero();
final Long overdraftControlAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue())
.value(overdraftControlAccountId).notNull().integerGreaterThanZero();
final Long incomeFromInterest = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue()).value(incomeFromInterest)
.notNull().integerGreaterThanZero();
final Long writtenoff = this.fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(),
element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue()).value(writtenoff).notNull()
.integerGreaterThanZero();
if (null != isDormancyActive && isDormancyActive) {
final Long escheatLiabilityAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue())
.value(escheatLiabilityAccountId).notNull().integerGreaterThanZero();
}
validatePaymentChannelFundSourceMappings(baseDataValidator, element);
validateChargeToIncomeAccountMappings(baseDataValidator, element);
}
validateOverdraftParams(baseDataValidator, element);
if (this.fromApiJsonHelper.parameterExists(minBalanceForInterestCalculationParamName, element)) {
final BigDecimal minBalanceForInterestCalculation = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(minBalanceForInterestCalculationParamName, element);
baseDataValidator.reset().parameter(minBalanceForInterestCalculationParamName).value(minBalanceForInterestCalculation)
.ignoreIfNull().zeroOrPositiveAmount();
}
validateTaxWithHoldingParams(baseDataValidator, element, true);
validateLienParams(baseDataValidator, element);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateForUpdate(final String json, final SavingsProduct product) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, SAVINGS_PRODUCT_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
.resource(SAVINGS_PRODUCT_RESOURCE_NAME);
final JsonElement element = this.fromApiJsonHelper.parse(json);
if (this.fromApiJsonHelper.parameterExists(nameParamName, element)) {
final String name = this.fromApiJsonHelper.extractStringNamed(nameParamName, element);
baseDataValidator.reset().parameter(nameParamName).value(name).notBlank().notExceedingLengthOf(100);
}
if (this.fromApiJsonHelper.parameterExists(shortNameParamName, element)) {
final String shortName = this.fromApiJsonHelper.extractStringNamed(shortNameParamName, element);
baseDataValidator.reset().parameter(shortNameParamName).value(shortName).notBlank().notExceedingLengthOf(4);
}
if (this.fromApiJsonHelper.parameterExists(descriptionParamName, element)) {
final String description = this.fromApiJsonHelper.extractStringNamed(descriptionParamName, element);
baseDataValidator.reset().parameter(descriptionParamName).value(description).notBlank().notExceedingLengthOf(500);
}
if (this.fromApiJsonHelper.parameterExists(currencyCodeParamName, element)) {
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(currencyCodeParamName, element);
baseDataValidator.reset().parameter(currencyCodeParamName).value(currencyCode).notBlank();
}
if (this.fromApiJsonHelper.parameterExists(digitsAfterDecimalParamName, element)) {
final Integer digitsAfterDecimal = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(digitsAfterDecimalParamName, element);
baseDataValidator.reset().parameter(digitsAfterDecimalParamName).value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6);
}
if (this.fromApiJsonHelper.parameterExists(inMultiplesOfParamName, element)) {
final Integer inMultiplesOf = this.fromApiJsonHelper.extractIntegerNamed(inMultiplesOfParamName, element, Locale.getDefault());
baseDataValidator.reset().parameter(inMultiplesOfParamName).value(inMultiplesOf).ignoreIfNull().integerZeroOrGreater();
}
if (this.fromApiJsonHelper.parameterExists(nominalAnnualInterestRateParamName, element)) {
final BigDecimal interestRate = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateParamName,
element);
baseDataValidator.reset().parameter(nominalAnnualInterestRateParamName).value(interestRate).notNull().zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(interestCompoundingPeriodTypeParamName, element)) {
final Integer interestCompoundingPeriodType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestCompoundingPeriodTypeParamName, element);
baseDataValidator.reset().parameter(interestCompoundingPeriodTypeParamName).value(interestCompoundingPeriodType).notNull()
.isOneOfTheseValues(SavingsCompoundingInterestPeriodType.integerValues());
}
if (this.fromApiJsonHelper.parameterExists(interestCalculationTypeParamName, element)) {
final Integer interestCalculationType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(interestCalculationTypeParamName,
element);
baseDataValidator.reset().parameter(interestCalculationTypeParamName).value(interestCalculationType).notNull().inMinMaxRange(1,
2);
}
if (this.fromApiJsonHelper.parameterExists(interestCalculationDaysInYearTypeParamName, element)) {
final Integer interestCalculationDaysInYearType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(interestCalculationDaysInYearTypeParamName, element);
baseDataValidator.reset().parameter(interestCalculationDaysInYearTypeParamName).value(interestCalculationDaysInYearType)
.notNull().isOneOfTheseValues(360, 365);
}
if (this.fromApiJsonHelper.parameterExists(minRequiredOpeningBalanceParamName, element)) {
final BigDecimal minOpeningBalance = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(minRequiredOpeningBalanceParamName,
element);
baseDataValidator.reset().parameter(minRequiredOpeningBalanceParamName).value(minOpeningBalance).ignoreIfNull()
.zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyParamName, element)) {
final Integer lockinPeriodFrequency = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(lockinPeriodFrequencyParamName,
element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(lockinPeriodFrequency).ignoreIfNull()
.integerZeroOrGreater();
}
if (this.fromApiJsonHelper.parameterExists(lockinPeriodFrequencyTypeParamName, element)) {
final Integer lockinPeriodFrequencyType = this.fromApiJsonHelper
.extractIntegerSansLocaleNamed(lockinPeriodFrequencyTypeParamName, element);
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(lockinPeriodFrequencyType).inMinMaxRange(0, 3);
}
if (this.fromApiJsonHelper.parameterExists(withdrawalFeeForTransfersParamName, element)) {
final Boolean isWithdrawalFeeApplicableForTransfers = this.fromApiJsonHelper
.extractBooleanNamed(withdrawalFeeForTransfersParamName, element);
baseDataValidator.reset().parameter(withdrawalFeeForTransfersParamName).value(isWithdrawalFeeApplicableForTransfers)
.ignoreIfNull().validateForBooleanValue();
}
if (this.fromApiJsonHelper.parameterExists(feeAmountParamName, element)) {
final BigDecimal annualFeeAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(feeAmountParamName, element);
baseDataValidator.reset().parameter(feeAmountParamName).value(annualFeeAmount).ignoreIfNull().zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(feeOnMonthDayParamName, element)) {
final MonthDay monthDayOfAnnualFee = this.fromApiJsonHelper.extractMonthDayNamed(feeOnMonthDayParamName, element);
baseDataValidator.reset().parameter(feeOnMonthDayParamName).value(monthDayOfAnnualFee).ignoreIfNull();
}
final Long savingsControlAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.SAVINGS_CONTROL.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_CONTROL.getValue()).value(savingsControlAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long savingsReferenceAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.SAVINGS_REFERENCE.getValue()).value(savingsReferenceAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long transfersInSuspenseAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.TRANSFERS_SUSPENSE.getValue()).value(transfersInSuspenseAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long interestOnSavingsAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.INTEREST_ON_SAVINGS.getValue()).value(interestOnSavingsAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long incomeFromFeeId = this.fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_FEES.getValue(),
element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_FEES.getValue()).value(incomeFromFeeId).ignoreIfNull()
.integerGreaterThanZero();
final Long incomeFromPenaltyId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_PENALTIES.getValue()).value(incomeFromPenaltyId)
.ignoreIfNull().integerGreaterThanZero();
final Long overdraftAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.OVERDRAFT_PORTFOLIO_CONTROL.getValue()).value(overdraftAccountId)
.ignoreIfNull().integerGreaterThanZero();
final Long incomeFromInterest = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.INCOME_FROM_INTEREST.getValue()).value(incomeFromInterest)
.ignoreIfNull().integerGreaterThanZero();
final Long writtenoff = this.fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(),
element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.LOSSES_WRITTEN_OFF.getValue()).value(writtenoff).ignoreIfNull()
.integerGreaterThanZero();
// dormancy
final Boolean isDormancyActive = this.fromApiJsonHelper.parameterExists(isDormancyTrackingActiveParamName, element)
? this.fromApiJsonHelper.extractBooleanNamed(isDormancyTrackingActiveParamName, element)
: product.isDormancyTrackingActive();
if (null != isDormancyActive && isDormancyActive) {
final Long daysToInact = this.fromApiJsonHelper.parameterExists(daysToInactiveParamName, element)
? this.fromApiJsonHelper.extractLongNamed(daysToInactiveParamName, element)
: product.getDaysToInactive();
baseDataValidator.reset().parameter(daysToInactiveParamName).value(daysToInact).notNull().longGreaterThanZero();
final Long daysToDor = this.fromApiJsonHelper.parameterExists(daysToDormancyParamName, element)
? this.fromApiJsonHelper.extractLongNamed(daysToDormancyParamName, element)
: product.getDaysToDormancy();
baseDataValidator.reset().parameter(daysToDormancyParamName).value(daysToDor).notNull().longGreaterThanZero();
final Long daysToEsc = this.fromApiJsonHelper.parameterExists(daysToEscheatParamName, element)
? this.fromApiJsonHelper.extractLongNamed(daysToEscheatParamName, element)
: product.getDaysToEscheat();
baseDataValidator.reset().parameter(daysToEscheatParamName).value(daysToEsc).notNull().longGreaterThanZero();
if (null != daysToInact && null != daysToDor && null != daysToEsc) {
baseDataValidator.reset().parameter(daysToDormancyParamName).value(daysToDor).longGreaterThanNumber(daysToInact);
baseDataValidator.reset().parameter(daysToEscheatParamName).value(daysToEsc).longGreaterThanNumber(daysToDor);
}
if (this.fromApiJsonHelper.parameterExists(SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue(), element)) {
final Long escheatLiabilityAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue(), element);
baseDataValidator.reset().parameter(SavingProductAccountingParams.ESCHEAT_LIABILITY.getValue())
.value(escheatLiabilityAccountId).notNull().integerGreaterThanZero();
}
}
validatePaymentChannelFundSourceMappings(baseDataValidator, element);
validateChargeToIncomeAccountMappings(baseDataValidator, element);
validateOverdraftParams(baseDataValidator, element);
if (this.fromApiJsonHelper.parameterExists(minBalanceForInterestCalculationParamName, element)) {
final BigDecimal minBalanceForInterestCalculation = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(minBalanceForInterestCalculationParamName, element);
baseDataValidator.reset().parameter(minBalanceForInterestCalculationParamName).value(minBalanceForInterestCalculation)
.ignoreIfNull().zeroOrPositiveAmount();
}
validateTaxWithHoldingParams(baseDataValidator, element, false);
validateLienParams(baseDataValidator, element);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
}
private boolean isCashBasedAccounting(final Integer accountingRuleType) {
return AccountingRuleType.CASH_BASED.getValue().equals(accountingRuleType);
}
/**
* Validation for advanced accounting options
*/
private void validatePaymentChannelFundSourceMappings(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
if (this.fromApiJsonHelper.parameterExists(SavingProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element)) {
final JsonArray paymentChannelMappingArray = this.fromApiJsonHelper
.extractJsonArrayNamed(SavingProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue(), element);
if (paymentChannelMappingArray != null && paymentChannelMappingArray.size() > 0) {
int i = 0;
do {
final JsonObject jsonObject = paymentChannelMappingArray.get(i).getAsJsonObject();
final Long paymentTypeId = jsonObject.get(SavingProductAccountingParams.PAYMENT_TYPE.getValue()).getAsLong();
final Long paymentSpecificFundAccountId = jsonObject.get(SavingProductAccountingParams.FUND_SOURCE.getValue())
.getAsLong();
baseDataValidator.reset()
.parameter(SavingProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue() + "[" + i + "]."
+ SavingProductAccountingParams.PAYMENT_TYPE.toString())
.value(paymentTypeId).notNull().integerGreaterThanZero();
baseDataValidator.reset()
.parameter(SavingProductAccountingParams.PAYMENT_CHANNEL_FUND_SOURCE_MAPPING.getValue() + "[" + i + "]."
+ SavingProductAccountingParams.FUND_SOURCE.getValue())
.value(paymentSpecificFundAccountId).notNull().integerGreaterThanZero();
i++;
} while (i < paymentChannelMappingArray.size());
}
}
}
private void validateChargeToIncomeAccountMappings(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
// validate for both fee and penalty charges
validateChargeToIncomeAccountMappings(baseDataValidator, element, true);
validateChargeToIncomeAccountMappings(baseDataValidator, element, true);
}
private void validateChargeToIncomeAccountMappings(final DataValidatorBuilder baseDataValidator, final JsonElement element,
final boolean isPenalty) {
String parameterName;
if (isPenalty) {
parameterName = SavingProductAccountingParams.PENALTY_INCOME_ACCOUNT_MAPPING.getValue();
} else {
parameterName = SavingProductAccountingParams.FEE_INCOME_ACCOUNT_MAPPING.getValue();
}
if (this.fromApiJsonHelper.parameterExists(parameterName, element)) {
final JsonArray chargeToIncomeAccountMappingArray = this.fromApiJsonHelper.extractJsonArrayNamed(parameterName, element);
if (chargeToIncomeAccountMappingArray != null && chargeToIncomeAccountMappingArray.size() > 0) {
int i = 0;
do {
final JsonObject jsonObject = chargeToIncomeAccountMappingArray.get(i).getAsJsonObject();
final Long chargeId = this.fromApiJsonHelper.extractLongNamed(SavingProductAccountingParams.CHARGE_ID.getValue(),
jsonObject);
final Long incomeAccountId = this.fromApiJsonHelper
.extractLongNamed(SavingProductAccountingParams.INCOME_ACCOUNT_ID.getValue(), jsonObject);
baseDataValidator.reset().parameter(parameterName + "[" + i + "]." + SavingProductAccountingParams.CHARGE_ID.getValue())
.value(chargeId).notNull().integerGreaterThanZero();
baseDataValidator.reset()
.parameter(parameterName + "[" + i + "]." + SavingProductAccountingParams.INCOME_ACCOUNT_ID.getValue())
.value(incomeAccountId).notNull().integerGreaterThanZero();
i++;
} while (i < chargeToIncomeAccountMappingArray.size());
}
}
}
private void validateOverdraftParams(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
if (this.fromApiJsonHelper.parameterExists(allowOverdraftParamName, element)) {
final Boolean allowOverdraft = this.fromApiJsonHelper.extractBooleanNamed(allowOverdraftParamName, element);
baseDataValidator.reset().parameter(allowOverdraftParamName).value(allowOverdraft).ignoreIfNull().validateForBooleanValue();
}
if (this.fromApiJsonHelper.parameterExists(overdraftLimitParamName, element)) {
final BigDecimal overdraftLimit = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(overdraftLimitParamName, element);
baseDataValidator.reset().parameter(overdraftLimitParamName).value(overdraftLimit).ignoreIfNull().zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(nominalAnnualInterestRateOverdraftParamName, element)) {
final BigDecimal nominalAnnualInterestRateOverdraft = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(nominalAnnualInterestRateOverdraftParamName, element);
baseDataValidator.reset().parameter(nominalAnnualInterestRateOverdraftParamName).value(nominalAnnualInterestRateOverdraft)
.ignoreIfNull().zeroOrPositiveAmount();
}
if (this.fromApiJsonHelper.parameterExists(minOverdraftForInterestCalculationParamName, element)) {
final BigDecimal minOverdraftForInterestCalculation = this.fromApiJsonHelper
.extractBigDecimalWithLocaleNamed(minOverdraftForInterestCalculationParamName, element);
baseDataValidator.reset().parameter(minOverdraftForInterestCalculationParamName).value(minOverdraftForInterestCalculation)
.ignoreIfNull().zeroOrPositiveAmount();
}
}
private void validateLienParams(final DataValidatorBuilder baseDataValidator, final JsonElement element) {
if (this.fromApiJsonHelper.parameterExists(lienAllowedParamName, element)) {
final Boolean lienAllowed = this.fromApiJsonHelper.extractBooleanNamed(lienAllowedParamName, element);
baseDataValidator.reset().parameter(lienAllowedParamName).value(lienAllowed).ignoreIfNull().validateForBooleanValue();
}
if (this.fromApiJsonHelper.parameterExists(maxAllowedLienLimitParamName, element)) {
final BigDecimal maxAllowedLienLimit = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(maxAllowedLienLimitParamName,
element);
baseDataValidator.reset().parameter(maxAllowedLienLimitParamName).value(maxAllowedLienLimit).ignoreIfNull()
.zeroOrPositiveAmount();
}
if (BooleanUtils.isTrue(this.fromApiJsonHelper.extractBooleanNamed(lienAllowedParamName, element))
&& BooleanUtils.isTrue(this.fromApiJsonHelper.extractBooleanNamed(allowOverdraftParamName, element))) {
final BigDecimal maxAllowedLienLimit = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(maxAllowedLienLimitParamName,
element);
final BigDecimal overdraftLimit = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(overdraftLimitParamName, element);
if (overdraftLimit.compareTo(maxAllowedLienLimit) > 0) {
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("Overdraft.limit.can.not.be.greater.than.lien.limit");
}
}
}
private void validateTaxWithHoldingParams(final DataValidatorBuilder baseDataValidator, final JsonElement element,
final boolean isCreate) {
if (this.fromApiJsonHelper.parameterExists(withHoldTaxParamName, element)) {
final String withHoldTax = this.fromApiJsonHelper.extractStringNamed(withHoldTaxParamName, element);
baseDataValidator.reset().parameter(withHoldTaxParamName).value(withHoldTax).ignoreIfNull().validateForBooleanValue();
}
Boolean withHoldTax = this.fromApiJsonHelper.extractBooleanNamed(withHoldTaxParamName, element);
if (withHoldTax == null) {
withHoldTax = false;
}
if (this.fromApiJsonHelper.parameterExists(taxGroupIdParamName, element)) {
final Long taxGroupId = this.fromApiJsonHelper.extractLongNamed(taxGroupIdParamName, element);
baseDataValidator.reset().parameter(taxGroupIdParamName).value(taxGroupId).ignoreIfNull().longGreaterThanZero();
if (withHoldTax) {
baseDataValidator.reset().parameter(taxGroupIdParamName).value(taxGroupId).notBlank();
}
} else if (withHoldTax && isCreate) {
final Long taxGroupId = null;
baseDataValidator.reset().parameter(taxGroupIdParamName).value(taxGroupId).notBlank();
}
}
}
@@ -1,34 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.data;
import java.time.LocalDate;
/**
* Immutable data object representing date
*/
@SuppressWarnings("unused")
public class TransactionDateData {
private final LocalDate date;
public TransactionDateData(final LocalDate date) {
this.date = date;
}
}
@@ -1,50 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.domain;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.portfolio.interestratechart.domain.InterestIncentivesFields;
@Entity
@Table(name = "m_deposit_account_interest_incentives")
public class DepositAccountInterestIncentive extends AbstractPersistableCustom {
@ManyToOne
@JoinColumn(name = "deposit_account_interest_rate_slab_id", nullable = false)
private DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs;
@Embedded
private InterestIncentivesFields interestIncentivesFields;
protected DepositAccountInterestIncentive() {
// TODO Auto-generated constructor stub
}
public DepositAccountInterestIncentive(final DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs,
final InterestIncentivesFields interestIncentivesFields) {
this.depositAccountInterestRateChartSlabs = depositAccountInterestRateChartSlabs;
this.interestIncentivesFields = interestIncentivesFields;
}
}
@@ -1,63 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.domain;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.portfolio.interestratechart.domain.InterestIncentivesFields;
@Entity
@Table(name = "m_savings_interest_incentives")
public class DepositAccountInterestIncentives extends AbstractPersistableCustom {
@ManyToOne
@JoinColumn(name = "deposit_account_interest_rate_slab_id", nullable = false)
private DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs;
@Embedded
private InterestIncentivesFields interestIncentivesFields;
protected DepositAccountInterestIncentives() {
}
private DepositAccountInterestIncentives(final DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs,
final InterestIncentivesFields interestIncentivesFields) {
this.depositAccountInterestRateChartSlabs = depositAccountInterestRateChartSlabs;
this.interestIncentivesFields = interestIncentivesFields;
}
public static DepositAccountInterestIncentives from(final DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs,
final InterestIncentivesFields interestIncentivesFields) {
return new DepositAccountInterestIncentives(depositAccountInterestRateChartSlabs, interestIncentivesFields);
}
public void updateDepositAccountInterestRateChartSlabs(DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs) {
this.depositAccountInterestRateChartSlabs = depositAccountInterestRateChartSlabs;
}
public InterestIncentivesFields interestIncentivesFields() {
return this.interestIncentivesFields;
}
}
@@ -1,159 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.domain;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.portfolio.client.domain.Client;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChart;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartFields;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartSlab;
import org.apache.fineract.portfolio.interestratechart.incentive.AttributeIncentiveCalculation;
import org.apache.fineract.portfolio.interestratechart.incentive.AttributeIncentiveCalculationFactory;
import org.apache.fineract.portfolio.interestratechart.incentive.IncentiveDTO;
@Entity
@Table(name = "m_savings_account_interest_rate_chart")
public class DepositAccountInterestRateChart extends AbstractPersistableCustom {
@Embedded
private InterestRateChartFields chartFields;
@OneToOne
@JoinColumn(name = "savings_account_id", nullable = false)
private SavingsAccount account;
@OneToMany(mappedBy = "depositAccountInterestRateChart", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Set<DepositAccountInterestRateChartSlabs> chartSlabs = new HashSet<>();
protected DepositAccountInterestRateChart() {
//
}
public static DepositAccountInterestRateChart from(InterestRateChart productChart) {
final Set<InterestRateChartSlab> chartSlabs = productChart.setOfChartSlabs();
final Set<DepositAccountInterestRateChartSlabs> depostiChartSlabs = new HashSet<>();
for (InterestRateChartSlab interestRateChartSlab : chartSlabs) {
depostiChartSlabs.add(DepositAccountInterestRateChartSlabs.from(interestRateChartSlab, null));
}
final DepositAccountInterestRateChart depositChart = new DepositAccountInterestRateChart(productChart.chartFields(), null,
depostiChartSlabs);
// update deposit account interest rate chart ference to chart Slabs
depositChart.updateChartSlabsReference();
return depositChart;
}
private DepositAccountInterestRateChart(InterestRateChartFields chartFields, SavingsAccount account,
Set<DepositAccountInterestRateChartSlabs> chartSlabs) {
this.chartFields = chartFields;
this.account = account;
this.chartSlabs = chartSlabs;
}
private void updateChartSlabsReference() {
final Set<DepositAccountInterestRateChartSlabs> chartSlabs = setOfChartSlabs();
for (DepositAccountInterestRateChartSlabs chartSlab : chartSlabs) {
chartSlab.updateChartReference(this);
}
}
public Set<DepositAccountInterestRateChartSlabs> setOfChartSlabs() {
if (this.chartSlabs == null) {
this.chartSlabs = new HashSet<>();
}
return this.chartSlabs;
}
public DepositAccountInterestRateChartSlabs findChartSlab(Long chartSlabId) {
final Set<DepositAccountInterestRateChartSlabs> chartSlabs = setOfChartSlabs();
for (DepositAccountInterestRateChartSlabs interestRateChartSlab : chartSlabs) {
if (interestRateChartSlab.getId().equals(chartSlabId)) {
return interestRateChartSlab;
}
}
return null;
}
public LocalDate getFromDate() {
return this.chartFields.getFromDate();
}
public LocalDate getEndDate() {
return this.chartFields.getEndDate();
}
public Long savingsAccountId() {
return this.account == null ? null : this.account.getId();
}
public SavingsAccount savingsAccount() {
return this.account;
}
public InterestRateChartFields chartFields() {
return this.chartFields;
}
public void updateDepositAccountReference(final SavingsAccount account) {
this.account = account;
}
public BigDecimal getApplicableInterestRate(final BigDecimal depositAmount, final LocalDate periodStartDate,
final LocalDate periodEndDate, final Client client) {
BigDecimal effectiveInterestRate = BigDecimal.ZERO;
for (DepositAccountInterestRateChartSlabs slab : setOfChartSlabs()) {
if (slab.slabFields().isBetweenPeriod(periodStartDate, periodEndDate) && slab.slabFields().isAmountBetween(depositAmount)) {
effectiveInterestRate = slab.slabFields().annualInterestRate();
Set<DepositAccountInterestIncentives> depositInterestIncentives = slab.setOfIncentives();
for (DepositAccountInterestIncentives incentives : depositInterestIncentives) {
AttributeIncentiveCalculation attributeIncentiveCalculation = AttributeIncentiveCalculationFactory
.findAttributeIncentiveCalculation(incentives.interestIncentivesFields().entiryType());
IncentiveDTO incentiveDTO = new IncentiveDTO(client, effectiveInterestRate, incentives.interestIncentivesFields());
effectiveInterestRate = attributeIncentiveCalculation.calculateIncentive(incentiveDTO);
}
// effectiveInterestRate is zero or null then reset to default
// interest rate.
if (effectiveInterestRate == null || effectiveInterestRate.compareTo(BigDecimal.ZERO) == 0) {
effectiveInterestRate = slab.slabFields().annualInterestRate();
}
}
}
return effectiveInterestRate;
}
public boolean isPrimaryGroupingByAmount() {
return this.chartFields.isPrimaryGroupingByAmount();
}
}
@@ -1,105 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.savings.domain;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.util.HashSet;
import java.util.Set;
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
import org.apache.fineract.portfolio.interestratechart.domain.InterestIncentives;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartSlab;
import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartSlabFields;
@Entity
@Table(name = "m_savings_account_interest_rate_slab")
public class DepositAccountInterestRateChartSlabs extends AbstractPersistableCustom {
@Embedded
private InterestRateChartSlabFields slabFields;
@ManyToOne(optional = false)
@JoinColumn(name = "savings_account_interest_rate_chart_id", referencedColumnName = "id", nullable = false)
private DepositAccountInterestRateChart depositAccountInterestRateChart;
@OneToMany(mappedBy = "depositAccountInterestRateChartSlabs", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Set<DepositAccountInterestIncentives> interestIncentives = new HashSet<>();
protected DepositAccountInterestRateChartSlabs() {
//
}
private DepositAccountInterestRateChartSlabs(InterestRateChartSlabFields slabFields,
DepositAccountInterestRateChart depositAccountInterestRateChart,
final Set<DepositAccountInterestIncentives> interestIncentives) {
this.slabFields = slabFields;
this.depositAccountInterestRateChart = depositAccountInterestRateChart;
this.interestIncentives = interestIncentives;
}
public void setDepositAccountInterestRateChart(DepositAccountInterestRateChart depositAccountInterestRateChart) {
this.depositAccountInterestRateChart = depositAccountInterestRateChart;
}
public Long savingsProductId() {
return this.depositAccountInterestRateChart.savingsAccountId();
}
public InterestRateChartSlabFields slabFields() {
return this.slabFields;
}
public static DepositAccountInterestRateChartSlabs from(InterestRateChartSlab interestRateChartSlab,
DepositAccountInterestRateChart depositAccountInterestRateChart) {
InterestRateChartSlabFields slabFields = interestRateChartSlab.slabFields();
Set<DepositAccountInterestIncentives> depositInterestIncentives = new HashSet<>();
Set<InterestIncentives> incentives = interestRateChartSlab.setOfInterestIncentives();
for (InterestIncentives incentive : incentives) {
depositInterestIncentives.add(DepositAccountInterestIncentives.from(null, incentive.interestIncentivesFields()));
}
DepositAccountInterestRateChartSlabs chartSlabs = new DepositAccountInterestRateChartSlabs(slabFields,
depositAccountInterestRateChart, depositInterestIncentives);
chartSlabs.updateIncentiveReference();
return chartSlabs;
}
private void updateIncentiveReference() {
final Set<DepositAccountInterestIncentives> incentives = setOfIncentives();
for (DepositAccountInterestIncentives depositInterestIncentives : incentives) {
depositInterestIncentives.updateDepositAccountInterestRateChartSlabs(this);
}
}
public Set<DepositAccountInterestIncentives> setOfIncentives() {
if (this.interestIncentives == null) {
this.interestIncentives = new HashSet<>();
}
return this.interestIncentives;
}
public void updateChartReference(final DepositAccountInterestRateChart chart) {
this.depositAccountInterestRateChart = chart;
}
}

Some files were not shown because too many files have changed in this diff Show More