FINERACT-2180: Trigger (internal) business event when new datatable entry was added
This commit is contained in:
committed by
Adam Saghy
parent
3198b1b99e
commit
e1d820756f
+38
-11
@@ -106,8 +106,12 @@ import org.apache.fineract.infrastructure.dataqueries.data.ResultsetRowData;
|
|||||||
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableEntryRequiredException;
|
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableEntryRequiredException;
|
||||||
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableNotFoundException;
|
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableNotFoundException;
|
||||||
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableSystemErrorException;
|
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableSystemErrorException;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.datatable.DatatableEntryCreatedBusinessEvent;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.datatable.DatatableEntryDeletedBusinessEvent;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.datatable.DatatableEntryDetails;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.datatable.DatatableEntryUpdatedBusinessEvent;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.apache.fineract.infrastructure.security.service.SqlInjectionPreventerService;
|
|
||||||
import org.apache.fineract.infrastructure.security.service.SqlValidator;
|
import org.apache.fineract.infrastructure.security.service.SqlValidator;
|
||||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||||
import org.apache.fineract.portfolio.search.data.AdvancedQueryData;
|
import org.apache.fineract.portfolio.search.data.AdvancedQueryData;
|
||||||
@@ -156,10 +160,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
|||||||
private final DataTableValidator dataTableValidator;
|
private final DataTableValidator dataTableValidator;
|
||||||
private final ColumnValidator columnValidator;
|
private final ColumnValidator columnValidator;
|
||||||
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
||||||
private final SqlInjectionPreventerService preventSqlInjectionService;
|
|
||||||
private final DatatableKeywordGenerator datatableKeywordGenerator;
|
private final DatatableKeywordGenerator datatableKeywordGenerator;
|
||||||
private final SqlValidator sqlValidator;
|
private final SqlValidator sqlValidator;
|
||||||
private final SearchUtil searchUtil;
|
private final SearchUtil searchUtil;
|
||||||
|
private final BusinessEventNotifierService businessEventNotifierService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DatatableData> retrieveDatatableNames(final String appTable) {
|
public List<DatatableData> retrieveDatatableNames(final String appTable) {
|
||||||
@@ -1307,8 +1311,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
|||||||
|
|
||||||
ArrayList<String> insertColumns = new ArrayList<>(
|
ArrayList<String> insertColumns = new ArrayList<>(
|
||||||
List.of(entityTable.getForeignKeyColumnNameOnDatatable(), CREATEDAT_FIELD_NAME, UPDATEDAT_FIELD_NAME));
|
List.of(entityTable.getForeignKeyColumnNameOnDatatable(), CREATEDAT_FIELD_NAME, UPDATEDAT_FIELD_NAME));
|
||||||
LocalDateTime auditDateTime = DateUtils.getAuditLocalDateTime();
|
final LocalDateTime auditDateTime = DateUtils.getAuditLocalDateTime();
|
||||||
ArrayList<Object> params = new ArrayList<>(List.of(appTableId, auditDateTime, auditDateTime));
|
ArrayList<Object> params = new ArrayList<>(List.of(appTableId, auditDateTime, auditDateTime));
|
||||||
|
Map<String, Object> dataObjectParams = new HashMap<String, Object>();
|
||||||
for (Map.Entry<String, String> entry : dataParams.entrySet()) {
|
for (Map.Entry<String, String> entry : dataParams.entrySet()) {
|
||||||
if (isTechnicalParam(entry.getKey())) {
|
if (isTechnicalParam(entry.getKey())) {
|
||||||
continue;
|
continue;
|
||||||
@@ -1318,8 +1323,11 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
insertColumns.add(columnHeader.getColumnName());
|
insertColumns.add(columnHeader.getColumnName());
|
||||||
params.add(searchUtil.parseJdbcColumnValue(columnHeader, entry.getValue(), dateFormat, dateTimeFormat, locale, false,
|
Object valueParam = searchUtil.parseJdbcColumnValue(columnHeader, entry.getValue(), dateFormat, dateTimeFormat, locale, false,
|
||||||
sqlGenerator));
|
sqlGenerator);
|
||||||
|
params.add(valueParam);
|
||||||
|
dataObjectParams.put(entry.getKey(), valueParam);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (addScore) {
|
if (addScore) {
|
||||||
List<Object> scoreIds = params.stream().filter(e -> e != null && !String.valueOf(e).isBlank()).toList();
|
List<Object> scoreIds = params.stream().filter(e -> e != null && !String.valueOf(e).isBlank()).toList();
|
||||||
@@ -1353,6 +1361,11 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
|||||||
if (isMultirowDatatable(columnHeaders)) {
|
if (isMultirowDatatable(columnHeaders)) {
|
||||||
resourceId = sqlGenerator.fetchPK(keyHolder);
|
resourceId = sqlGenerator.fetchPK(keyHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final DatatableEntryDetails datatableEntryDetails = new DatatableEntryDetails(dataTableName, entityTable, resourceId,
|
||||||
|
appTableId, dataObjectParams);
|
||||||
|
businessEventNotifierService.notifyPostBusinessEvent(new DatatableEntryCreatedBusinessEvent(datatableEntryDetails));
|
||||||
|
|
||||||
return CommandProcessingResult.fromCommandProcessingResult(commandProcessingResult, resourceId);
|
return CommandProcessingResult.fromCommandProcessingResult(commandProcessingResult, resourceId);
|
||||||
} catch (final DataAccessException dve) {
|
} catch (final DataAccessException dve) {
|
||||||
handleDataIntegrityIssues(dataTableName, appTableId, dve.getMostSpecificCause(), dve);
|
handleDataIntegrityIssues(dataTableName, appTableId, dve.getMostSpecificCause(), dve);
|
||||||
@@ -1422,6 +1435,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
|||||||
|
|
||||||
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
|
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
|
||||||
final Map<String, String> dataParams = fromJsonHelper.extractDataMap(typeOfMap, command.json());
|
final Map<String, String> dataParams = fromJsonHelper.extractDataMap(typeOfMap, command.json());
|
||||||
|
final Map<String, Object> dataObjectParams = new HashMap<String, Object>();
|
||||||
|
|
||||||
final String dateFormat = dataParams.get(API_PARAM_DATE_FORMAT);
|
final String dateFormat = dataParams.get(API_PARAM_DATE_FORMAT);
|
||||||
// fall back to dateFormat to keep backward compatibility
|
// fall back to dateFormat to keep backward compatibility
|
||||||
@@ -1445,6 +1459,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
|||||||
Object existingValue = valuesByHeader.get(columnHeader);
|
Object existingValue = valuesByHeader.get(columnHeader);
|
||||||
Object columnValue = searchUtil.parseColumnValue(columnHeader, entry.getValue(), dateFormat, dateTimeFormat, locale, false,
|
Object columnValue = searchUtil.parseColumnValue(columnHeader, entry.getValue(), dateFormat, dateTimeFormat, locale, false,
|
||||||
sqlGenerator);
|
sqlGenerator);
|
||||||
|
dataObjectParams.put(entry.getKey(), columnValue);
|
||||||
if ((columnHeader.getColumnType().isDecimalType() && MathUtil.isEqualTo((BigDecimal) existingValue, (BigDecimal) columnValue))
|
if ((columnHeader.getColumnType().isDecimalType() && MathUtil.isEqualTo((BigDecimal) existingValue, (BigDecimal) columnValue))
|
||||||
|| (existingValue == null ? columnValue == null : existingValue.equals(columnValue))) {
|
|| (existingValue == null ? columnValue == null : existingValue.equals(columnValue))) {
|
||||||
log.debug("Ignore change on update {}:{}", dataTableName, columnName);
|
log.debug("Ignore change on update {}:{}", dataTableName, columnName);
|
||||||
@@ -1457,16 +1472,23 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
|||||||
Long primaryKey = datatableId == null ? appTableId : datatableId;
|
Long primaryKey = datatableId == null ? appTableId : datatableId;
|
||||||
if (!updateColumns.isEmpty()) {
|
if (!updateColumns.isEmpty()) {
|
||||||
ResultsetColumnHeaderData pkColumn = searchUtil.getFiltered(columnHeaders, ResultsetColumnHeaderData::getIsColumnPrimaryKey);
|
ResultsetColumnHeaderData pkColumn = searchUtil.getFiltered(columnHeaders, ResultsetColumnHeaderData::getIsColumnPrimaryKey);
|
||||||
params.add(primaryKey);
|
if (pkColumn != null) {
|
||||||
final String sql = sqlGenerator.buildUpdate(dataTableName, updateColumns, headersByName) + " WHERE " + pkColumn.getColumnName()
|
params.add(primaryKey);
|
||||||
+ " = ?";
|
final String sql = sqlGenerator.buildUpdate(dataTableName, updateColumns, headersByName) + " WHERE "
|
||||||
int updated = jdbcTemplate.update(sql, params.toArray(Object[]::new)); // NOSONAR
|
+ pkColumn.getColumnName() + " = ?";
|
||||||
if (updated != 1) {
|
int updated = jdbcTemplate.update(sql, params.toArray(Object[]::new)); // NOSONAR
|
||||||
throw new PlatformDataIntegrityException("error.msg.invalid.update", "Expected one updated row.");
|
if (updated != 1) {
|
||||||
|
throw new PlatformDataIntegrityException("error.msg.invalid.update", "Expected one updated row.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.debug("No change on update {}", dataTableName);
|
log.debug("No change on update {}", dataTableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final DatatableEntryDetails datatableEntryDetails = new DatatableEntryDetails(dataTableName, entityTable, datatableId, appTableId,
|
||||||
|
dataObjectParams);
|
||||||
|
businessEventNotifierService.notifyPostBusinessEvent(new DatatableEntryUpdatedBusinessEvent(datatableEntryDetails));
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder().withCommandId(command.commandId()) //
|
return new CommandProcessingResultBuilder().withCommandId(command.commandId()) //
|
||||||
.withEntityId(primaryKey) //
|
.withEntityId(primaryKey) //
|
||||||
.withOfficeId(commandProcessingResult.getOfficeId()) //
|
.withOfficeId(commandProcessingResult.getOfficeId()) //
|
||||||
@@ -1517,6 +1539,11 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
|||||||
+ whereValue;
|
+ whereValue;
|
||||||
|
|
||||||
this.jdbcTemplate.update(sql); // NOSONAR
|
this.jdbcTemplate.update(sql); // NOSONAR
|
||||||
|
final Map<String, Object> dataParams = null;
|
||||||
|
final DatatableEntryDetails datatableEntryDetails = new DatatableEntryDetails(dataTableName, entityTable, datatableId, appTableId,
|
||||||
|
dataParams);
|
||||||
|
businessEventNotifierService.notifyPostBusinessEvent(new DatatableEntryDeletedBusinessEvent(datatableEntryDetails));
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(whereValue) //
|
.withEntityId(whereValue) //
|
||||||
|
|||||||
+5
-5
@@ -29,8 +29,8 @@ import org.apache.fineract.infrastructure.dataqueries.service.DatatableKeywordGe
|
|||||||
import org.apache.fineract.infrastructure.dataqueries.service.GenericDataService;
|
import org.apache.fineract.infrastructure.dataqueries.service.GenericDataService;
|
||||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataServiceImpl;
|
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataServiceImpl;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.apache.fineract.infrastructure.security.service.SqlInjectionPreventerService;
|
|
||||||
import org.apache.fineract.infrastructure.security.service.SqlValidator;
|
import org.apache.fineract.infrastructure.security.service.SqlValidator;
|
||||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||||
import org.apache.fineract.portfolio.search.service.SearchUtil;
|
import org.apache.fineract.portfolio.search.service.SearchUtil;
|
||||||
@@ -51,11 +51,11 @@ public class DataQueriesAutoConfiguration {
|
|||||||
final DatatableCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
final DatatableCommandFromApiJsonDeserializer fromApiJsonDeserializer,
|
||||||
final ConfigurationDomainService configurationDomainService, final CodeReadPlatformService codeReadPlatformService,
|
final ConfigurationDomainService configurationDomainService, final CodeReadPlatformService codeReadPlatformService,
|
||||||
final DataTableValidator dataTableValidator, final ColumnValidator columnValidator,
|
final DataTableValidator dataTableValidator, final ColumnValidator columnValidator,
|
||||||
final NamedParameterJdbcTemplate namedParameterJdbcTemplate, final SqlInjectionPreventerService preventSqlInjectionService,
|
final NamedParameterJdbcTemplate namedParameterJdbcTemplate, DatatableKeywordGenerator datatableKeywordGenerator,
|
||||||
DatatableKeywordGenerator datatableKeywordGenerator, SqlValidator sqlValidator, SearchUtil searchUtil) {
|
SqlValidator sqlValidator, SearchUtil searchUtil, final BusinessEventNotifierService businessEventNotifierService) {
|
||||||
return new ReadWriteNonCoreDataServiceImpl(jdbcTemplate, databaseTypeResolver, sqlGenerator, context, fromJsonHelper,
|
return new ReadWriteNonCoreDataServiceImpl(jdbcTemplate, databaseTypeResolver, sqlGenerator, context, fromJsonHelper,
|
||||||
genericDataService, fromApiJsonDeserializer, configurationDomainService, codeReadPlatformService, dataTableValidator,
|
genericDataService, fromApiJsonDeserializer, configurationDomainService, codeReadPlatformService, dataTableValidator,
|
||||||
columnValidator, namedParameterJdbcTemplate, preventSqlInjectionService, datatableKeywordGenerator, sqlValidator,
|
columnValidator, namedParameterJdbcTemplate, datatableKeywordGenerator, sqlValidator, searchUtil,
|
||||||
searchUtil);
|
businessEventNotifierService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* 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.event.business.domain.datatable;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.AbstractBusinessEvent;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public abstract class DatatableEntryBusinessEvent extends AbstractBusinessEvent<DatatableEntryDetails> {
|
||||||
|
|
||||||
|
protected static final String CATEGORY = "Datatable";
|
||||||
|
public static final String TYPE = "DatatableEntryBusinessEvent";
|
||||||
|
|
||||||
|
protected DatatableEntryDetails datatableEntryDetails;
|
||||||
|
|
||||||
|
public DatatableEntryBusinessEvent(final DatatableEntryDetails datatableEntryDetails) {
|
||||||
|
super(datatableEntryDetails);
|
||||||
|
this.datatableEntryDetails = datatableEntryDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return CATEGORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* 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.event.business.domain.datatable;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.NoExternalEvent;
|
||||||
|
|
||||||
|
public class DatatableEntryCreatedBusinessEvent extends DatatableEntryBusinessEvent implements NoExternalEvent {
|
||||||
|
|
||||||
|
public static final String TYPE = "DatatableEntryCreatedBusinessEvent";
|
||||||
|
|
||||||
|
public DatatableEntryCreatedBusinessEvent(final DatatableEntryDetails datatableEntryDetails) {
|
||||||
|
super(datatableEntryDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getAggregateRootId() {
|
||||||
|
return datatableEntryDetails.getEntityId();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* 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.event.business.domain.datatable;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.NoExternalEvent;
|
||||||
|
|
||||||
|
public class DatatableEntryDeletedBusinessEvent extends DatatableEntryBusinessEvent implements NoExternalEvent {
|
||||||
|
|
||||||
|
public static final String TYPE = "DatatableEntryDeletedBusinessEvent";
|
||||||
|
|
||||||
|
public DatatableEntryDeletedBusinessEvent(final DatatableEntryDetails datatableEntryDetails) {
|
||||||
|
super(datatableEntryDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getAggregateRootId() {
|
||||||
|
return datatableEntryDetails.getEntityId();
|
||||||
|
}
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* 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.event.business.domain.datatable;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class DatatableEntryDetails {
|
||||||
|
|
||||||
|
private final String datatableName;
|
||||||
|
private final EntityTables entityType;
|
||||||
|
private final Long entityId;
|
||||||
|
private final Long appTableId;
|
||||||
|
private final Map<String, Object> data;
|
||||||
|
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* 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.event.business.domain.datatable;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.NoExternalEvent;
|
||||||
|
|
||||||
|
public class DatatableEntryUpdatedBusinessEvent extends DatatableEntryBusinessEvent implements NoExternalEvent {
|
||||||
|
|
||||||
|
public static final String TYPE = "DatatableEntryUpdatedBusinessEvent";
|
||||||
|
|
||||||
|
public DatatableEntryUpdatedBusinessEvent(final DatatableEntryDetails datatableEntryDetails) {
|
||||||
|
super(datatableEntryDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getAggregateRootId() {
|
||||||
|
return datatableEntryDetails.getEntityId();
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-2
@@ -68,6 +68,7 @@ import org.apache.fineract.portfolio.accountdetails.service.AccountDetailsReadPl
|
|||||||
import org.apache.fineract.portfolio.client.data.ClientData;
|
import org.apache.fineract.portfolio.client.data.ClientData;
|
||||||
import org.apache.fineract.portfolio.client.exception.ClientNotFoundException;
|
import org.apache.fineract.portfolio.client.exception.ClientNotFoundException;
|
||||||
import org.apache.fineract.portfolio.client.service.ClientReadPlatformService;
|
import org.apache.fineract.portfolio.client.service.ClientReadPlatformService;
|
||||||
|
import org.apache.fineract.portfolio.client.service.ClientTemplateReadPlatformService;
|
||||||
import org.apache.fineract.portfolio.loanaccount.guarantor.data.ObligeeData;
|
import org.apache.fineract.portfolio.loanaccount.guarantor.data.ObligeeData;
|
||||||
import org.apache.fineract.portfolio.loanaccount.guarantor.service.GuarantorReadPlatformService;
|
import org.apache.fineract.portfolio.loanaccount.guarantor.service.GuarantorReadPlatformService;
|
||||||
import org.apache.fineract.portfolio.savings.data.SavingsAccountData;
|
import org.apache.fineract.portfolio.savings.data.SavingsAccountData;
|
||||||
@@ -85,6 +86,7 @@ public class ClientsApiResource {
|
|||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final ClientReadPlatformService clientReadPlatformService;
|
private final ClientReadPlatformService clientReadPlatformService;
|
||||||
|
private final ClientTemplateReadPlatformService clientTemplateReadPlatformService;
|
||||||
private final ToApiJsonSerializer<ClientData> toApiJsonSerializer;
|
private final ToApiJsonSerializer<ClientData> toApiJsonSerializer;
|
||||||
private final ToApiJsonSerializer<AccountSummaryCollectionData> clientAccountSummaryToApiJsonSerializer;
|
private final ToApiJsonSerializer<AccountSummaryCollectionData> clientAccountSummaryToApiJsonSerializer;
|
||||||
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
private final ApiRequestParameterHelper apiRequestParameterHelper;
|
||||||
@@ -122,7 +124,7 @@ public class ClientsApiResource {
|
|||||||
} else if (CommandParameterUtil.is(commandParam, "withdraw")) {
|
} else if (CommandParameterUtil.is(commandParam, "withdraw")) {
|
||||||
clientData = clientReadPlatformService.retrieveAllNarrations(ClientApiConstants.CLIENT_WITHDRAW_REASON);
|
clientData = clientReadPlatformService.retrieveAllNarrations(ClientApiConstants.CLIENT_WITHDRAW_REASON);
|
||||||
} else {
|
} else {
|
||||||
clientData = clientReadPlatformService.retrieveTemplate(officeId, staffInSelectedOfficeOnly);
|
clientData = clientTemplateReadPlatformService.retrieveTemplate(officeId, staffInSelectedOfficeOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
@@ -458,7 +460,8 @@ public class ClientsApiResource {
|
|||||||
private ClientData retrieveClientData(final Long clientId, final boolean staffInSelectedOfficeOnly, final boolean isTemplate) {
|
private ClientData retrieveClientData(final Long clientId, final boolean staffInSelectedOfficeOnly, final boolean isTemplate) {
|
||||||
ClientData clientData = clientReadPlatformService.retrieveOne(clientId);
|
ClientData clientData = clientReadPlatformService.retrieveOne(clientId);
|
||||||
if (isTemplate) {
|
if (isTemplate) {
|
||||||
final ClientData templateData = clientReadPlatformService.retrieveTemplate(clientData.getOfficeId(), staffInSelectedOfficeOnly);
|
final ClientData templateData = clientTemplateReadPlatformService.retrieveTemplate(clientData.getOfficeId(),
|
||||||
|
staffInSelectedOfficeOnly);
|
||||||
clientData = ClientData.templateOnTop(clientData, templateData);
|
clientData = ClientData.templateOnTop(clientData, templateData);
|
||||||
Collection<SavingsAccountData> savingAccountOptions = savingsAccountReadPlatformService.retrieveForLookup(clientId, null);
|
Collection<SavingsAccountData> savingAccountOptions = savingsAccountReadPlatformService.retrieveForLookup(clientId, null);
|
||||||
if (savingAccountOptions != null && savingAccountOptions.size() > 0) {
|
if (savingAccountOptions != null && savingAccountOptions.size() > 0) {
|
||||||
|
|||||||
-2
@@ -27,8 +27,6 @@ import org.apache.fineract.portfolio.client.data.ClientData;
|
|||||||
|
|
||||||
public interface ClientReadPlatformService {
|
public interface ClientReadPlatformService {
|
||||||
|
|
||||||
ClientData retrieveTemplate(Long officeId, boolean staffInSelectedOfficeOnly);
|
|
||||||
|
|
||||||
Page<ClientData> retrieveAll(SearchParameters searchParameters);
|
Page<ClientData> retrieveAll(SearchParameters searchParameters);
|
||||||
|
|
||||||
ClientData retrieveOne(Long clientId);
|
ClientData retrieveOne(Long clientId);
|
||||||
|
|||||||
-89
@@ -32,54 +32,36 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
||||||
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
|
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
|
||||||
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
|
||||||
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
import org.apache.fineract.infrastructure.core.domain.ExternalId;
|
||||||
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
||||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
|
||||||
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
import org.apache.fineract.infrastructure.core.service.ExternalIdFactory;
|
||||||
import org.apache.fineract.infrastructure.core.service.Page;
|
import org.apache.fineract.infrastructure.core.service.Page;
|
||||||
import org.apache.fineract.infrastructure.core.service.PaginationHelper;
|
import org.apache.fineract.infrastructure.core.service.PaginationHelper;
|
||||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||||
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
|
||||||
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
|
||||||
import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
|
|
||||||
import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksReadService;
|
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||||
import org.apache.fineract.organisation.office.data.OfficeData;
|
|
||||||
import org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
|
|
||||||
import org.apache.fineract.organisation.staff.data.StaffData;
|
|
||||||
import org.apache.fineract.organisation.staff.service.StaffReadPlatformService;
|
|
||||||
import org.apache.fineract.portfolio.address.data.AddressData;
|
|
||||||
import org.apache.fineract.portfolio.address.service.AddressReadPlatformService;
|
|
||||||
import org.apache.fineract.portfolio.client.api.ClientApiConstants;
|
|
||||||
import org.apache.fineract.portfolio.client.data.ClientCollateralManagementData;
|
import org.apache.fineract.portfolio.client.data.ClientCollateralManagementData;
|
||||||
import org.apache.fineract.portfolio.client.data.ClientData;
|
import org.apache.fineract.portfolio.client.data.ClientData;
|
||||||
import org.apache.fineract.portfolio.client.data.ClientFamilyMembersData;
|
|
||||||
import org.apache.fineract.portfolio.client.data.ClientNonPersonData;
|
import org.apache.fineract.portfolio.client.data.ClientNonPersonData;
|
||||||
import org.apache.fineract.portfolio.client.data.ClientTimelineData;
|
import org.apache.fineract.portfolio.client.data.ClientTimelineData;
|
||||||
import org.apache.fineract.portfolio.client.domain.Client;
|
import org.apache.fineract.portfolio.client.domain.Client;
|
||||||
import org.apache.fineract.portfolio.client.domain.ClientEnumerations;
|
import org.apache.fineract.portfolio.client.domain.ClientEnumerations;
|
||||||
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
|
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
|
||||||
import org.apache.fineract.portfolio.client.domain.ClientStatus;
|
import org.apache.fineract.portfolio.client.domain.ClientStatus;
|
||||||
import org.apache.fineract.portfolio.client.domain.LegalForm;
|
|
||||||
import org.apache.fineract.portfolio.client.exception.ClientNotFoundException;
|
import org.apache.fineract.portfolio.client.exception.ClientNotFoundException;
|
||||||
import org.apache.fineract.portfolio.client.mapper.ClientMapper;
|
import org.apache.fineract.portfolio.client.mapper.ClientMapper;
|
||||||
import org.apache.fineract.portfolio.collateralmanagement.domain.ClientCollateralManagement;
|
import org.apache.fineract.portfolio.collateralmanagement.domain.ClientCollateralManagement;
|
||||||
import org.apache.fineract.portfolio.collateralmanagement.domain.ClientCollateralManagementRepositoryWrapper;
|
import org.apache.fineract.portfolio.collateralmanagement.domain.ClientCollateralManagementRepositoryWrapper;
|
||||||
import org.apache.fineract.portfolio.group.data.GroupGeneralData;
|
import org.apache.fineract.portfolio.group.data.GroupGeneralData;
|
||||||
import org.apache.fineract.portfolio.savings.data.SavingsProductData;
|
|
||||||
import org.apache.fineract.portfolio.savings.service.SavingsProductReadPlatformService;
|
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
import org.springframework.dao.EmptyResultDataAccessException;
|
import org.springframework.dao.EmptyResultDataAccessException;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@@ -87,10 +69,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
|||||||
|
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final OfficeReadPlatformService officeReadPlatformService;
|
|
||||||
private final StaffReadPlatformService staffReadPlatformService;
|
|
||||||
private final CodeValueReadPlatformService codeValueReadPlatformService;
|
private final CodeValueReadPlatformService codeValueReadPlatformService;
|
||||||
private final SavingsProductReadPlatformService savingsProductReadPlatformService;
|
|
||||||
// data mappers
|
// data mappers
|
||||||
private final PaginationHelper paginationHelper;
|
private final PaginationHelper paginationHelper;
|
||||||
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||||
@@ -99,71 +78,11 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
|||||||
private final ClientMembersOfGroupMapper membersOfGroupMapper = new ClientMembersOfGroupMapper();
|
private final ClientMembersOfGroupMapper membersOfGroupMapper = new ClientMembersOfGroupMapper();
|
||||||
private final ParentGroupsMapper clientGroupsMapper = new ParentGroupsMapper();
|
private final ParentGroupsMapper clientGroupsMapper = new ParentGroupsMapper();
|
||||||
|
|
||||||
private final AddressReadPlatformService addressReadPlatformService;
|
|
||||||
private final ClientFamilyMembersReadPlatformService clientFamilyMembersReadPlatformService;
|
|
||||||
private final EntityDatatableChecksReadService entityDatatableChecksReadService;
|
|
||||||
private final ColumnValidator columnValidator;
|
private final ColumnValidator columnValidator;
|
||||||
private final ClientCollateralManagementRepositoryWrapper clientCollateralManagementRepositoryWrapper;
|
private final ClientCollateralManagementRepositoryWrapper clientCollateralManagementRepositoryWrapper;
|
||||||
private final ConfigurationDomainService configurationDomainService;
|
|
||||||
private final ClientRepositoryWrapper clientRepositoryWrapper;
|
private final ClientRepositoryWrapper clientRepositoryWrapper;
|
||||||
private final ClientMapper clientMapper;
|
private final ClientMapper clientMapper;
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClientData retrieveTemplate(final Long officeId, final boolean staffInSelectedOfficeOnly) {
|
|
||||||
this.context.authenticatedUser();
|
|
||||||
|
|
||||||
final Long defaultOfficeId = defaultToUsersOfficeIfNull(officeId);
|
|
||||||
AddressData address = null;
|
|
||||||
|
|
||||||
final Collection<OfficeData> offices = this.officeReadPlatformService.retrieveAllOfficesForDropdown();
|
|
||||||
|
|
||||||
final Collection<SavingsProductData> savingsProductDatas = this.savingsProductReadPlatformService.retrieveAllForLookupByType(null);
|
|
||||||
|
|
||||||
final Boolean isAddressEnabled = configurationDomainService.isAddressEnabled();
|
|
||||||
if (isAddressEnabled) {
|
|
||||||
address = this.addressReadPlatformService.retrieveTemplate();
|
|
||||||
}
|
|
||||||
|
|
||||||
final ClientFamilyMembersData familyMemberOptions = this.clientFamilyMembersReadPlatformService.retrieveTemplate();
|
|
||||||
|
|
||||||
Collection<StaffData> staffOptions = null;
|
|
||||||
|
|
||||||
final boolean loanOfficersOnly = false;
|
|
||||||
if (staffInSelectedOfficeOnly) {
|
|
||||||
staffOptions = this.staffReadPlatformService.retrieveAllStaffForDropdown(defaultOfficeId);
|
|
||||||
} else {
|
|
||||||
staffOptions = this.staffReadPlatformService.retrieveAllStaffInOfficeAndItsParentOfficeHierarchy(defaultOfficeId,
|
|
||||||
loanOfficersOnly);
|
|
||||||
}
|
|
||||||
if (CollectionUtils.isEmpty(staffOptions)) {
|
|
||||||
staffOptions = null;
|
|
||||||
}
|
|
||||||
final List<CodeValueData> genderOptions = new ArrayList<>(
|
|
||||||
this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.GENDER));
|
|
||||||
|
|
||||||
final List<CodeValueData> clientTypeOptions = new ArrayList<>(
|
|
||||||
this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_TYPE));
|
|
||||||
|
|
||||||
final List<CodeValueData> clientClassificationOptions = new ArrayList<>(
|
|
||||||
this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_CLASSIFICATION));
|
|
||||||
|
|
||||||
final List<CodeValueData> clientNonPersonConstitutionOptions = new ArrayList<>(
|
|
||||||
this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_NON_PERSON_CONSTITUTION));
|
|
||||||
|
|
||||||
final List<CodeValueData> clientNonPersonMainBusinessLineOptions = new ArrayList<>(
|
|
||||||
this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_NON_PERSON_MAIN_BUSINESS_LINE));
|
|
||||||
|
|
||||||
final List<EnumOptionData> clientLegalFormOptions = ClientEnumerations.legalForm(LegalForm.values());
|
|
||||||
|
|
||||||
final List<DatatableData> datatableTemplates = this.entityDatatableChecksReadService.retrieveTemplates(StatusEnum.CREATE.getValue(),
|
|
||||||
EntityTables.CLIENT.getName(), null);
|
|
||||||
|
|
||||||
return ClientData.template(defaultOfficeId, LocalDate.now(DateUtils.getDateTimeZoneOfTenant()), offices, staffOptions, null,
|
|
||||||
genderOptions, savingsProductDatas, clientTypeOptions, clientClassificationOptions, clientNonPersonConstitutionOptions,
|
|
||||||
clientNonPersonMainBusinessLineOptions, clientLegalFormOptions, familyMemberOptions,
|
|
||||||
new ArrayList<AddressData>(Arrays.asList(address)), isAddressEnabled, datatableTemplates);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<ClientData> retrieveAll(final SearchParameters searchParameters) {
|
public Page<ClientData> retrieveAll(final SearchParameters searchParameters) {
|
||||||
|
|
||||||
@@ -643,14 +562,6 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Long defaultToUsersOfficeIfNull(final Long officeId) {
|
|
||||||
Long defaultOfficeId = officeId;
|
|
||||||
if (defaultOfficeId == null) {
|
|
||||||
defaultOfficeId = this.context.authenticatedUser().getOffice().getId();
|
|
||||||
}
|
|
||||||
return defaultOfficeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientData retrieveAllNarrations(final String clientNarrations) {
|
public ClientData retrieveAllNarrations(final String clientNarrations) {
|
||||||
final List<CodeValueData> narrations = new ArrayList<>(
|
final List<CodeValueData> narrations = new ArrayList<>(
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* 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.client.service;
|
||||||
|
|
||||||
|
import org.apache.fineract.portfolio.client.data.ClientData;
|
||||||
|
|
||||||
|
public interface ClientTemplateReadPlatformService {
|
||||||
|
|
||||||
|
ClientData retrieveTemplate(Long officeId, boolean staffInSelectedOfficeOnly);
|
||||||
|
|
||||||
|
}
|
||||||
+133
@@ -0,0 +1,133 @@
|
|||||||
|
/**
|
||||||
|
* 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.client.service;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
|
||||||
|
import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformService;
|
||||||
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
|
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
||||||
|
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||||
|
import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
|
||||||
|
import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksReadService;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.apache.fineract.organisation.office.data.OfficeData;
|
||||||
|
import org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
|
||||||
|
import org.apache.fineract.organisation.staff.data.StaffData;
|
||||||
|
import org.apache.fineract.organisation.staff.service.StaffReadPlatformService;
|
||||||
|
import org.apache.fineract.portfolio.address.data.AddressData;
|
||||||
|
import org.apache.fineract.portfolio.address.service.AddressReadPlatformService;
|
||||||
|
import org.apache.fineract.portfolio.client.api.ClientApiConstants;
|
||||||
|
import org.apache.fineract.portfolio.client.data.ClientData;
|
||||||
|
import org.apache.fineract.portfolio.client.data.ClientFamilyMembersData;
|
||||||
|
import org.apache.fineract.portfolio.client.domain.ClientEnumerations;
|
||||||
|
import org.apache.fineract.portfolio.client.domain.LegalForm;
|
||||||
|
import org.apache.fineract.portfolio.savings.data.SavingsProductData;
|
||||||
|
import org.apache.fineract.portfolio.savings.service.SavingsProductReadPlatformService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class ClientTemplateReadPlatformServiceImpl implements ClientTemplateReadPlatformService {
|
||||||
|
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
private final OfficeReadPlatformService officeReadPlatformService;
|
||||||
|
private final StaffReadPlatformService staffReadPlatformService;
|
||||||
|
private final CodeValueReadPlatformService codeValueReadPlatformService;
|
||||||
|
private final SavingsProductReadPlatformService savingsProductReadPlatformService;
|
||||||
|
// data mappers
|
||||||
|
private final EntityDatatableChecksReadService entityDatatableChecksReadService;
|
||||||
|
|
||||||
|
private final AddressReadPlatformService addressReadPlatformService;
|
||||||
|
private final ClientFamilyMembersReadPlatformService clientFamilyMembersReadPlatformService;
|
||||||
|
private final ConfigurationDomainService configurationDomainService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientData retrieveTemplate(final Long officeId, final boolean staffInSelectedOfficeOnly) {
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
|
||||||
|
final Long defaultOfficeId = defaultToUsersOfficeIfNull(officeId);
|
||||||
|
AddressData address = null;
|
||||||
|
|
||||||
|
final Collection<OfficeData> offices = this.officeReadPlatformService.retrieveAllOfficesForDropdown();
|
||||||
|
|
||||||
|
final Collection<SavingsProductData> savingsProductDatas = this.savingsProductReadPlatformService.retrieveAllForLookupByType(null);
|
||||||
|
|
||||||
|
final Boolean isAddressEnabled = configurationDomainService.isAddressEnabled();
|
||||||
|
if (isAddressEnabled) {
|
||||||
|
address = this.addressReadPlatformService.retrieveTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
final ClientFamilyMembersData familyMemberOptions = this.clientFamilyMembersReadPlatformService.retrieveTemplate();
|
||||||
|
|
||||||
|
Collection<StaffData> staffOptions = null;
|
||||||
|
|
||||||
|
final boolean loanOfficersOnly = false;
|
||||||
|
if (staffInSelectedOfficeOnly) {
|
||||||
|
staffOptions = this.staffReadPlatformService.retrieveAllStaffForDropdown(defaultOfficeId);
|
||||||
|
} else {
|
||||||
|
staffOptions = this.staffReadPlatformService.retrieveAllStaffInOfficeAndItsParentOfficeHierarchy(defaultOfficeId,
|
||||||
|
loanOfficersOnly);
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isEmpty(staffOptions)) {
|
||||||
|
staffOptions = null;
|
||||||
|
}
|
||||||
|
final List<CodeValueData> genderOptions = new ArrayList<>(
|
||||||
|
this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.GENDER));
|
||||||
|
|
||||||
|
final List<CodeValueData> clientTypeOptions = new ArrayList<>(
|
||||||
|
this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_TYPE));
|
||||||
|
|
||||||
|
final List<CodeValueData> clientClassificationOptions = new ArrayList<>(
|
||||||
|
this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_CLASSIFICATION));
|
||||||
|
|
||||||
|
final List<CodeValueData> clientNonPersonConstitutionOptions = new ArrayList<>(
|
||||||
|
this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_NON_PERSON_CONSTITUTION));
|
||||||
|
|
||||||
|
final List<CodeValueData> clientNonPersonMainBusinessLineOptions = new ArrayList<>(
|
||||||
|
this.codeValueReadPlatformService.retrieveCodeValuesByCode(ClientApiConstants.CLIENT_NON_PERSON_MAIN_BUSINESS_LINE));
|
||||||
|
|
||||||
|
final List<EnumOptionData> clientLegalFormOptions = ClientEnumerations.legalForm(LegalForm.values());
|
||||||
|
|
||||||
|
final List<DatatableData> datatableTemplates = this.entityDatatableChecksReadService.retrieveTemplates(StatusEnum.CREATE.getValue(),
|
||||||
|
EntityTables.CLIENT.getName(), null);
|
||||||
|
|
||||||
|
return ClientData.template(defaultOfficeId, LocalDate.now(DateUtils.getDateTimeZoneOfTenant()), offices, staffOptions, null,
|
||||||
|
genderOptions, savingsProductDatas, clientTypeOptions, clientClassificationOptions, clientNonPersonConstitutionOptions,
|
||||||
|
clientNonPersonMainBusinessLineOptions, clientLegalFormOptions, familyMemberOptions,
|
||||||
|
new ArrayList<AddressData>(Arrays.asList(address)), isAddressEnabled, datatableTemplates);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long defaultToUsersOfficeIfNull(final Long officeId) {
|
||||||
|
Long defaultOfficeId = officeId;
|
||||||
|
if (defaultOfficeId == null) {
|
||||||
|
defaultOfficeId = this.context.authenticatedUser().getOffice().getId();
|
||||||
|
}
|
||||||
|
return defaultOfficeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+5
-3
@@ -74,6 +74,7 @@ import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionData;
|
|||||||
import org.apache.fineract.portfolio.savings.exception.SavingsAccountNotFoundException;
|
import org.apache.fineract.portfolio.savings.exception.SavingsAccountNotFoundException;
|
||||||
import org.apache.fineract.portfolio.savings.service.SavingsAccountChargeReadPlatformService;
|
import org.apache.fineract.portfolio.savings.service.SavingsAccountChargeReadPlatformService;
|
||||||
import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformService;
|
import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformService;
|
||||||
|
import org.apache.fineract.portfolio.savings.service.SavingsAccountTemplateReadPlatformService;
|
||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -86,6 +87,7 @@ import org.springframework.util.CollectionUtils;
|
|||||||
public class SavingsAccountsApiResource {
|
public class SavingsAccountsApiResource {
|
||||||
|
|
||||||
private final SavingsAccountReadPlatformService savingsAccountReadPlatformService;
|
private final SavingsAccountReadPlatformService savingsAccountReadPlatformService;
|
||||||
|
private final SavingsAccountTemplateReadPlatformService savingsAccountTemplateReadPlatformService;
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final DefaultToApiJsonSerializer<SavingsAccountData> toApiJsonSerializer;
|
private final DefaultToApiJsonSerializer<SavingsAccountData> toApiJsonSerializer;
|
||||||
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
|
||||||
@@ -112,7 +114,7 @@ public class SavingsAccountsApiResource {
|
|||||||
|
|
||||||
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
|
context.authenticatedUser().validateHasReadPermission(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME);
|
||||||
|
|
||||||
final SavingsAccountData savingsAccount = savingsAccountReadPlatformService.retrieveTemplate(clientId, groupId, productId,
|
final SavingsAccountData savingsAccount = savingsAccountTemplateReadPlatformService.retrieveTemplate(clientId, groupId, productId,
|
||||||
staffInSelectedOfficeOnly);
|
staffInSelectedOfficeOnly);
|
||||||
|
|
||||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
@@ -662,8 +664,8 @@ public class SavingsAccountsApiResource {
|
|||||||
SavingsAccountData templateData = null;
|
SavingsAccountData templateData = null;
|
||||||
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
|
||||||
if (settings.isTemplate()) {
|
if (settings.isTemplate()) {
|
||||||
templateData = savingsAccountReadPlatformService.retrieveTemplate(savingsAccount.getClientId(), savingsAccount.getGroupId(),
|
templateData = savingsAccountTemplateReadPlatformService.retrieveTemplate(savingsAccount.getClientId(),
|
||||||
savingsAccount.getSavingsProductId(), staffInSelectedOfficeOnly);
|
savingsAccount.getGroupId(), savingsAccount.getSavingsProductId(), staffInSelectedOfficeOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SavingsAccountData.withTemplateOptions(savingsAccount, templateData, transactions, charges);
|
return SavingsAccountData.withTemplateOptions(savingsAccount, templateData, transactions, charges);
|
||||||
|
|||||||
+1
-349
@@ -42,23 +42,12 @@ import org.apache.fineract.infrastructure.core.service.Page;
|
|||||||
import org.apache.fineract.infrastructure.core.service.PaginationHelper;
|
import org.apache.fineract.infrastructure.core.service.PaginationHelper;
|
||||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||||
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||||
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
|
||||||
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
|
||||||
import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
|
|
||||||
import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksReadService;
|
|
||||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||||
import org.apache.fineract.organisation.staff.data.StaffData;
|
|
||||||
import org.apache.fineract.organisation.staff.service.StaffReadPlatformService;
|
|
||||||
import org.apache.fineract.portfolio.account.data.AccountTransferData;
|
import org.apache.fineract.portfolio.account.data.AccountTransferData;
|
||||||
import org.apache.fineract.portfolio.charge.data.ChargeData;
|
|
||||||
import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService;
|
|
||||||
import org.apache.fineract.portfolio.charge.util.ConvertChargeDataToSpecificChargeData;
|
|
||||||
import org.apache.fineract.portfolio.client.data.ClientData;
|
import org.apache.fineract.portfolio.client.data.ClientData;
|
||||||
import org.apache.fineract.portfolio.client.service.ClientReadPlatformService;
|
|
||||||
import org.apache.fineract.portfolio.group.data.GroupGeneralData;
|
import org.apache.fineract.portfolio.group.data.GroupGeneralData;
|
||||||
import org.apache.fineract.portfolio.group.service.GroupReadPlatformService;
|
|
||||||
import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData;
|
import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData;
|
||||||
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData;
|
||||||
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
||||||
@@ -91,19 +80,12 @@ import org.springframework.dao.EmptyResultDataAccessException;
|
|||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountReadPlatformService {
|
public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountReadPlatformService {
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
private final ClientReadPlatformService clientReadPlatformService;
|
|
||||||
private final GroupReadPlatformService groupReadPlatformService;
|
|
||||||
private final SavingsProductReadPlatformService savingsProductReadPlatformService;
|
|
||||||
private final StaffReadPlatformService staffReadPlatformService;
|
|
||||||
private final SavingsDropdownReadPlatformService dropdownReadPlatformService;
|
|
||||||
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
private final DatabaseSpecificSQLGenerator sqlGenerator;
|
||||||
private final ChargeReadPlatformService chargeReadPlatformService;
|
|
||||||
|
|
||||||
// mappers
|
// mappers
|
||||||
private final SavingsAccountTransactionTemplateMapper transactionTemplateMapper;
|
private final SavingsAccountTransactionTemplateMapper transactionTemplateMapper;
|
||||||
@@ -116,35 +98,22 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
|||||||
// pagination
|
// pagination
|
||||||
private final PaginationHelper paginationHelper;
|
private final PaginationHelper paginationHelper;
|
||||||
|
|
||||||
private final EntityDatatableChecksReadService entityDatatableChecksReadService;
|
|
||||||
private final ColumnValidator columnValidator;
|
private final ColumnValidator columnValidator;
|
||||||
private final SavingsAccountAssembler savingAccountAssembler;
|
private final SavingsAccountAssembler savingAccountAssembler;
|
||||||
|
|
||||||
private final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper;
|
private final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper;
|
||||||
|
|
||||||
public SavingsAccountReadPlatformServiceImpl(final PlatformSecurityContext context, final JdbcTemplate jdbcTemplate,
|
public SavingsAccountReadPlatformServiceImpl(final PlatformSecurityContext context, final JdbcTemplate jdbcTemplate,
|
||||||
final ClientReadPlatformService clientReadPlatformService, final GroupReadPlatformService groupReadPlatformService,
|
final SavingsAccountAssembler savingAccountAssembler, PaginationHelper paginationHelper, ColumnValidator columnValidator,
|
||||||
final SavingsProductReadPlatformService savingProductReadPlatformService,
|
|
||||||
final StaffReadPlatformService staffReadPlatformService, final SavingsDropdownReadPlatformService dropdownReadPlatformService,
|
|
||||||
final ChargeReadPlatformService chargeReadPlatformService,
|
|
||||||
final EntityDatatableChecksReadService entityDatatableChecksReadService, final ColumnValidator columnValidator,
|
|
||||||
final SavingsAccountAssembler savingAccountAssembler, PaginationHelper paginationHelper,
|
|
||||||
DatabaseSpecificSQLGenerator sqlGenerator, SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper) {
|
DatabaseSpecificSQLGenerator sqlGenerator, SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
this.jdbcTemplate = jdbcTemplate;
|
||||||
this.clientReadPlatformService = clientReadPlatformService;
|
|
||||||
this.groupReadPlatformService = groupReadPlatformService;
|
|
||||||
this.savingsProductReadPlatformService = savingProductReadPlatformService;
|
|
||||||
this.staffReadPlatformService = staffReadPlatformService;
|
|
||||||
this.dropdownReadPlatformService = dropdownReadPlatformService;
|
|
||||||
this.sqlGenerator = sqlGenerator;
|
this.sqlGenerator = sqlGenerator;
|
||||||
this.savingsAccountRepositoryWrapper = savingsAccountRepositoryWrapper;
|
this.savingsAccountRepositoryWrapper = savingsAccountRepositoryWrapper;
|
||||||
this.transactionTemplateMapper = new SavingsAccountTransactionTemplateMapper();
|
this.transactionTemplateMapper = new SavingsAccountTransactionTemplateMapper();
|
||||||
this.transactionsMapper = new SavingsAccountTransactionsMapper();
|
this.transactionsMapper = new SavingsAccountTransactionsMapper();
|
||||||
this.savingsAccountTransactionsForBatchMapper = new SavingsAccountTransactionsForBatchMapper();
|
this.savingsAccountTransactionsForBatchMapper = new SavingsAccountTransactionsForBatchMapper();
|
||||||
this.savingAccountMapper = new SavingAccountMapper();
|
this.savingAccountMapper = new SavingAccountMapper();
|
||||||
this.chargeReadPlatformService = chargeReadPlatformService;
|
|
||||||
this.entityDatatableChecksReadService = entityDatatableChecksReadService;
|
|
||||||
this.columnValidator = columnValidator;
|
this.columnValidator = columnValidator;
|
||||||
this.paginationHelper = paginationHelper;
|
this.paginationHelper = paginationHelper;
|
||||||
this.savingAccountMapperForInterestPosting = new SavingAccountMapperForInterestPosting();
|
this.savingAccountMapperForInterestPosting = new SavingAccountMapperForInterestPosting();
|
||||||
@@ -1033,141 +1002,6 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SavingsAccountData retrieveTemplate(final Long clientId, final Long groupId, final Long productId,
|
|
||||||
final boolean staffInSelectedOfficeOnly) {
|
|
||||||
|
|
||||||
final AppUser loggedInUser = this.context.authenticatedUser();
|
|
||||||
Long officeId = loggedInUser.getOffice().getId();
|
|
||||||
|
|
||||||
ClientData client = null;
|
|
||||||
if (clientId != null) {
|
|
||||||
client = this.clientReadPlatformService.retrieveOne(clientId);
|
|
||||||
officeId = client.getOfficeId();
|
|
||||||
}
|
|
||||||
|
|
||||||
GroupGeneralData group = null;
|
|
||||||
if (groupId != null) {
|
|
||||||
group = this.groupReadPlatformService.retrieveOne(groupId);
|
|
||||||
officeId = group.getOfficeId();
|
|
||||||
}
|
|
||||||
|
|
||||||
final Collection<SavingsProductData> productOptions = this.savingsProductReadPlatformService.retrieveAllForLookup();
|
|
||||||
SavingsAccountData template = null;
|
|
||||||
if (productId != null) {
|
|
||||||
|
|
||||||
final SavingAccountTemplateMapper mapper = new SavingAccountTemplateMapper(client, group);
|
|
||||||
|
|
||||||
final String sql = "select " + mapper.schema() + " where sp.id = ?";
|
|
||||||
template = this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { productId }); // NOSONAR
|
|
||||||
|
|
||||||
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService
|
|
||||||
.retrieveCompoundingInterestPeriodTypeOptions();
|
|
||||||
|
|
||||||
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = this.dropdownReadPlatformService
|
|
||||||
.retrieveInterestPostingPeriodTypeOptions();
|
|
||||||
|
|
||||||
final Collection<EnumOptionData> interestCalculationTypeOptions = this.dropdownReadPlatformService
|
|
||||||
.retrieveInterestCalculationTypeOptions();
|
|
||||||
|
|
||||||
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = this.dropdownReadPlatformService
|
|
||||||
.retrieveInterestCalculationDaysInYearTypeOptions();
|
|
||||||
|
|
||||||
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService
|
|
||||||
.retrieveLockinPeriodFrequencyTypeOptions();
|
|
||||||
|
|
||||||
final Collection<EnumOptionData> withdrawalFeeTypeOptions = this.dropdownReadPlatformService.retrievewithdrawalFeeTypeOptions();
|
|
||||||
|
|
||||||
final Collection<SavingsAccountTransactionData> transactions = null;
|
|
||||||
final Collection<ChargeData> productCharges = this.chargeReadPlatformService.retrieveSavingsProductCharges(productId);
|
|
||||||
// update charges from Product charges
|
|
||||||
final Collection<SavingsAccountChargeData> charges = fromChargesToSavingsCharges(productCharges);
|
|
||||||
|
|
||||||
final boolean feeChargesOnly = false;
|
|
||||||
final Collection<ChargeData> chargeOptions = this.chargeReadPlatformService
|
|
||||||
.retrieveSavingsProductApplicableCharges(feeChargesOnly);
|
|
||||||
|
|
||||||
Collection<StaffData> fieldOfficerOptions = null;
|
|
||||||
|
|
||||||
if (officeId != null) {
|
|
||||||
|
|
||||||
if (staffInSelectedOfficeOnly) {
|
|
||||||
// only bring back loan officers in selected branch/office
|
|
||||||
final Collection<StaffData> fieldOfficersInBranch = this.staffReadPlatformService
|
|
||||||
.retrieveAllLoanOfficersInOfficeById(officeId);
|
|
||||||
|
|
||||||
if (!CollectionUtils.isEmpty(fieldOfficersInBranch)) {
|
|
||||||
fieldOfficerOptions = new ArrayList<>(fieldOfficersInBranch);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// by default bring back all officers in selected
|
|
||||||
// branch/office as well as officers in office above
|
|
||||||
// this office
|
|
||||||
final boolean restrictToLoanOfficersOnly = true;
|
|
||||||
final Collection<StaffData> loanOfficersInHierarchy = this.staffReadPlatformService
|
|
||||||
.retrieveAllStaffInOfficeAndItsParentOfficeHierarchy(officeId, restrictToLoanOfficersOnly);
|
|
||||||
|
|
||||||
if (!CollectionUtils.isEmpty(loanOfficersInHierarchy)) {
|
|
||||||
fieldOfficerOptions = new ArrayList<>(loanOfficersInHierarchy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template = SavingsAccountData.withTemplateOptions(template, productOptions, fieldOfficerOptions,
|
|
||||||
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
|
|
||||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions,
|
|
||||||
charges, chargeOptions);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
String clientName = null;
|
|
||||||
if (client != null) {
|
|
||||||
clientName = client.getDisplayName();
|
|
||||||
}
|
|
||||||
|
|
||||||
String groupName = null;
|
|
||||||
if (group != null) {
|
|
||||||
groupName = group.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
template = SavingsAccountData.withClientTemplate(clientId, clientName, groupId, groupName);
|
|
||||||
|
|
||||||
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 boolean feeChargesOnly = false;
|
|
||||||
final Collection<ChargeData> chargeOptions = this.chargeReadPlatformService
|
|
||||||
.retrieveSavingsProductApplicableCharges(feeChargesOnly);
|
|
||||||
|
|
||||||
template = SavingsAccountData.withTemplateOptions(template, productOptions, fieldOfficerOptions,
|
|
||||||
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
|
|
||||||
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions,
|
|
||||||
charges, chargeOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<DatatableData> datatableTemplates = this.entityDatatableChecksReadService.retrieveTemplates(StatusEnum.CREATE.getValue(),
|
|
||||||
EntityTables.SAVINGS.getName(), productId);
|
|
||||||
template.setDatatables(datatableTemplates);
|
|
||||||
|
|
||||||
return template;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Collection<SavingsAccountChargeData> fromChargesToSavingsCharges(final Collection<ChargeData> productCharges) {
|
|
||||||
final Collection<SavingsAccountChargeData> savingsCharges = new ArrayList<>();
|
|
||||||
for (final ChargeData chargeData : productCharges) {
|
|
||||||
final SavingsAccountChargeData savingsCharge = ConvertChargeDataToSpecificChargeData.toSavingsAccountChargeData(chargeData);
|
|
||||||
savingsCharges.add(savingsCharge);
|
|
||||||
}
|
|
||||||
return savingsCharges;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SavingsAccountTransactionData retrieveDepositTransactionTemplate(final Long savingsId,
|
public SavingsAccountTransactionData retrieveDepositTransactionTemplate(final Long savingsId,
|
||||||
final DepositAccountType depositAccountType) {
|
final DepositAccountType depositAccountType) {
|
||||||
@@ -1402,188 +1236,6 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class SavingAccountTemplateMapper implements RowMapper<SavingsAccountData> {
|
|
||||||
|
|
||||||
private final ClientData client;
|
|
||||||
private final GroupGeneralData group;
|
|
||||||
|
|
||||||
private final String schemaSql;
|
|
||||||
|
|
||||||
SavingAccountTemplateMapper(final ClientData client, final GroupGeneralData group) {
|
|
||||||
this.client = client;
|
|
||||||
this.group = group;
|
|
||||||
|
|
||||||
final StringBuilder sqlBuilder = new StringBuilder(400);
|
|
||||||
sqlBuilder.append("sp.id as productId, sp.name as productName, ");
|
|
||||||
sqlBuilder.append(
|
|
||||||
"sp.currency_code as currencyCode, sp.currency_digits as currencyDigits, sp.currency_multiplesof as inMultiplesOf, ");
|
|
||||||
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
|
||||||
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
|
||||||
sqlBuilder.append("sp.nominal_annual_interest_rate as nominalAnnualIterestRate, ");
|
|
||||||
sqlBuilder.append("sp.interest_compounding_period_enum as interestCompoundingPeriodType, ");
|
|
||||||
sqlBuilder.append("sp.interest_posting_period_enum as interestPostingPeriodType, ");
|
|
||||||
sqlBuilder.append("sp.interest_calculation_type_enum as interestCalculationType, ");
|
|
||||||
sqlBuilder.append("sp.interest_calculation_days_in_year_type_enum as interestCalculationDaysInYearType, ");
|
|
||||||
sqlBuilder.append("sp.min_required_opening_balance as minRequiredOpeningBalance, ");
|
|
||||||
sqlBuilder.append("sp.lockin_period_frequency as lockinPeriodFrequency,");
|
|
||||||
sqlBuilder.append("sp.lockin_period_frequency_enum as lockinPeriodFrequencyType, ");
|
|
||||||
// sqlBuilder.append("sp.withdrawal_fee_amount as
|
|
||||||
// withdrawalFeeAmount,");
|
|
||||||
// sqlBuilder.append("sp.withdrawal_fee_type_enum as
|
|
||||||
// withdrawalFeeTypeEnum, ");
|
|
||||||
sqlBuilder.append("sp.withdrawal_fee_for_transfer as withdrawalFeeForTransfers, ");
|
|
||||||
sqlBuilder.append("sp.min_balance_for_interest_calculation as minBalanceForInterestCalculation, ");
|
|
||||||
sqlBuilder.append("sp.allow_overdraft as allowOverdraft, ");
|
|
||||||
sqlBuilder.append("sp.overdraft_limit as overdraftLimit, ");
|
|
||||||
sqlBuilder.append("sp.nominal_annual_interest_rate_overdraft as nominalAnnualInterestRateOverdraft, ");
|
|
||||||
sqlBuilder.append("sp.min_overdraft_for_interest_calculation as minOverdraftForInterestCalculation, ");
|
|
||||||
sqlBuilder.append("sp.withhold_tax as withHoldTax,");
|
|
||||||
sqlBuilder.append("tg.id as taxGroupId, tg.name as taxGroupName, ");
|
|
||||||
|
|
||||||
// sqlBuilder.append("sp.annual_fee_amount as annualFeeAmount,");
|
|
||||||
// sqlBuilder.append("sp.annual_fee_on_month as annualFeeOnMonth,
|
|
||||||
// ");
|
|
||||||
// sqlBuilder.append("sp.annual_fee_on_day as annualFeeOnDay ");
|
|
||||||
sqlBuilder.append("sp.min_required_balance as minRequiredBalance, ");
|
|
||||||
sqlBuilder.append("sp.enforce_min_required_balance as enforceMinRequiredBalance, ");
|
|
||||||
sqlBuilder.append("sp.max_allowed_lien_limit as maxAllowedLienLimit, ");
|
|
||||||
sqlBuilder.append("sp.is_lien_allowed as lienAllowed ");
|
|
||||||
sqlBuilder.append("from m_savings_product sp ");
|
|
||||||
sqlBuilder.append("join m_currency curr on curr.code = sp.currency_code ");
|
|
||||||
sqlBuilder.append("left join m_tax_group tg on tg.id = sp.tax_group_id ");
|
|
||||||
|
|
||||||
this.schemaSql = sqlBuilder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String schema() {
|
|
||||||
return this.schemaSql;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SavingsAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
|
||||||
|
|
||||||
final Long productId = rs.getLong("productId");
|
|
||||||
final String productName = rs.getString("productName");
|
|
||||||
|
|
||||||
final String currencyCode = rs.getString("currencyCode");
|
|
||||||
final String currencyName = rs.getString("currencyName");
|
|
||||||
final String currencyNameCode = rs.getString("currencyNameCode");
|
|
||||||
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
|
||||||
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
|
|
||||||
final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");
|
|
||||||
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf, currencyDisplaySymbol,
|
|
||||||
currencyNameCode);
|
|
||||||
|
|
||||||
final BigDecimal nominalAnnualIterestRate = rs.getBigDecimal("nominalAnnualIterestRate");
|
|
||||||
|
|
||||||
final EnumOptionData interestCompoundingPeriodType = SavingsEnumerations.compoundingInterestPeriodType(
|
|
||||||
SavingsCompoundingInterestPeriodType.fromInt(JdbcSupport.getInteger(rs, "interestCompoundingPeriodType")));
|
|
||||||
|
|
||||||
final EnumOptionData interestPostingPeriodType = SavingsEnumerations.interestPostingPeriodType(
|
|
||||||
SavingsPostingInterestPeriodType.fromInt(JdbcSupport.getInteger(rs, "interestPostingPeriodType")));
|
|
||||||
|
|
||||||
final EnumOptionData interestCalculationType = SavingsEnumerations
|
|
||||||
.interestCalculationType(SavingsInterestCalculationType.fromInt(JdbcSupport.getInteger(rs, "interestCalculationType")));
|
|
||||||
|
|
||||||
final EnumOptionData interestCalculationDaysInYearType = SavingsEnumerations.interestCalculationDaysInYearType(
|
|
||||||
SavingsInterestCalculationDaysInYearType.fromInt(JdbcSupport.getInteger(rs, "interestCalculationDaysInYearType")));
|
|
||||||
|
|
||||||
final BigDecimal minRequiredOpeningBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "minRequiredOpeningBalance");
|
|
||||||
|
|
||||||
final Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockinPeriodFrequency");
|
|
||||||
EnumOptionData lockinPeriodFrequencyType = null;
|
|
||||||
final Integer lockinPeriodFrequencyTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodFrequencyType");
|
|
||||||
if (lockinPeriodFrequencyTypeValue != null) {
|
|
||||||
final SavingsPeriodFrequencyType lockinPeriodType = SavingsPeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
|
|
||||||
lockinPeriodFrequencyType = SavingsEnumerations.lockinPeriodFrequencyType(lockinPeriodType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// final BigDecimal withdrawalFeeAmount =
|
|
||||||
// rs.getBigDecimal("withdrawalFeeAmount");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* EnumOptionData withdrawalFeeType = null; final Integer withdrawalFeeTypeValue =
|
|
||||||
* JdbcSupport.getInteger(rs, "withdrawalFeeTypeEnum"); if (withdrawalFeeTypeValue != null) {
|
|
||||||
* withdrawalFeeType = SavingsEnumerations.withdrawalFeeType(withdrawalFeeTypeValue); }
|
|
||||||
*/
|
|
||||||
final boolean withdrawalFeeForTransfers = rs.getBoolean("withdrawalFeeForTransfers");
|
|
||||||
|
|
||||||
final boolean allowOverdraft = rs.getBoolean("allowOverdraft");
|
|
||||||
final BigDecimal overdraftLimit = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "overdraftLimit");
|
|
||||||
final BigDecimal nominalAnnualInterestRateOverdraft = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs,
|
|
||||||
"nominalAnnualInterestRateOverdraft");
|
|
||||||
final BigDecimal minOverdraftForInterestCalculation = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs,
|
|
||||||
"minOverdraftForInterestCalculation");
|
|
||||||
|
|
||||||
final BigDecimal minRequiredBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "minRequiredBalance");
|
|
||||||
final boolean enforceMinRequiredBalance = rs.getBoolean("enforceMinRequiredBalance");
|
|
||||||
final BigDecimal maxAllowedLienLimit = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "maxAllowedLienLimit");
|
|
||||||
final boolean lienAllowed = rs.getBoolean("lienAllowed");
|
|
||||||
final BigDecimal minBalanceForInterestCalculation = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs,
|
|
||||||
"minBalanceForInterestCalculation");
|
|
||||||
|
|
||||||
// final BigDecimal annualFeeAmount =
|
|
||||||
// JdbcSupport.getBigDecimalDefaultToNullIfZero(rs,
|
|
||||||
// "annualFeeAmount");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MonthDay annualFeeOnMonthDay = null; final Integer annualFeeOnMonth = JdbcSupport.getInteger(rs,
|
|
||||||
* "annualFeeOnMonth"); final Integer annualFeeOnDay = JdbcSupport.getInteger(rs, "annualFeeOnDay"); if
|
|
||||||
* (annualFeeAmount != null && annualFeeOnDay != null) { annualFeeOnMonthDay = new
|
|
||||||
* MonthDay(annualFeeOnMonth, annualFeeOnDay); }
|
|
||||||
*/
|
|
||||||
|
|
||||||
final boolean withHoldTax = rs.getBoolean("withHoldTax");
|
|
||||||
final Long taxGroupId = JdbcSupport.getLong(rs, "taxGroupId");
|
|
||||||
final String taxGroupName = rs.getString("taxGroupName");
|
|
||||||
TaxGroupData taxGroupData = null;
|
|
||||||
if (taxGroupId != null) {
|
|
||||||
taxGroupData = TaxGroupData.lookup(taxGroupId, taxGroupName);
|
|
||||||
}
|
|
||||||
|
|
||||||
Long clientId = null;
|
|
||||||
String clientName = null;
|
|
||||||
if (this.client != null) {
|
|
||||||
clientId = this.client.getId();
|
|
||||||
clientName = this.client.getDisplayName();
|
|
||||||
}
|
|
||||||
|
|
||||||
Long groupId = null;
|
|
||||||
String groupName = null;
|
|
||||||
if (this.group != null) {
|
|
||||||
groupId = this.group.getId();
|
|
||||||
groupName = this.group.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
final Long fieldOfficerId = null;
|
|
||||||
final String fieldOfficerName = null;
|
|
||||||
final SavingsAccountStatusEnumData status = null;
|
|
||||||
// final LocalDate annualFeeNextDueDate = null;
|
|
||||||
final SavingsAccountSummaryData summary = null;
|
|
||||||
final BigDecimal onHoldFunds = null;
|
|
||||||
final BigDecimal savingsAmountOnHold = null;
|
|
||||||
|
|
||||||
final SavingsAccountSubStatusEnumData subStatus = null;
|
|
||||||
final String reasonForBlock = null;
|
|
||||||
final LocalDate lastActiveTransactionDate = null;
|
|
||||||
final boolean isDormancyTrackingActive = false;
|
|
||||||
final Integer daysToInactive = null;
|
|
||||||
final Integer daysToDormancy = null;
|
|
||||||
final Integer daysToEscheat = null;
|
|
||||||
|
|
||||||
final SavingsAccountApplicationTimelineData timeline = SavingsAccountApplicationTimelineData.templateDefault();
|
|
||||||
final EnumOptionData depositType = null;
|
|
||||||
return SavingsAccountData.instance(null, null, depositType, null, groupId, groupName, clientId, clientName, productId,
|
|
||||||
productName, fieldOfficerId, fieldOfficerName, status, subStatus, reasonForBlock, timeline, currency,
|
|
||||||
nominalAnnualIterestRate, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
|
|
||||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
|
||||||
withdrawalFeeForTransfers, summary, allowOverdraft, overdraftLimit, minRequiredBalance, enforceMinRequiredBalance,
|
|
||||||
maxAllowedLienLimit, lienAllowed, minBalanceForInterestCalculation, onHoldFunds, nominalAnnualInterestRateOverdraft,
|
|
||||||
minOverdraftForInterestCalculation, withHoldTax, taxGroupData, lastActiveTransactionDate, isDormancyTrackingActive,
|
|
||||||
daysToInactive, daysToDormancy, daysToEscheat, savingsAmountOnHold);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<SavingsAccountData> retrieveForLookup(Long clientId, Boolean overdraft) {
|
public Collection<SavingsAccountData> retrieveForLookup(Long clientId, Boolean overdraft) {
|
||||||
|
|
||||||
|
|||||||
+412
@@ -0,0 +1,412 @@
|
|||||||
|
/**
|
||||||
|
* 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.service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
||||||
|
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
|
||||||
|
import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||||
|
import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
|
||||||
|
import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksReadService;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||||
|
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||||
|
import org.apache.fineract.organisation.staff.data.StaffData;
|
||||||
|
import org.apache.fineract.organisation.staff.service.StaffReadPlatformService;
|
||||||
|
import org.apache.fineract.portfolio.charge.data.ChargeData;
|
||||||
|
import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService;
|
||||||
|
import org.apache.fineract.portfolio.charge.util.ConvertChargeDataToSpecificChargeData;
|
||||||
|
import org.apache.fineract.portfolio.client.data.ClientData;
|
||||||
|
import org.apache.fineract.portfolio.client.service.ClientReadPlatformService;
|
||||||
|
import org.apache.fineract.portfolio.group.data.GroupGeneralData;
|
||||||
|
import org.apache.fineract.portfolio.group.service.GroupReadPlatformService;
|
||||||
|
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.SavingsPeriodFrequencyType;
|
||||||
|
import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType;
|
||||||
|
import org.apache.fineract.portfolio.savings.data.SavingsAccountApplicationTimelineData;
|
||||||
|
import org.apache.fineract.portfolio.savings.data.SavingsAccountChargeData;
|
||||||
|
import org.apache.fineract.portfolio.savings.data.SavingsAccountData;
|
||||||
|
import org.apache.fineract.portfolio.savings.data.SavingsAccountStatusEnumData;
|
||||||
|
import org.apache.fineract.portfolio.savings.data.SavingsAccountSubStatusEnumData;
|
||||||
|
import org.apache.fineract.portfolio.savings.data.SavingsAccountSummaryData;
|
||||||
|
import org.apache.fineract.portfolio.savings.data.SavingsAccountTransactionData;
|
||||||
|
import org.apache.fineract.portfolio.savings.data.SavingsProductData;
|
||||||
|
import org.apache.fineract.portfolio.tax.data.TaxGroupData;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
public class SavingsAccountTemplateReadPlatformServiceImpl implements SavingsAccountTemplateReadPlatformService {
|
||||||
|
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
private final ClientReadPlatformService clientReadPlatformService;
|
||||||
|
private final GroupReadPlatformService groupReadPlatformService;
|
||||||
|
private final SavingsProductReadPlatformService savingsProductReadPlatformService;
|
||||||
|
private final StaffReadPlatformService staffReadPlatformService;
|
||||||
|
private final SavingsDropdownReadPlatformService dropdownReadPlatformService;
|
||||||
|
private final ChargeReadPlatformService chargeReadPlatformService;
|
||||||
|
|
||||||
|
private final EntityDatatableChecksReadService entityDatatableChecksReadService;
|
||||||
|
|
||||||
|
public SavingsAccountTemplateReadPlatformServiceImpl(final PlatformSecurityContext context, final JdbcTemplate jdbcTemplate,
|
||||||
|
final ClientReadPlatformService clientReadPlatformService, final GroupReadPlatformService groupReadPlatformService,
|
||||||
|
final SavingsProductReadPlatformService savingProductReadPlatformService,
|
||||||
|
final StaffReadPlatformService staffReadPlatformService, final SavingsDropdownReadPlatformService dropdownReadPlatformService,
|
||||||
|
final ChargeReadPlatformService chargeReadPlatformService,
|
||||||
|
final EntityDatatableChecksReadService entityDatatableChecksReadService, final ColumnValidator columnValidator) {
|
||||||
|
this.context = context;
|
||||||
|
this.jdbcTemplate = jdbcTemplate;
|
||||||
|
this.clientReadPlatformService = clientReadPlatformService;
|
||||||
|
this.groupReadPlatformService = groupReadPlatformService;
|
||||||
|
this.savingsProductReadPlatformService = savingProductReadPlatformService;
|
||||||
|
this.staffReadPlatformService = staffReadPlatformService;
|
||||||
|
this.dropdownReadPlatformService = dropdownReadPlatformService;
|
||||||
|
this.chargeReadPlatformService = chargeReadPlatformService;
|
||||||
|
this.entityDatatableChecksReadService = entityDatatableChecksReadService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SavingsAccountData retrieveTemplate(final Long clientId, final Long groupId, final Long productId,
|
||||||
|
final boolean staffInSelectedOfficeOnly) {
|
||||||
|
|
||||||
|
final AppUser loggedInUser = this.context.authenticatedUser();
|
||||||
|
Long officeId = loggedInUser.getOffice().getId();
|
||||||
|
|
||||||
|
ClientData client = null;
|
||||||
|
if (clientId != null) {
|
||||||
|
client = this.clientReadPlatformService.retrieveOne(clientId);
|
||||||
|
officeId = client.getOfficeId();
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupGeneralData group = null;
|
||||||
|
if (groupId != null) {
|
||||||
|
group = this.groupReadPlatformService.retrieveOne(groupId);
|
||||||
|
officeId = group.getOfficeId();
|
||||||
|
}
|
||||||
|
|
||||||
|
final Collection<SavingsProductData> productOptions = this.savingsProductReadPlatformService.retrieveAllForLookup();
|
||||||
|
SavingsAccountData template = null;
|
||||||
|
if (productId != null) {
|
||||||
|
|
||||||
|
final SavingAccountTemplateMapper mapper = new SavingAccountTemplateMapper(client, group);
|
||||||
|
|
||||||
|
final String sql = "select " + mapper.schema() + " where sp.id = ?";
|
||||||
|
template = this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { productId }); // NOSONAR
|
||||||
|
|
||||||
|
final Collection<EnumOptionData> interestCompoundingPeriodTypeOptions = this.dropdownReadPlatformService
|
||||||
|
.retrieveCompoundingInterestPeriodTypeOptions();
|
||||||
|
|
||||||
|
final Collection<EnumOptionData> interestPostingPeriodTypeOptions = this.dropdownReadPlatformService
|
||||||
|
.retrieveInterestPostingPeriodTypeOptions();
|
||||||
|
|
||||||
|
final Collection<EnumOptionData> interestCalculationTypeOptions = this.dropdownReadPlatformService
|
||||||
|
.retrieveInterestCalculationTypeOptions();
|
||||||
|
|
||||||
|
final Collection<EnumOptionData> interestCalculationDaysInYearTypeOptions = this.dropdownReadPlatformService
|
||||||
|
.retrieveInterestCalculationDaysInYearTypeOptions();
|
||||||
|
|
||||||
|
final Collection<EnumOptionData> lockinPeriodFrequencyTypeOptions = this.dropdownReadPlatformService
|
||||||
|
.retrieveLockinPeriodFrequencyTypeOptions();
|
||||||
|
|
||||||
|
final Collection<EnumOptionData> withdrawalFeeTypeOptions = this.dropdownReadPlatformService.retrievewithdrawalFeeTypeOptions();
|
||||||
|
|
||||||
|
final Collection<SavingsAccountTransactionData> transactions = null;
|
||||||
|
final Collection<ChargeData> productCharges = this.chargeReadPlatformService.retrieveSavingsProductCharges(productId);
|
||||||
|
// update charges from Product charges
|
||||||
|
final Collection<SavingsAccountChargeData> charges = fromChargesToSavingsCharges(productCharges);
|
||||||
|
|
||||||
|
final boolean feeChargesOnly = false;
|
||||||
|
final Collection<ChargeData> chargeOptions = this.chargeReadPlatformService
|
||||||
|
.retrieveSavingsProductApplicableCharges(feeChargesOnly);
|
||||||
|
|
||||||
|
Collection<StaffData> fieldOfficerOptions = null;
|
||||||
|
|
||||||
|
if (officeId != null) {
|
||||||
|
|
||||||
|
if (staffInSelectedOfficeOnly) {
|
||||||
|
// only bring back loan officers in selected branch/office
|
||||||
|
final Collection<StaffData> fieldOfficersInBranch = this.staffReadPlatformService
|
||||||
|
.retrieveAllLoanOfficersInOfficeById(officeId);
|
||||||
|
|
||||||
|
if (!CollectionUtils.isEmpty(fieldOfficersInBranch)) {
|
||||||
|
fieldOfficerOptions = new ArrayList<>(fieldOfficersInBranch);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// by default bring back all officers in selected
|
||||||
|
// branch/office as well as officers in office above
|
||||||
|
// this office
|
||||||
|
final boolean restrictToLoanOfficersOnly = true;
|
||||||
|
final Collection<StaffData> loanOfficersInHierarchy = this.staffReadPlatformService
|
||||||
|
.retrieveAllStaffInOfficeAndItsParentOfficeHierarchy(officeId, restrictToLoanOfficersOnly);
|
||||||
|
|
||||||
|
if (!CollectionUtils.isEmpty(loanOfficersInHierarchy)) {
|
||||||
|
fieldOfficerOptions = new ArrayList<>(loanOfficersInHierarchy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template = SavingsAccountData.withTemplateOptions(template, productOptions, fieldOfficerOptions,
|
||||||
|
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||||
|
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions,
|
||||||
|
charges, chargeOptions);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
String clientName = null;
|
||||||
|
if (client != null) {
|
||||||
|
clientName = client.getDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
String groupName = null;
|
||||||
|
if (group != null) {
|
||||||
|
groupName = group.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
template = SavingsAccountData.withClientTemplate(clientId, clientName, groupId, groupName);
|
||||||
|
|
||||||
|
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 boolean feeChargesOnly = false;
|
||||||
|
final Collection<ChargeData> chargeOptions = this.chargeReadPlatformService
|
||||||
|
.retrieveSavingsProductApplicableCharges(feeChargesOnly);
|
||||||
|
|
||||||
|
template = SavingsAccountData.withTemplateOptions(template, productOptions, fieldOfficerOptions,
|
||||||
|
interestCompoundingPeriodTypeOptions, interestPostingPeriodTypeOptions, interestCalculationTypeOptions,
|
||||||
|
interestCalculationDaysInYearTypeOptions, lockinPeriodFrequencyTypeOptions, withdrawalFeeTypeOptions, transactions,
|
||||||
|
charges, chargeOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<DatatableData> datatableTemplates = this.entityDatatableChecksReadService.retrieveTemplates(StatusEnum.CREATE.getValue(),
|
||||||
|
EntityTables.SAVINGS.getName(), productId);
|
||||||
|
template.setDatatables(datatableTemplates);
|
||||||
|
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class SavingAccountTemplateMapper implements RowMapper<SavingsAccountData> {
|
||||||
|
|
||||||
|
private final ClientData client;
|
||||||
|
private final GroupGeneralData group;
|
||||||
|
|
||||||
|
private final String schemaSql;
|
||||||
|
|
||||||
|
SavingAccountTemplateMapper(final ClientData client, final GroupGeneralData group) {
|
||||||
|
this.client = client;
|
||||||
|
this.group = group;
|
||||||
|
|
||||||
|
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||||
|
sqlBuilder.append("sp.id as productId, sp.name as productName, ");
|
||||||
|
sqlBuilder.append(
|
||||||
|
"sp.currency_code as currencyCode, sp.currency_digits as currencyDigits, sp.currency_multiplesof as inMultiplesOf, ");
|
||||||
|
sqlBuilder.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
|
||||||
|
sqlBuilder.append("curr.display_symbol as currencyDisplaySymbol, ");
|
||||||
|
sqlBuilder.append("sp.nominal_annual_interest_rate as nominalAnnualIterestRate, ");
|
||||||
|
sqlBuilder.append("sp.interest_compounding_period_enum as interestCompoundingPeriodType, ");
|
||||||
|
sqlBuilder.append("sp.interest_posting_period_enum as interestPostingPeriodType, ");
|
||||||
|
sqlBuilder.append("sp.interest_calculation_type_enum as interestCalculationType, ");
|
||||||
|
sqlBuilder.append("sp.interest_calculation_days_in_year_type_enum as interestCalculationDaysInYearType, ");
|
||||||
|
sqlBuilder.append("sp.min_required_opening_balance as minRequiredOpeningBalance, ");
|
||||||
|
sqlBuilder.append("sp.lockin_period_frequency as lockinPeriodFrequency,");
|
||||||
|
sqlBuilder.append("sp.lockin_period_frequency_enum as lockinPeriodFrequencyType, ");
|
||||||
|
// sqlBuilder.append("sp.withdrawal_fee_amount as
|
||||||
|
// withdrawalFeeAmount,");
|
||||||
|
// sqlBuilder.append("sp.withdrawal_fee_type_enum as
|
||||||
|
// withdrawalFeeTypeEnum, ");
|
||||||
|
sqlBuilder.append("sp.withdrawal_fee_for_transfer as withdrawalFeeForTransfers, ");
|
||||||
|
sqlBuilder.append("sp.min_balance_for_interest_calculation as minBalanceForInterestCalculation, ");
|
||||||
|
sqlBuilder.append("sp.allow_overdraft as allowOverdraft, ");
|
||||||
|
sqlBuilder.append("sp.overdraft_limit as overdraftLimit, ");
|
||||||
|
sqlBuilder.append("sp.nominal_annual_interest_rate_overdraft as nominalAnnualInterestRateOverdraft, ");
|
||||||
|
sqlBuilder.append("sp.min_overdraft_for_interest_calculation as minOverdraftForInterestCalculation, ");
|
||||||
|
sqlBuilder.append("sp.withhold_tax as withHoldTax,");
|
||||||
|
sqlBuilder.append("tg.id as taxGroupId, tg.name as taxGroupName, ");
|
||||||
|
|
||||||
|
// sqlBuilder.append("sp.annual_fee_amount as annualFeeAmount,");
|
||||||
|
// sqlBuilder.append("sp.annual_fee_on_month as annualFeeOnMonth,
|
||||||
|
// ");
|
||||||
|
// sqlBuilder.append("sp.annual_fee_on_day as annualFeeOnDay ");
|
||||||
|
sqlBuilder.append("sp.min_required_balance as minRequiredBalance, ");
|
||||||
|
sqlBuilder.append("sp.enforce_min_required_balance as enforceMinRequiredBalance, ");
|
||||||
|
sqlBuilder.append("sp.max_allowed_lien_limit as maxAllowedLienLimit, ");
|
||||||
|
sqlBuilder.append("sp.is_lien_allowed as lienAllowed ");
|
||||||
|
sqlBuilder.append("from m_savings_product sp ");
|
||||||
|
sqlBuilder.append("join m_currency curr on curr.code = sp.currency_code ");
|
||||||
|
sqlBuilder.append("left join m_tax_group tg on tg.id = sp.tax_group_id ");
|
||||||
|
|
||||||
|
this.schemaSql = sqlBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String schema() {
|
||||||
|
return this.schemaSql;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SavingsAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||||
|
|
||||||
|
final Long productId = rs.getLong("productId");
|
||||||
|
final String productName = rs.getString("productName");
|
||||||
|
|
||||||
|
final String currencyCode = rs.getString("currencyCode");
|
||||||
|
final String currencyName = rs.getString("currencyName");
|
||||||
|
final String currencyNameCode = rs.getString("currencyNameCode");
|
||||||
|
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
|
||||||
|
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
|
||||||
|
final Integer inMultiplesOf = JdbcSupport.getInteger(rs, "inMultiplesOf");
|
||||||
|
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf, currencyDisplaySymbol,
|
||||||
|
currencyNameCode);
|
||||||
|
|
||||||
|
final BigDecimal nominalAnnualIterestRate = rs.getBigDecimal("nominalAnnualIterestRate");
|
||||||
|
|
||||||
|
final EnumOptionData interestCompoundingPeriodType = SavingsEnumerations.compoundingInterestPeriodType(
|
||||||
|
SavingsCompoundingInterestPeriodType.fromInt(JdbcSupport.getInteger(rs, "interestCompoundingPeriodType")));
|
||||||
|
|
||||||
|
final EnumOptionData interestPostingPeriodType = SavingsEnumerations.interestPostingPeriodType(
|
||||||
|
SavingsPostingInterestPeriodType.fromInt(JdbcSupport.getInteger(rs, "interestPostingPeriodType")));
|
||||||
|
|
||||||
|
final EnumOptionData interestCalculationType = SavingsEnumerations
|
||||||
|
.interestCalculationType(SavingsInterestCalculationType.fromInt(JdbcSupport.getInteger(rs, "interestCalculationType")));
|
||||||
|
|
||||||
|
final EnumOptionData interestCalculationDaysInYearType = SavingsEnumerations.interestCalculationDaysInYearType(
|
||||||
|
SavingsInterestCalculationDaysInYearType.fromInt(JdbcSupport.getInteger(rs, "interestCalculationDaysInYearType")));
|
||||||
|
|
||||||
|
final BigDecimal minRequiredOpeningBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "minRequiredOpeningBalance");
|
||||||
|
|
||||||
|
final Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockinPeriodFrequency");
|
||||||
|
EnumOptionData lockinPeriodFrequencyType = null;
|
||||||
|
final Integer lockinPeriodFrequencyTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodFrequencyType");
|
||||||
|
if (lockinPeriodFrequencyTypeValue != null) {
|
||||||
|
final SavingsPeriodFrequencyType lockinPeriodType = SavingsPeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue);
|
||||||
|
lockinPeriodFrequencyType = SavingsEnumerations.lockinPeriodFrequencyType(lockinPeriodType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// final BigDecimal withdrawalFeeAmount =
|
||||||
|
// rs.getBigDecimal("withdrawalFeeAmount");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EnumOptionData withdrawalFeeType = null; final Integer withdrawalFeeTypeValue =
|
||||||
|
* JdbcSupport.getInteger(rs, "withdrawalFeeTypeEnum"); if (withdrawalFeeTypeValue != null) {
|
||||||
|
* withdrawalFeeType = SavingsEnumerations.withdrawalFeeType(withdrawalFeeTypeValue); }
|
||||||
|
*/
|
||||||
|
final boolean withdrawalFeeForTransfers = rs.getBoolean("withdrawalFeeForTransfers");
|
||||||
|
|
||||||
|
final boolean allowOverdraft = rs.getBoolean("allowOverdraft");
|
||||||
|
final BigDecimal overdraftLimit = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "overdraftLimit");
|
||||||
|
final BigDecimal nominalAnnualInterestRateOverdraft = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs,
|
||||||
|
"nominalAnnualInterestRateOverdraft");
|
||||||
|
final BigDecimal minOverdraftForInterestCalculation = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs,
|
||||||
|
"minOverdraftForInterestCalculation");
|
||||||
|
|
||||||
|
final BigDecimal minRequiredBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "minRequiredBalance");
|
||||||
|
final boolean enforceMinRequiredBalance = rs.getBoolean("enforceMinRequiredBalance");
|
||||||
|
final BigDecimal maxAllowedLienLimit = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "maxAllowedLienLimit");
|
||||||
|
final boolean lienAllowed = rs.getBoolean("lienAllowed");
|
||||||
|
final BigDecimal minBalanceForInterestCalculation = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs,
|
||||||
|
"minBalanceForInterestCalculation");
|
||||||
|
|
||||||
|
// final BigDecimal annualFeeAmount =
|
||||||
|
// JdbcSupport.getBigDecimalDefaultToNullIfZero(rs,
|
||||||
|
// "annualFeeAmount");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MonthDay annualFeeOnMonthDay = null; final Integer annualFeeOnMonth = JdbcSupport.getInteger(rs,
|
||||||
|
* "annualFeeOnMonth"); final Integer annualFeeOnDay = JdbcSupport.getInteger(rs, "annualFeeOnDay"); if
|
||||||
|
* (annualFeeAmount != null && annualFeeOnDay != null) { annualFeeOnMonthDay = new
|
||||||
|
* MonthDay(annualFeeOnMonth, annualFeeOnDay); }
|
||||||
|
*/
|
||||||
|
|
||||||
|
final boolean withHoldTax = rs.getBoolean("withHoldTax");
|
||||||
|
final Long taxGroupId = JdbcSupport.getLong(rs, "taxGroupId");
|
||||||
|
final String taxGroupName = rs.getString("taxGroupName");
|
||||||
|
TaxGroupData taxGroupData = null;
|
||||||
|
if (taxGroupId != null) {
|
||||||
|
taxGroupData = TaxGroupData.lookup(taxGroupId, taxGroupName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Long clientId = null;
|
||||||
|
String clientName = null;
|
||||||
|
if (this.client != null) {
|
||||||
|
clientId = this.client.getId();
|
||||||
|
clientName = this.client.getDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
Long groupId = null;
|
||||||
|
String groupName = null;
|
||||||
|
if (this.group != null) {
|
||||||
|
groupId = this.group.getId();
|
||||||
|
groupName = this.group.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
final Long fieldOfficerId = null;
|
||||||
|
final String fieldOfficerName = null;
|
||||||
|
final SavingsAccountStatusEnumData status = null;
|
||||||
|
// final LocalDate annualFeeNextDueDate = null;
|
||||||
|
final SavingsAccountSummaryData summary = null;
|
||||||
|
final BigDecimal onHoldFunds = null;
|
||||||
|
final BigDecimal savingsAmountOnHold = null;
|
||||||
|
|
||||||
|
final SavingsAccountSubStatusEnumData subStatus = null;
|
||||||
|
final String reasonForBlock = null;
|
||||||
|
final LocalDate lastActiveTransactionDate = null;
|
||||||
|
final boolean isDormancyTrackingActive = false;
|
||||||
|
final Integer daysToInactive = null;
|
||||||
|
final Integer daysToDormancy = null;
|
||||||
|
final Integer daysToEscheat = null;
|
||||||
|
|
||||||
|
final SavingsAccountApplicationTimelineData timeline = SavingsAccountApplicationTimelineData.templateDefault();
|
||||||
|
final EnumOptionData depositType = null;
|
||||||
|
return SavingsAccountData.instance(null, null, depositType, null, groupId, groupName, clientId, clientName, productId,
|
||||||
|
productName, fieldOfficerId, fieldOfficerName, status, subStatus, reasonForBlock, timeline, currency,
|
||||||
|
nominalAnnualIterestRate, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
|
||||||
|
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
||||||
|
withdrawalFeeForTransfers, summary, allowOverdraft, overdraftLimit, minRequiredBalance, enforceMinRequiredBalance,
|
||||||
|
maxAllowedLienLimit, lienAllowed, minBalanceForInterestCalculation, onHoldFunds, nominalAnnualInterestRateOverdraft,
|
||||||
|
minOverdraftForInterestCalculation, withHoldTax, taxGroupData, lastActiveTransactionDate, isDormancyTrackingActive,
|
||||||
|
daysToInactive, daysToDormancy, daysToEscheat, savingsAmountOnHold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<SavingsAccountChargeData> fromChargesToSavingsCharges(final Collection<ChargeData> productCharges) {
|
||||||
|
final Collection<SavingsAccountChargeData> savingsCharges = new ArrayList<>();
|
||||||
|
for (final ChargeData chargeData : productCharges) {
|
||||||
|
final SavingsAccountChargeData savingsCharge = ConvertChargeDataToSpecificChargeData.toSavingsAccountChargeData(chargeData);
|
||||||
|
savingsCharges.add(savingsCharge);
|
||||||
|
}
|
||||||
|
return savingsCharges;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+17
-8
@@ -124,6 +124,8 @@ import org.apache.fineract.portfolio.savings.service.SavingsAccountInterestPosti
|
|||||||
import org.apache.fineract.portfolio.savings.service.SavingsAccountInterestPostingServiceImpl;
|
import org.apache.fineract.portfolio.savings.service.SavingsAccountInterestPostingServiceImpl;
|
||||||
import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformService;
|
import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformService;
|
||||||
import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformServiceImpl;
|
import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformServiceImpl;
|
||||||
|
import org.apache.fineract.portfolio.savings.service.SavingsAccountTemplateReadPlatformService;
|
||||||
|
import org.apache.fineract.portfolio.savings.service.SavingsAccountTemplateReadPlatformServiceImpl;
|
||||||
import org.apache.fineract.portfolio.savings.service.SavingsAccountWritePlatformService;
|
import org.apache.fineract.portfolio.savings.service.SavingsAccountWritePlatformService;
|
||||||
import org.apache.fineract.portfolio.savings.service.SavingsAccountWritePlatformServiceJpaRepositoryImpl;
|
import org.apache.fineract.portfolio.savings.service.SavingsAccountWritePlatformServiceJpaRepositoryImpl;
|
||||||
import org.apache.fineract.portfolio.savings.service.SavingsApplicationProcessWritePlatformService;
|
import org.apache.fineract.portfolio.savings.service.SavingsApplicationProcessWritePlatformService;
|
||||||
@@ -335,16 +337,23 @@ public class SavingsConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(SavingsAccountReadPlatformService.class)
|
@ConditionalOnMissingBean(SavingsAccountReadPlatformService.class)
|
||||||
public SavingsAccountReadPlatformService savingsAccountReadPlatformService(PlatformSecurityContext context, JdbcTemplate jdbcTemplate,
|
public SavingsAccountReadPlatformService savingsAccountReadPlatformService(PlatformSecurityContext context, JdbcTemplate jdbcTemplate,
|
||||||
ClientReadPlatformService clientReadPlatformService, GroupReadPlatformService groupReadPlatformService,
|
|
||||||
SavingsProductReadPlatformService savingProductReadPlatformService, StaffReadPlatformService staffReadPlatformService,
|
|
||||||
SavingsDropdownReadPlatformService dropdownReadPlatformService, ChargeReadPlatformService chargeReadPlatformService,
|
|
||||||
EntityDatatableChecksReadService entityDatatableChecksReadService, ColumnValidator columnValidator,
|
|
||||||
SavingsAccountAssembler savingAccountAssembler, PaginationHelper paginationHelper, DatabaseSpecificSQLGenerator sqlGenerator,
|
SavingsAccountAssembler savingAccountAssembler, PaginationHelper paginationHelper, DatabaseSpecificSQLGenerator sqlGenerator,
|
||||||
SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper) {
|
SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper, ColumnValidator columnValidator) {
|
||||||
return new SavingsAccountReadPlatformServiceImpl(context, jdbcTemplate, clientReadPlatformService, groupReadPlatformService,
|
return new SavingsAccountReadPlatformServiceImpl(context, jdbcTemplate, savingAccountAssembler, paginationHelper, columnValidator,
|
||||||
|
sqlGenerator, savingsAccountRepositoryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(SavingsAccountTemplateReadPlatformService.class)
|
||||||
|
public SavingsAccountTemplateReadPlatformService savingsAccountTemplateReadPlatformService(PlatformSecurityContext context,
|
||||||
|
JdbcTemplate jdbcTemplate, ClientReadPlatformService clientReadPlatformService,
|
||||||
|
GroupReadPlatformService groupReadPlatformService, SavingsProductReadPlatformService savingProductReadPlatformService,
|
||||||
|
StaffReadPlatformService staffReadPlatformService, SavingsDropdownReadPlatformService dropdownReadPlatformService,
|
||||||
|
ChargeReadPlatformService chargeReadPlatformService, EntityDatatableChecksReadService entityDatatableChecksReadService,
|
||||||
|
ColumnValidator columnValidator) {
|
||||||
|
return new SavingsAccountTemplateReadPlatformServiceImpl(context, jdbcTemplate, clientReadPlatformService, groupReadPlatformService,
|
||||||
savingProductReadPlatformService, staffReadPlatformService, dropdownReadPlatformService, chargeReadPlatformService,
|
savingProductReadPlatformService, staffReadPlatformService, dropdownReadPlatformService, chargeReadPlatformService,
|
||||||
entityDatatableChecksReadService, columnValidator, savingAccountAssembler, paginationHelper, sqlGenerator,
|
entityDatatableChecksReadService, columnValidator);
|
||||||
savingsAccountRepositoryWrapper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
+207
@@ -0,0 +1,207 @@
|
|||||||
|
/**
|
||||||
|
* 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 static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
|
import org.apache.fineract.infrastructure.codes.service.CodeReadPlatformService;
|
||||||
|
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||||
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.ActionContext;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
|
||||||
|
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenantConnection;
|
||||||
|
import org.apache.fineract.infrastructure.core.serialization.DatatableCommandFromApiJsonDeserializer;
|
||||||
|
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
|
||||||
|
import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
|
||||||
|
import org.apache.fineract.infrastructure.dataqueries.data.DataTableValidator;
|
||||||
|
import org.apache.fineract.infrastructure.dataqueries.data.ResultsetRowData;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.domain.datatable.DatatableEntryBusinessEvent;
|
||||||
|
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||||
|
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||||
|
import org.apache.fineract.infrastructure.security.utils.DefaultSqlValidator;
|
||||||
|
import org.apache.fineract.organisation.office.domain.Office;
|
||||||
|
import org.apache.fineract.portfolio.search.service.SearchUtil;
|
||||||
|
import org.apache.fineract.useradministration.domain.AppUser;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.jdbc.core.PreparedStatementCreator;
|
||||||
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||||
|
import org.springframework.jdbc.support.KeyHolder;
|
||||||
|
import org.springframework.jdbc.support.rowset.SqlRowSet;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class DatatableBusinessEventTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private PlatformSecurityContext context;
|
||||||
|
@Mock
|
||||||
|
private BusinessEventNotifierService businessEventNotifierService;
|
||||||
|
@Mock
|
||||||
|
private JdbcTemplate jdbcTemplate;
|
||||||
|
@Mock
|
||||||
|
private GenericDataService genericDataService;
|
||||||
|
@Mock
|
||||||
|
private SearchUtil searchUtil;
|
||||||
|
@Mock
|
||||||
|
private DatabaseTypeResolver databaseTypeResolver;
|
||||||
|
@Mock
|
||||||
|
private DatabaseSpecificSQLGenerator sqlGenerator;
|
||||||
|
@Mock
|
||||||
|
private FineractPlatformTenantConnection tenantConnection;
|
||||||
|
@Mock
|
||||||
|
private DefaultSqlValidator sqlValidator;
|
||||||
|
@Mock
|
||||||
|
private FromJsonHelper fromJsonHelper;
|
||||||
|
@Mock
|
||||||
|
private DatatableCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||||
|
@Mock
|
||||||
|
private ConfigurationDomainService configurationDomainService;
|
||||||
|
@Mock
|
||||||
|
private CodeReadPlatformService codeReadPlatformService;
|
||||||
|
@Mock
|
||||||
|
private DataTableValidator dataTableValidator;
|
||||||
|
@Mock
|
||||||
|
private ColumnValidator columnValidator;
|
||||||
|
@Mock
|
||||||
|
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
||||||
|
@Mock
|
||||||
|
private DatatableKeywordGenerator datatableKeywordGenerator;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private ReadWriteNonCoreDataServiceImpl underTest;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor;
|
||||||
|
|
||||||
|
private static String DATATABLE_NAME = "test_loan_data";
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null));
|
||||||
|
ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT);
|
||||||
|
ThreadLocalContextUtil.setBusinessDates(new HashMap<>(Map.of(BusinessDateType.BUSINESS_DATE, LocalDate.parse("2024-01-16"),
|
||||||
|
BusinessDateType.COB_DATE, LocalDate.parse("2024-01-15"))));
|
||||||
|
|
||||||
|
SqlRowSet sqlRS = Mockito.mock(SqlRowSet.class);
|
||||||
|
SqlRowSet sqlRSData = Mockito.mock(SqlRowSet.class);
|
||||||
|
doNothing().when(sqlValidator).validate(anyString());
|
||||||
|
when(jdbcTemplate.queryForRowSet(anyString(), anyString())).thenReturn(sqlRS);
|
||||||
|
when(jdbcTemplate.queryForRowSet(anyString())).thenReturn(sqlRSData);
|
||||||
|
|
||||||
|
when(sqlRS.next()).thenReturn(true).thenReturn(false);
|
||||||
|
when(sqlRS.getString("application_table_name")).thenReturn("m_loan");
|
||||||
|
when(sqlRSData.next()).thenReturn(true).thenReturn(false);
|
||||||
|
when(sqlRSData.getObject(anyString())).thenReturn(1L);
|
||||||
|
|
||||||
|
AppUser currentUser = Mockito.mock(AppUser.class);
|
||||||
|
Office office = Mockito.mock(Office.class);
|
||||||
|
when(context.authenticatedUser()).thenReturn(currentUser);
|
||||||
|
when(currentUser.getOffice()).thenReturn(office);
|
||||||
|
when(office.getHierarchy()).thenReturn(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void tearDown() {
|
||||||
|
ThreadLocalContextUtil.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void businessEventCreateNewDatatableEntryTest() {
|
||||||
|
when(jdbcTemplate.update(any(PreparedStatementCreator.class), any(KeyHolder.class))).thenReturn(1);
|
||||||
|
|
||||||
|
underTest.createNewDatatableEntry(DATATABLE_NAME, 1L, createJsonCommand("{}", 1L));
|
||||||
|
|
||||||
|
ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor = verifyBusinessEvents(1);
|
||||||
|
verifyDatatableBusinessEvent(businessEventArgumentCaptor, 0, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void businessEventUpdateDatatableEntryTest() {
|
||||||
|
List<Object> values = new ArrayList<>();
|
||||||
|
values.add(1L);
|
||||||
|
List<ResultsetRowData> result = new ArrayList<>();
|
||||||
|
result.add(ResultsetRowData.create(values));
|
||||||
|
when(genericDataService.fillResultsetRowData(anyString(), any())).thenReturn(result);
|
||||||
|
|
||||||
|
// ResultsetColumnHeaderData resultSet = Mockito.mock(ResultsetColumnHeaderData.class);
|
||||||
|
// when(searchUtil.getFiltered(columnHeaders,
|
||||||
|
// ResultsetColumnHeaderData::getIsColumnPrimaryKey)).thenReturn(resultSet);
|
||||||
|
|
||||||
|
underTest.updateDatatableEntryOneToMany(DATATABLE_NAME, 1L, 1L, createJsonCommand("{}", 1L));
|
||||||
|
|
||||||
|
ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor = verifyBusinessEvents(1);
|
||||||
|
verifyDatatableBusinessEvent(businessEventArgumentCaptor, 0, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void businessEventDeleteDatatableEntryTest() {
|
||||||
|
|
||||||
|
underTest.deleteDatatableEntry(DATATABLE_NAME, 1L, 1L, createJsonCommand("{}", 1L));
|
||||||
|
|
||||||
|
ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor = verifyBusinessEvents(1);
|
||||||
|
verifyDatatableBusinessEvent(businessEventArgumentCaptor, 0, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private ArgumentCaptor<BusinessEvent<?>> verifyBusinessEvents(int expectedBusinessEvents) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor = ArgumentCaptor.forClass(BusinessEvent.class);
|
||||||
|
verify(businessEventNotifierService, times(expectedBusinessEvents)).notifyPostBusinessEvent(businessEventArgumentCaptor.capture());
|
||||||
|
return businessEventArgumentCaptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyDatatableBusinessEvent(ArgumentCaptor<BusinessEvent<?>> businessEventArgumentCaptor, int index, Long entityId) {
|
||||||
|
assertTrue(businessEventArgumentCaptor.getAllValues().get(index) instanceof DatatableEntryBusinessEvent);
|
||||||
|
assertEquals(DATATABLE_NAME, ((DatatableEntryBusinessEvent) businessEventArgumentCaptor.getAllValues().get(index))
|
||||||
|
.getDatatableEntryDetails().getDatatableName());
|
||||||
|
assertEquals(entityId, ((DatatableEntryBusinessEvent) businessEventArgumentCaptor.getAllValues().get(index)).getAggregateRootId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonCommand createJsonCommand(final String jsonCommand, final Long resourceId) {
|
||||||
|
return new JsonCommand(null, jsonCommand, null, null, null, resourceId, null, null, null, null, null, null, null, null, null, null,
|
||||||
|
null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
-2
@@ -40,8 +40,6 @@ public interface SavingsAccountReadPlatformService {
|
|||||||
|
|
||||||
SavingsAccountData retrieveOne(Long savingsId);
|
SavingsAccountData retrieveOne(Long savingsId);
|
||||||
|
|
||||||
SavingsAccountData retrieveTemplate(Long clientId, Long groupId, Long productId, boolean staffInSelectedOfficeOnly);
|
|
||||||
|
|
||||||
SavingsAccountTransactionData retrieveDepositTransactionTemplate(Long savingsId, DepositAccountType depositAccountType);
|
SavingsAccountTransactionData retrieveDepositTransactionTemplate(Long savingsId, DepositAccountType depositAccountType);
|
||||||
|
|
||||||
Collection<SavingsAccountTransactionData> retrieveAllTransactions(Long savingsId, DepositAccountType depositAccountType);
|
Collection<SavingsAccountTransactionData> retrieveAllTransactions(Long savingsId, DepositAccountType depositAccountType);
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* 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.service;
|
||||||
|
|
||||||
|
import org.apache.fineract.portfolio.savings.data.SavingsAccountData;
|
||||||
|
|
||||||
|
public interface SavingsAccountTemplateReadPlatformService {
|
||||||
|
|
||||||
|
SavingsAccountData retrieveTemplate(Long clientId, Long groupId, Long productId, boolean staffInSelectedOfficeOnly);
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user