balance-api-collection-init
diff --git a/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/EventConstants.java b/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/EventConstants.java
index 1f70ac1..5bd1063 100644
--- a/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/EventConstants.java
+++ b/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/EventConstants.java
@@ -63,4 +63,5 @@
String SELECTOR_INTEREST_ACCRUED = SELECTOR_NAME + " = '" + INTEREST_ACCRUED + "'";
String INTEREST_PAYED = "interest-payed";
String SELECTOR_INTEREST_PAYED = SELECTOR_NAME + " = '" + INTEREST_PAYED + "'";
+ String CALCULATE_IBB = "calculate-ibb";
}
diff --git a/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/transaction/domain/data/BalanceResponse.java b/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/transaction/domain/data/BalanceResponse.java
new file mode 100644
index 0000000..41a42fb
--- /dev/null
+++ b/api/src/main/java/org/apache/fineract/cn/deposit/api/v1/transaction/domain/data/BalanceResponse.java
@@ -0,0 +1,44 @@
+/*
+ * 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.cn.deposit.api.v1.transaction.domain.data;
+
+import java.math.BigDecimal;
+
+public class BalanceResponse {
+ private BigDecimal balance;
+ private BigDecimal interest;
+
+ public BalanceResponse() {
+ }
+
+ public BigDecimal getBalance() {
+ return balance;
+ }
+
+ public void setBalance(BigDecimal balance) {
+ this.balance = balance;
+ }
+
+ public BigDecimal getInterest() {
+ return interest;
+ }
+
+ public void setInterest(BigDecimal interest) {
+ this.interest = interest;
+ }
+}
diff --git a/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/command/CalculateIBBCommand.java b/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/command/CalculateIBBCommand.java
new file mode 100644
index 0000000..c6751ed
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/command/CalculateIBBCommand.java
@@ -0,0 +1,33 @@
+/*
+ * 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.cn.deposit.service.internal.command;
+
+import java.time.LocalDate;
+
+public class CalculateIBBCommand {
+ private final LocalDate dueDate;
+
+ public CalculateIBBCommand(final LocalDate dueDate) {
+ super();
+ this.dueDate = dueDate;
+ }
+
+ public LocalDate dueDate() {
+ return this.dueDate;
+ }
+}
diff --git a/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/command/handler/InterestBearingBalanceCalculator.java b/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/command/handler/InterestBearingBalanceCalculator.java
new file mode 100644
index 0000000..9d5647b
--- /dev/null
+++ b/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/command/handler/InterestBearingBalanceCalculator.java
@@ -0,0 +1,131 @@
+/*
+ * 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.cn.deposit.service.internal.command.handler;
+
+import org.apache.fineract.cn.command.annotation.Aggregate;
+import org.apache.fineract.cn.command.annotation.CommandHandler;
+import org.apache.fineract.cn.command.annotation.CommandLogLevel;
+import org.apache.fineract.cn.command.annotation.EventEmitter;
+import org.apache.fineract.cn.deposit.api.v1.EventConstants;
+import org.apache.fineract.cn.deposit.api.v1.domain.Type;
+import org.apache.fineract.cn.deposit.service.internal.command.CalculateIBBCommand;
+import org.apache.fineract.cn.deposit.service.internal.repository.*;
+import org.apache.fineract.cn.deposit.service.internal.service.TransactionService;
+import org.apache.fineract.cn.lang.DateConverter;
+
+import javax.transaction.Transactional;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Optional;
+
+@Aggregate
+public class InterestBearingBalanceCalculator {
+
+ private static final String ACTIVE = "ACTIVE";
+
+ private ProductDefinitionRepository productDefinitionRepository;
+ private ProductInstanceRepository productInstanceRepository;
+ private TransactionRepository transactionRepository;
+ private SubTransactionTypeRepository subTransactionTypeRepository;
+
+ //TODO: constructor
+
+ @Transactional
+ @CommandHandler(logStart = CommandLogLevel.DEBUG, logFinish = CommandLogLevel.DEBUG)
+ @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.CALCULATE_IBB)
+ public String process(final CalculateIBBCommand calculateIBBCommand) {
+ final LocalDate dueDate = calculateIBBCommand.dueDate();
+ //calculate and store ibb for the date-1day
+ final List<ProductDefinitionEntity> productDefinitions = this.productDefinitionRepository.findAll();
+
+ productDefinitions.forEach(productDefinitionEntity -> {
+ if (this.canFindIBBForProduct(productDefinitionEntity)) {
+ final List<ProductInstanceEntity> productInstances =
+ this.productInstanceRepository.findByProductDefinition(productDefinitionEntity);
+
+ productInstances.forEach(productInstanceEntity -> {
+ if (productInstanceEntity.getState().equals(ACTIVE)) {
+ //get transactions
+ List<TransactionEntity> transactions = transactionRepository.findByAccountId(productInstanceEntity.getAccountIdentifier());
+ if(!transactions.isEmpty())
+ calculateAndSaveIBB(productInstanceEntity, transactions, dueDate);
+ }
+ });
+ }
+ });
+
+ return DateConverter.toIsoString(dueDate);
+ }
+
+ private void calculateAndSaveIBB(ProductInstanceEntity productInstanceEntity, List<TransactionEntity> transactions,
+ LocalDate dueDate) {
+ BigDecimal ibBalance = BigDecimal.ZERO;
+ for(TransactionEntity transaction: transactions){
+ SubTransactionTypeEntity subTransactionTypeEntity = getSubTxnTypeEntityFromTxn(transaction);
+ if(subTransactionTypeEntity!= null && (subTransactionTypeEntity.getIbbConfPlusDays() != 0
+ || subTransactionTypeEntity.getIbbConfMinusDays() !=0)) {
+
+ if(TransactionService.CREDIT.equals(transaction.getType()) &&
+ isTxnDateOnOrAfterTodayPlusX(dueDate, transaction.getTransactionDate().toLocalDate(),
+ subTransactionTypeEntity.getIbbConfPlusDays())){
+ //add credit after checking day passed condition: Deposit Value Date - T+x
+ ibBalance = ibBalance.add(transaction.getAmount());
+
+ }else if(TransactionService.DEBIT.equals(transaction.getType())&&
+ isTxnDateOnOrBeforeTodayMinusY(dueDate, transaction.getTransactionDate().toLocalDate(),
+ subTransactionTypeEntity.getIbbConfMinusDays())){
+ //subtract debit after checking day condition: Withdrawal Value Date - T-y
+ ibBalance = ibBalance.subtract(transaction.getAmount());
+ }
+ //else ignore
+ }else if(TransactionService.CREDIT.equals(transaction.getType())){
+ //add credit
+ ibBalance = ibBalance.add(transaction.getAmount());
+
+ }else if(TransactionService.DEBIT.equals(transaction.getType())) {
+ //subtract debit
+ ibBalance = ibBalance.subtract(transaction.getAmount());
+ }
+ }
+ }
+
+ private SubTransactionTypeEntity getSubTxnTypeEntityFromTxn(TransactionEntity transaction){
+ if(transaction.getSubTxnType() == null) return null;
+ Optional<SubTransactionTypeEntity> optsubTxn = subTransactionTypeRepository.findByIdentifier(transaction.getSubTxnType());
+ return (optsubTxn.isPresent() ? optsubTxn.get(): null);
+ }
+
+ private boolean canFindIBBForProduct(final ProductDefinitionEntity productDefinitionEntity) {
+ return productDefinitionEntity.getActive()
+ && !productDefinitionEntity.getType().equals(Type.SHARE.name())
+ && productDefinitionEntity.getInterest() != null
+ && productDefinitionEntity.getInterest() > 0.00D;
+ }
+
+ private boolean isTxnDateOnOrAfterTodayPlusX(LocalDate today, LocalDate txnDate, int x){
+
+ return false;
+ }
+
+ private boolean isTxnDateOnOrBeforeTodayMinusY(LocalDate today, LocalDate txnDate, int y){
+ return false;
+ }
+
+}
diff --git a/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/repository/SubTransactionTypeEntity.java b/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/repository/SubTransactionTypeEntity.java
index ba9e525..a245543 100644
--- a/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/repository/SubTransactionTypeEntity.java
+++ b/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/repository/SubTransactionTypeEntity.java
@@ -52,6 +52,12 @@
@Column(name = "ledger_account_identifier", nullable = false)
private String ledgerAccount;
+ @Column(name = "ibb_conf_plus_days")
+ private Integer ibbConfPlusDays;
+
+ @Column(name = "ibb_conf_minus_days")
+ private Integer ibbConfMinusDays;
+
public SubTransactionTypeEntity() {
super();
}
@@ -127,4 +133,20 @@
public void setLedgerAccount(String ledgerAccount) {
this.ledgerAccount = ledgerAccount;
}
+
+ public Integer getIbbConfPlusDays() {
+ return ibbConfPlusDays;
+ }
+
+ public void setIbbConfPlusDays(Integer ibbConfPlusDays) {
+ this.ibbConfPlusDays = ibbConfPlusDays;
+ }
+
+ public Integer getIbbConfMinusDays() {
+ return ibbConfMinusDays;
+ }
+
+ public void setIbbConfMinusDays(Integer ibbConfMinusDays) {
+ this.ibbConfMinusDays = ibbConfMinusDays;
+ }
}
diff --git a/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/service/TransactionService.java b/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/service/TransactionService.java
index df96b58..03f989f 100644
--- a/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/service/TransactionService.java
+++ b/service/src/main/java/org/apache/fineract/cn/deposit/service/internal/service/TransactionService.java
@@ -432,6 +432,14 @@
return statementObj;
}).collect(Collectors.toList());
}
+
+ public BalanceResponse fetchBalance(String identifier) {
+ Account account = ledgerManager.findAccount(identifier);
+ BalanceResponse balance = new BalanceResponse();
+ balance.setBalance(new BigDecimal(account.getBalance()));
+ balance.setInterest(BigDecimal.ZERO);
+ return balance;
+ }
public static class AccountWrapper {
diff --git a/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/BeatListenerRestController.java b/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/BeatListenerRestController.java
index 32d017f..f5461f1 100644
--- a/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/BeatListenerRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/BeatListenerRestController.java
@@ -65,5 +65,6 @@
{
this.commandGateway.process(new BeatListenerCommand(beatPublish));
return ResponseEntity.accepted().build();
+
}
}
diff --git a/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/ProductInstanceRestController.java b/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/ProductInstanceRestController.java
index aece9a3..f0cc9fb 100644
--- a/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/ProductInstanceRestController.java
+++ b/service/src/main/java/org/apache/fineract/cn/deposit/service/rest/ProductInstanceRestController.java
@@ -25,10 +25,22 @@
import org.apache.fineract.cn.deposit.api.v1.PermittableGroupIds;
import org.apache.fineract.cn.deposit.api.v1.instance.domain.AvailableTransactionType;
import org.apache.fineract.cn.deposit.api.v1.instance.domain.ProductInstance;
+import org.apache.fineract.cn.deposit.api.v1.transaction.domain.data.BalanceResponse;
import org.apache.fineract.cn.deposit.api.v1.transaction.domain.data.StatementResponse;
import org.apache.fineract.cn.deposit.service.ServiceConstants;
import org.apache.fineract.cn.deposit.service.internal.command.*;
import org.apache.fineract.cn.deposit.service.internal.service.ProductInstanceService;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.validation.Valid;
+import org.apache.fineract.cn.anubis.annotation.AcceptedTokenType;
+import org.apache.fineract.cn.anubis.annotation.Permittable;
+import org.apache.fineract.cn.command.gateway.CommandGateway;
import org.apache.fineract.cn.deposit.service.internal.service.TransactionService;
import org.apache.fineract.cn.lang.ServiceException;
import org.slf4j.Logger;
@@ -222,6 +234,18 @@
return ResponseEntity.ok(statement);
}
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.INSTANCE_MANAGEMENT)
+ @RequestMapping(
+ value = "/{identifier}/balance",
+ method = RequestMethod.GET,
+ consumes = MediaType.ALL_VALUE,
+ produces = MediaType.APPLICATION_JSON_VALUE
+ )
+ @ResponseBody
+ ResponseEntity<BalanceResponse> balance(@PathVariable("identifier") final String identifier) {
+ return ResponseEntity.ok(transactionService.fetchBalance(identifier));
+ }
+
private LocalDateTime convertToLocalDateTime(Date dateToConvert) {
return dateToConvert.toInstant()
.atZone(ZoneId.systemDefault())
diff --git a/service/src/main/resources/db/migrations/postgresql/V10__ibb_conf_to_sub_txn.sql b/service/src/main/resources/db/migrations/postgresql/V10__ibb_conf_to_sub_txn.sql
new file mode 100644
index 0000000..1abb9af
--- /dev/null
+++ b/service/src/main/resources/db/migrations/postgresql/V10__ibb_conf_to_sub_txn.sql
@@ -0,0 +1,24 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License. You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied. See the License for the
+-- specific language governing permissions and limitations
+-- under the License.
+--
+
+ALTER TABLE shed_sub_tx_type
+ADD COLUMN ibb_conf_plus_days INT 0;
+
+ALTER TABLE shed_sub_tx_type
+ADD COLUMN ibb_conf_minus_days INT 0;
diff --git a/service/src/main/resources/db/migrations/postgresql/V11__collections.sql b/service/src/main/resources/db/migrations/postgresql/V11__collections.sql
new file mode 100644
index 0000000..43f951d
--- /dev/null
+++ b/service/src/main/resources/db/migrations/postgresql/V11__collections.sql
@@ -0,0 +1,67 @@
+--
+-- 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.
+--
+
+
+CREATE TABLE shed_collections (
+ id bigserial NOT null,
+ transaction_date TIMESTAMP NULL,
+ amount numeric(15,5) NOT NULL,
+ transport_fee_amount numeric(15,5) NULL,
+ currency VARCHAR(10) NULL,
+ remarks VARCHAR(1024) NULL,
+ account_identifier BIGINT NULL,
+ sub_txn_type_id BIGINT NULL,
+ status VARCHAR(20) NOT NULL,
+ c_reference VARCHAR(36) NOT NULL,
+ created_by VARCHAR(32) NOT NULL,
+ created_on TIMESTAMP NOT NULL,
+ last_modified_by VARCHAR(32) NULL,
+ last_modified_on TIMESTAMP NULL,
+ CONSTRAINT pk_shed_collections PRIMARY KEY (id),
+ CONSTRAINT uk_shed_collections_ref UNIQUE (c_reference),
+ CONSTRAINT fk_collection_sub_txn_type_id FOREIGN KEY (sub_txn_type_id) REFERENCES shed_sub_tx_type (id),
+ CONSTRAINT fk_collection_account_identifier FOREIGN KEY (account_identifier) REFERENCES shed_product_instances (account_identifier)
+);
+
+
+CREATE TABLE shed_collections_inidividual (
+ id bigserial NOT NULL,
+ collections_id BIGINT NOT NULL,
+ account_identifier BIGINT NULL,
+ account_external_id VARCHAR(64) NULL,
+ amount numeric(15,5) NOT NULL,
+ i_reference VARCHAR(36) NOT NULL,
+ CONSTRAINT pk_shed_collections_inidividual PRIMARY KEY (id),
+ CONSTRAINT uk_shed_collections_inidividual_ref UNIQUE (i_reference),
+ CONSTRAINT fk_indidual_collections FOREIGN KEY (collections_id) REFERENCES shed_collections (id),
+ CONSTRAINT fk_ind_collections_account_identifier FOREIGN KEY (account_identifier) REFERENCES shed_product_instances (account_identifier)
+);
+
+
+
+CREATE TABLE shed_self_expiring_tokens (
+ id bigserial NOT NULL,
+ token VARCHAR(10) NOT NULL,
+ token_expires_by TIMESTAMP NOT NULL,
+ status VARCHAR(10) NOT NULL,
+ entity_type VARCHAR(36) NOT NULL,
+ entity_reference VARCHAR(36) NOT NULL,
+ CONSTRAINT pk_shed_self_expiring_tokens PRIMARY KEY (id),
+ CONSTRAINT uk_shed_self_expiring_tokens_token UNIQUE (token, status)
+);
diff --git a/service/src/main/resources/db/migrations/postgresql/V8__transaction.sql b/service/src/main/resources/db/migrations/postgresql/V8__transaction.sql
index 9acf61e..8fba6c2 100644
--- a/service/src/main/resources/db/migrations/postgresql/V8__transaction.sql
+++ b/service/src/main/resources/db/migrations/postgresql/V8__transaction.sql
@@ -43,4 +43,4 @@
CONSTRAINT uk_shed_transactions_id UNIQUE (identifier),
CONSTRAINT shed_txn_sub_txn_type_fk FOREIGN KEY (sub_txn_type) REFERENCES shed_sub_tx_type (identifier),
CONSTRAINT shed_txn_prod_instance_fk FOREIGN KEY (account_identifier) REFERENCES shed_product_instances (account_identifier)
-);
\ No newline at end of file
+);
diff --git a/service/src/main/resources/db/migrations/postgresql/V9__transaction_update.sql b/service/src/main/resources/db/migrations/postgresql/V9__transaction_update.sql
index 450715a..07bfe2e 100644
--- a/service/src/main/resources/db/migrations/postgresql/V9__transaction_update.sql
+++ b/service/src/main/resources/db/migrations/postgresql/V9__transaction_update.sql
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
@@ -23,8 +24,7 @@
ALTER TABLE shed_transactions
ADD COLUMN parent_txn_id bigint NULL;
-
ALTER TABLE shed_transactions
ADD CONSTRAINT shed_txn_to_txn_fk
FOREIGN KEY (parent_txn_id)
-REFERENCES shed_transactions (id);
\ No newline at end of file
+REFERENCES shed_transactions (id);