From 7ae9b67d930c50b736d995910c4b8f3184569db7 Mon Sep 17 00:00:00 2001 From: Nazeer Hussain Shaik Date: Tue, 17 May 2016 12:34:22 +0530 Subject: [PATCH] Shares Integration Tests and Fixes --- .../common/charges/ChargesHelper.java | 67 +- .../shares/DividendsIntegrationTests.java | 203 ++++ .../common/shares/ShareAccountHelper.java | 144 +++ .../shares/ShareAccountIntegrationTests.java | 1032 +++++++++++++++++ .../shares/ShareAccountTransactionHelper.java | 55 + .../ShareDividendsTransactionHelper.java | 58 + .../common/shares/ShareProductHelper.java | 199 ++++ .../shares/ShareProductTransactionHelper.java | 51 + .../accounts/api/AccountsApiResource.java | 56 +- .../service/AccountReadPlatformService.java | 4 +- .../fineract/portfolio/note/domain/Note.java | 17 + .../portfolio/note/domain/NoteType.java | 5 +- .../products/api/ProductsApiResource.java | 61 +- .../exception/ResourceNotFoundException.java | 33 + .../shareaccounts/domain/ShareAccount.java | 29 +- .../domain/ShareAccountTransaction.java | 4 + .../ShareAccountDataSerializer.java | 108 +- .../ShareAccountReadPlatformServiceImpl.java | 49 +- ...WritePlatformServiceJpaRepositoryImpl.java | 34 +- .../service/SharesEnumerations.java | 33 +- .../ShareProductDataSerializer.java | 3 +- .../ShareProductReadPlatformServiceImpl.java | 19 +- .../core_db/V307__add_share_notes.sql | 2 + 23 files changed, 2136 insertions(+), 130 deletions(-) create mode 100644 fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/DividendsIntegrationTests.java create mode 100644 fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountHelper.java create mode 100644 fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountIntegrationTests.java create mode 100644 fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountTransactionHelper.java create mode 100644 fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareDividendsTransactionHelper.java create mode 100644 fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductHelper.java create mode 100644 fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductTransactionHelper.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/portfolio/products/exception/ResourceNotFoundException.java create mode 100644 fineract-provider/src/main/resources/sql/migrations/core_db/V307__add_share_notes.sql diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java index c8134a6ae..b4b7dc558 100755 --- a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/charges/ChargesHelper.java @@ -37,7 +37,8 @@ public class ChargesHelper { private static final Integer CHARGE_APPLIES_TO_LOAN = 1; private static final Integer CHARGE_APPLIES_TO_SAVINGS = 2; private static final Integer CHARGE_APPLIES_TO_CLIENT = 3; - + private static final Integer CHARGE_APPLIES_TO_SHARES = 4; + private static final Integer CHARGE_DISBURSEMENT_FEE = 1; private static final Integer CHARGE_SPECIFIED_DUE_DATE = 2; private static final Integer CHARGE_SAVINGS_ACTIVATION_FEE = 3; @@ -48,6 +49,10 @@ public class ChargesHelper { private static final Integer CHARGE_OVERDUE_INSTALLMENT_FEE = 9; private static final Integer CHARGE_OVERDRAFT_FEE = 10; private static final Integer WEEKLY_FEE = 11; + private static final Integer SHAREACCOUNT_ACTIVATION = 13 ; + private static final Integer SHARE_PURCHASE = 14 ; + private static final Integer SHARE_REDEEM = 15 ; + private static final Integer CHARGE_SAVINGS_NO_ACTIVITY_FEE = 16; private static final Integer CHARGE_CLIENT_SPECIFIED_DUE_DATE = 1; @@ -235,6 +240,27 @@ public class ChargesHelper { return getLoanInstallmentJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, ChargesHelper.amount, ChargesHelper.penalty); } + public static String getShareAccountActivationChargeJson() { + HashMap map = populateDefaultsShareActivationCharge() ; + String chargesCreateJson = new Gson().toJson(map); + System.out.println(chargesCreateJson); + return chargesCreateJson; + } + + public static String getShareAccountPurchaseChargeJson() { + HashMap map = populateDefaultsSharePurchaseFlatCharge() ; + String chargesCreateJson = new Gson().toJson(map); + System.out.println(chargesCreateJson); + return chargesCreateJson; + } + + public static String getShareAccountRedeemChargeJson() { + HashMap map = populateDefaultsShareRedeemFlatCharge() ; + String chargesCreateJson = new Gson().toJson(map); + System.out.println(chargesCreateJson); + return chargesCreateJson; + } + public static String getLoanOverdueFeeJSON() { final HashMap map = populateDefaultsForLoan(); map.put("penalty", ChargesHelper.penalty); @@ -287,6 +313,45 @@ public class ChargesHelper { return map; } + public static HashMap populateDefaultsShareActivationCharge() { + final HashMap map = new HashMap<>(); + map.put("active", ChargesHelper.active); + map.put("amount", ChargesHelper.amount); + map.put("chargeAppliesTo", ChargesHelper.CHARGE_APPLIES_TO_SHARES); + map.put("chargeCalculationType", ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT); + map.put("chargeTimeType",ChargesHelper.SHAREACCOUNT_ACTIVATION); + map.put("currencyCode", ChargesHelper.currencyCode); + map.put("locale", CommonConstants.locale); + map.put("name", Utils.randomNameGenerator("Charge_Share_Activation_", 8)); + return map; + } + + public static HashMap populateDefaultsSharePurchaseFlatCharge() { + final HashMap map = new HashMap<>(); + map.put("active", ChargesHelper.active); + map.put("amount", ChargesHelper.amount); + map.put("chargeAppliesTo", ChargesHelper.CHARGE_APPLIES_TO_SHARES); + map.put("chargeCalculationType", ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT); + map.put("chargeTimeType",ChargesHelper.SHARE_PURCHASE); + map.put("currencyCode", ChargesHelper.currencyCode); + map.put("locale", CommonConstants.locale); + map.put("name", Utils.randomNameGenerator("Charge_Share_Purchase_", 8)); + return map; + } + + public static HashMap populateDefaultsShareRedeemFlatCharge() { + final HashMap map = new HashMap<>(); + map.put("active", ChargesHelper.active); + map.put("amount", ChargesHelper.amount); + map.put("chargeAppliesTo", ChargesHelper.CHARGE_APPLIES_TO_SHARES); + map.put("chargeCalculationType", ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT); + map.put("chargeTimeType",ChargesHelper.SHARE_REDEEM); + map.put("currencyCode", ChargesHelper.currencyCode); + map.put("locale", CommonConstants.locale); + map.put("name", Utils.randomNameGenerator("Charge_Share_Redeem_", 8)); + return map; + } + public static Integer createCharges(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final String request) { return Utils.performServerPost(requestSpec, responseSpec, CREATE_CHARGES_URL, request, "resourceId"); diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/DividendsIntegrationTests.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/DividendsIntegrationTests.java new file mode 100644 index 000000000..5634dce7f --- /dev/null +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/DividendsIntegrationTests.java @@ -0,0 +1,203 @@ +/** + * 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.integrationtests.common.shares; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.fineract.integrationtests.common.ClientHelper; +import org.apache.fineract.integrationtests.common.Utils; +import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.google.gson.Gson; +import com.jayway.restassured.builder.RequestSpecBuilder; +import com.jayway.restassured.builder.ResponseSpecBuilder; +import com.jayway.restassured.http.ContentType; +import com.jayway.restassured.specification.RequestSpecification; +import com.jayway.restassured.specification.ResponseSpecification; + + +public class DividendsIntegrationTests { + + private final String[] dates = {"01 Jan 2015", "01 Apr 2015", "01 Oct 2015", "01 Dec 2015", "01 Mar 2016"} ; + private final String[] shares = {"100", "200", "300", "100", "500"} ; + + private RequestSpecification requestSpec; + private ResponseSpecification responseSpec; + + @Before + public void setup() { + Utils.initializeRESTAssured(); + this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); + this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); + this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + } + + @SuppressWarnings("unchecked") + @Test + public void testCreateDividends() { + DateFormat simple = new SimpleDateFormat("dd MMM yyyy"); + final Integer productId = createShareProduct() ; + ArrayList clients = new ArrayList<>() ; + ArrayList savingAccounts = new ArrayList<>() ; + ArrayList shareAccounts = new ArrayList<>() ; + for(int i = 0 ; i < 5; i++) { + final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec); + clients.add(clientId) ; + Assert.assertNotNull(clientId); + Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000"); + savingAccounts.add(savingsAccountId) ; + Assert.assertNotNull(savingsAccountId); + final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId, dates[i], shares[i]); + shareAccounts.add(shareAccountId) ; + Assert.assertNotNull(shareAccountId); + Map shareAccountData = ShareAccountTransactionHelper + .retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + Assert.assertNotNull(shareAccountData); + // Approve share Account + Map approveMap = new HashMap<>(); + approveMap.put("note", "Share Account Approval Note"); + approveMap.put("dateFormat", "dd MMMM yyyy"); + approveMap.put("approvedDate", "01 Jan 2016"); + approveMap.put("locale", "en"); + String approve = new Gson().toJson(approveMap); + ShareAccountTransactionHelper.postCommand("approve", shareAccountId, approve, requestSpec, responseSpec); + //Activate Share Account + Map activateMap = new HashMap<>(); + activateMap.put("dateFormat", "dd MMMM yyyy"); + activateMap.put("activatedDate", "01 Jan 2016"); + activateMap.put("locale", "en"); + String activateJson = new Gson().toJson(activateMap); + ShareAccountTransactionHelper.postCommand("activate", shareAccountId, activateJson, requestSpec, responseSpec); + } + + Map dividendsMap = new HashMap<>() ; + dividendsMap.put("dividendPeriodStartDate", "01 Jan 2015") ; + dividendsMap.put("dividendPeriodEndDate", "01 Apr 2016") ; + dividendsMap.put("dividendAmount", "50000") ; + dividendsMap.put("dateFormat", "dd MMMM yyyy"); + dividendsMap.put("locale", "en"); + String createDividendsJson = new Gson().toJson(dividendsMap); + final Integer dividendId = ShareDividendsTransactionHelper.createShareProductDividends(productId, createDividendsJson, requestSpec, responseSpec) ; + + Map productdividends = ShareDividendsTransactionHelper.retrieveAllDividends(productId, requestSpec, responseSpec); + Assert.assertEquals("1", String.valueOf(productdividends.get("totalFilteredRecords"))); + Map dividend = ((List>)productdividends.get("pageItems")).get(0) ; + Assert.assertEquals("50000.0", String.valueOf(dividend.get("amount"))) ; + Map status = (Map)dividend.get("status") ; + Assert.assertEquals("shareAccountDividendStatusType.initiated", String.valueOf(status.get("code"))); + List startdateList = (List) dividend.get("dividendPeriodStartDate"); + Calendar cal = Calendar.getInstance(); + cal.set(startdateList.get(0), startdateList.get(1) - 1, startdateList.get(2)); + Date startDate = cal.getTime(); + Assert.assertEquals("01 Jan 2015", simple.format(startDate)); + List enddateList = (List) dividend.get("dividendPeriodEndDate"); + cal = Calendar.getInstance(); + cal.set(enddateList.get(0), enddateList.get(1) - 1, enddateList.get(2)); + Date endDate = cal.getTime(); + Assert.assertEquals("01 Apr 2016", simple.format(endDate)); + + + + Map dividenddetails = ShareDividendsTransactionHelper.retrieveDividendDetails(productId, dividendId, requestSpec, responseSpec) ; + Assert.assertEquals("5", String.valueOf(dividenddetails.get("totalFilteredRecords"))); + List> pageItems = (List>)dividenddetails.get("pageItems") ; + for(Map dividendData: pageItems) { + Map accountData = (Map) dividendData.get("accountData") ; + String accountId = String.valueOf(accountData.get("id")) ; + if(String.valueOf(shareAccounts.get(0)).equals(accountId)) { + Assert.assertEquals("11320.755", String.valueOf(dividendData.get("amount"))); + }else if(String.valueOf(shareAccounts.get(1)).equals(accountId)) { + Assert.assertEquals("18172.791", String.valueOf(dividendData.get("amount"))); + }else if(String.valueOf(shareAccounts.get(2)).equals(accountId)) { + Assert.assertEquals("13629.593", String.valueOf(dividendData.get("amount"))); + }else if(String.valueOf(shareAccounts.get(3)).equals(accountId)) { + Assert.assertEquals("3028.7983", String.valueOf(dividendData.get("amount"))); + }else if(String.valueOf(shareAccounts.get(4)).equals(accountId)) { + Assert.assertEquals("3848.0637", String.valueOf(dividendData.get("amount"))); + } + Map statusMap = (Map) dividendData.get("status") ; + Assert.assertEquals("shareAccountDividendStatusType.initiated", String.valueOf(statusMap.get("code"))) ; + } + + String jsonString = "" ; + ShareDividendsTransactionHelper.postCommand("approve", productId, dividendId, jsonString, requestSpec, responseSpec) ; + + productdividends = ShareDividendsTransactionHelper.retrieveAllDividends(productId, requestSpec, responseSpec); + Assert.assertEquals("1", String.valueOf(productdividends.get("totalFilteredRecords"))); + dividend = ((List>)productdividends.get("pageItems")).get(0) ; + Assert.assertEquals("50000.0", String.valueOf(dividend.get("amount"))) ; + status = (Map)dividend.get("status") ; + Assert.assertEquals("shareAccountDividendStatusType.approved", String.valueOf(status.get("code"))); + startdateList = (List) dividend.get("dividendPeriodStartDate"); + cal = Calendar.getInstance(); + cal.set(startdateList.get(0), startdateList.get(1) - 1, startdateList.get(2)); + startDate = cal.getTime(); + Assert.assertEquals("01 Jan 2015", simple.format(startDate)); + enddateList = (List) dividend.get("dividendPeriodEndDate"); + cal = Calendar.getInstance(); + cal.set(enddateList.get(0), enddateList.get(1) - 1, enddateList.get(2)); + endDate = cal.getTime(); + Assert.assertEquals("01 Apr 2016", simple.format(endDate)); + + dividenddetails = ShareDividendsTransactionHelper.retrieveDividendDetails(productId, dividendId, requestSpec, responseSpec) ; + Assert.assertEquals("5", String.valueOf(dividenddetails.get("totalFilteredRecords"))); + pageItems = (List>)dividenddetails.get("pageItems") ; + for(Map dividendData: pageItems) { + Map accountData = (Map) dividendData.get("accountData") ; + String accountId = String.valueOf(accountData.get("id")) ; + if(String.valueOf(shareAccounts.get(0)).equals(accountId)) { + Assert.assertEquals("11320.755", String.valueOf(dividendData.get("amount"))); + }else if(String.valueOf(shareAccounts.get(1)).equals(accountId)) { + Assert.assertEquals("18172.791", String.valueOf(dividendData.get("amount"))); + }else if(String.valueOf(shareAccounts.get(2)).equals(accountId)) { + Assert.assertEquals("13629.593", String.valueOf(dividendData.get("amount"))); + }else if(String.valueOf(shareAccounts.get(3)).equals(accountId)) { + Assert.assertEquals("3028.7983", String.valueOf(dividendData.get("amount"))); + }else if(String.valueOf(shareAccounts.get(4)).equals(accountId)) { + Assert.assertEquals("3848.0637", String.valueOf(dividendData.get("amount"))); + } + Map statusMap = (Map) dividendData.get("status") ; + Assert.assertEquals("shareAccountDividendStatusType.initiated", String.valueOf(statusMap.get("code"))) ; + } + + } + + private Integer createShareProduct() { + String shareProductJson = new ShareProductHelper().build(); + return ShareProductTransactionHelper.createShareProduct(shareProductJson, requestSpec, responseSpec); + } + + private Integer createShareAccount(final Integer clientId, final Integer productId, final Integer savingsAccountId, + String applicationDate, String requestedShares) { + String josn = new ShareAccountHelper().withClientId(String.valueOf(clientId)).withProductId(String.valueOf(productId)) + .withExternalId("External1").withSavingsAccountId(String.valueOf(savingsAccountId)).withSubmittedDate("01 Jan 2016") + .withApplicationDate(applicationDate).withRequestedShares(requestedShares).build(); + return ShareAccountTransactionHelper.createShareAccount(josn, requestSpec, responseSpec); + } +} diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountHelper.java new file mode 100644 index 000000000..99846568b --- /dev/null +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountHelper.java @@ -0,0 +1,144 @@ +/** + * 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.integrationtests.common.shares; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.google.gson.Gson; + + +public class ShareAccountHelper { + + private static final String LOCALE = "en_GB"; + + private String clientId ; + + private String productId ; + + private String submittedDate ; + + private String externalId ; + + private String savingsAccountId ; + + private String requestedShares ; + + private String applicationDate ; + + private String allowDividendCalculationForInactiveClients ; + + private String minimumActivePeriod ; + + private String minimumActivePeriodFrequencyType ; + + private String lockinPeriodFrequency ; + + private String lockinPeriodFrequencyType ; + + private List> charges = null ; + //chargeId , amount + + public String build() { + final HashMap map = new HashMap<>(); + map.put("locale", LOCALE); + if(this.clientId != null) { + map.put("clientId", this.clientId) ; + } + if(this.productId != null) { + map.put("productId", this.productId) ; + } + map.put("dateFormat", "dd MMMM yyyy"); + + if(this.savingsAccountId != null) { + map.put("savingsAccountId", savingsAccountId) ; + } + + if(externalId != null) { + map.put("externalId", this.externalId) ; + } + + if(submittedDate != null) { + map.put("submittedDate", this.submittedDate) ; + } + + if(applicationDate != null) { + map.put("applicationDate", this.applicationDate) ; + } + + if(this.requestedShares != null) { + map.put("requestedShares", this.requestedShares) ; + } + + if(this.allowDividendCalculationForInactiveClients != null) { + map.put("allowDividendCalculationForInactiveClients", this.allowDividendCalculationForInactiveClients) ; + } + + if(this.charges != null) { + map.put("charges", this.charges) ; + } + + String shareAccountCreateJson = new Gson().toJson(map); + System.out.println(shareAccountCreateJson); + return shareAccountCreateJson; + } + + public ShareAccountHelper withClientId(final String clientId) { + this.clientId = clientId ; + return this ; + } + + public ShareAccountHelper withProductId(final String productId) { + this.productId = productId ; + return this ; + } + + public ShareAccountHelper withSavingsAccountId(final String savingsAccountId) { + this.savingsAccountId = savingsAccountId ; + return this ; + } + + public ShareAccountHelper withSubmittedDate(final String submittedDate) { + this.submittedDate = submittedDate ; + return this ; + } + + public ShareAccountHelper withRequestedShares(final String requestedShares) { + this.requestedShares = requestedShares ; + return this ; + } + + public ShareAccountHelper withApplicationDate(final String applicationDate) { + this.applicationDate = applicationDate ; + return this ; + } + + public ShareAccountHelper withExternalId(final String externalId) { + this.externalId = externalId ; + return this ; + } + + public ShareAccountHelper withCharges(final List> charges) { + this.charges = new ArrayList<>() ; + this.charges.addAll(charges) ; + return this ; + } +} diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountIntegrationTests.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountIntegrationTests.java new file mode 100644 index 000000000..cb904642e --- /dev/null +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountIntegrationTests.java @@ -0,0 +1,1032 @@ +/** + * 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.integrationtests.common.shares; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.apache.fineract.integrationtests.common.ClientHelper; +import org.apache.fineract.integrationtests.common.Utils; +import org.apache.fineract.integrationtests.common.charges.ChargesHelper; +import org.apache.fineract.integrationtests.common.savings.SavingsAccountHelper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.google.gson.Gson; +import com.jayway.restassured.builder.RequestSpecBuilder; +import com.jayway.restassured.builder.ResponseSpecBuilder; +import com.jayway.restassured.http.ContentType; +import com.jayway.restassured.specification.RequestSpecification; +import com.jayway.restassured.specification.ResponseSpecification; + +public class ShareAccountIntegrationTests { + + private RequestSpecification requestSpec; + private ResponseSpecification responseSpec; + private ShareProductHelper shareProductHelper; + + @Before + public void setup() { + Utils.initializeRESTAssured(); + this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); + this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); + this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + } + + @Test + public void testCreateShareProduct() { + // This method will check create share product, get share product, + // update share product. + System.out.println("------------------------------CREATING NEW SHARE PRODUCT ---------------------------------------"); + shareProductHelper = new ShareProductHelper(); + final Integer shareProductId = createShareProduct(); + Assert.assertNotNull(shareProductId); + System.out.println("------------------------------CREATING SHARE PRODUCT COMPLETE---------------------------------------"); + + System.out.println("------------------------------RETRIEVING SHARE PRODUCT---------------------------------------"); + Map shareProductData = ShareProductTransactionHelper + .retrieveShareProduct(shareProductId, requestSpec, responseSpec); + Assert.assertNotNull(shareProductData); + shareProductHelper.verifyShareProduct(shareProductData); + + System.out.println("------------------------------RETRIEVING SHARE PRODUCT COMPLETE---------------------------------------"); + + System.out.println("------------------------------UPDATING SHARE PRODUCT---------------------------------------"); + + Map shareProductDataForUpdate = new HashMap<>(); + + shareProductDataForUpdate.put("totalShares", "2000"); + shareProductDataForUpdate.put("sharesIssued", "2000"); + + String updateShareProductJsonString = new Gson().toJson(shareProductDataForUpdate); + Integer updatedProductId = ShareProductTransactionHelper.updateShareProduct(shareProductId, updateShareProductJsonString, + requestSpec, responseSpec); + Assert.assertNotNull(updatedProductId); + Map updatedShareProductData = ShareProductTransactionHelper.retrieveShareProduct(updatedProductId, requestSpec, + responseSpec); + String updatedTotalShares = String.valueOf(updatedShareProductData.get("totalShares")); + String updatedSharesIssued = String.valueOf(updatedShareProductData.get("totalSharesIssued")); + Assert.assertEquals("2000", updatedTotalShares); + Assert.assertEquals("2000", updatedSharesIssued); + System.out.println("------------------------------UPDATING SHARE PRODUCT COMPLETE---------------------------------------"); + + } + + @SuppressWarnings("unchecked") + @Test + public void testCreateShareAccount() { + shareProductHelper = new ShareProductHelper(); + final Integer productId = createShareProduct(); + Assert.assertNotNull(productId); + final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000"); + Assert.assertNotNull(savingsAccountId); + final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId); + Assert.assertNotNull(shareAccountId); + Map shareProductData = ShareAccountTransactionHelper + .retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + Assert.assertNotNull(shareProductData); + + Map shareAccountDataForUpdate = new HashMap<>(); + shareAccountDataForUpdate.put("requestedShares", 30); + shareAccountDataForUpdate.put("applicationDate", "02 Mar 2016"); + shareAccountDataForUpdate.put("dateFormat", "dd MMMM yyyy"); + shareAccountDataForUpdate.put("locale", "en_GB"); + String updateShareAccountJsonString = new Gson().toJson(shareAccountDataForUpdate); + ShareAccountTransactionHelper.updateShareAccount(shareAccountId, updateShareAccountJsonString, requestSpec, responseSpec); + shareProductData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + List> transactions = (List>) shareProductData.get("purchasedShares"); + Assert.assertNotNull(transactions); + Assert.assertEquals(1, transactions.size()); + Map transaction = transactions.get(0); + Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("60.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("60.0", String.valueOf(transaction.get("amountPaid"))); + List dateList = (List) transaction.get("purchasedDate"); + Calendar cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date date = cal.getTime(); + DateFormat simple = new SimpleDateFormat("dd MMM yyyy"); + Assert.assertEquals("02 Mar 2016", simple.format(date)); + } + + @Test + @SuppressWarnings("unchecked") + public void testShareAccountApproval() { + DateFormat simple = new SimpleDateFormat("dd MMM yyyy"); + shareProductHelper = new ShareProductHelper(); + final Integer productId = createShareProduct(); + Assert.assertNotNull(productId); + final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000"); + Assert.assertNotNull(savingsAccountId); + String activationCharge = ChargesHelper.getShareAccountActivationChargeJson(); + Integer activationChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, activationCharge); + String purchaseCharge = ChargesHelper.getShareAccountPurchaseChargeJson(); + Integer purchaseChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, purchaseCharge); + String redeemCharge = ChargesHelper.getShareAccountRedeemChargeJson(); + Integer redeemChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, redeemCharge); + List> charges = new ArrayList<>(); + charges.add(createCharge(activationChargeId, "2")); + charges.add(createCharge(purchaseChargeId, "2")); + charges.add(createCharge(redeemChargeId, "1")); + final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId, charges); + Assert.assertNotNull(shareAccountId); + Map shareAccountData = ShareAccountTransactionHelper + .retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + Assert.assertNotNull(shareAccountData); + + // Approve share Account + Map approveMap = new HashMap<>(); + approveMap.put("note", "Share Account Approval Note"); + approveMap.put("dateFormat", "dd MMMM yyyy"); + approveMap.put("approvedDate", "01 Jan 2016"); + approveMap.put("locale", "en"); + String approve = new Gson().toJson(approveMap); + ShareAccountTransactionHelper.postCommand("approve", shareAccountId, approve, requestSpec, responseSpec); + shareAccountData = ShareAccountTransactionHelper + .retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + Map statusMap = (Map) shareAccountData.get("status"); + Assert.assertEquals("shareAccountStatusType.approved", String.valueOf(statusMap.get("code"))); + Map timelineMap = (Map) shareAccountData.get("timeline"); + List dateList = (List) timelineMap.get("approvedDate"); + Calendar cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date approvedDate = cal.getTime(); + Assert.assertEquals("01 Jan 2016", simple.format(approvedDate)); + List> transactions = (List>) shareAccountData.get("purchasedShares"); + Assert.assertNotNull(transactions); + Assert.assertEquals(2, transactions.size()); + for (int i = 0; i < transactions.size(); i++) { + Map transaction = transactions.get(i); + Map transactionTypeMap = (Map) transaction.get("type"); + dateList = (List) transaction.get("purchasedDate"); + cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date date = cal.getTime(); + String transactionType = (String) transactionTypeMap.get("code"); + if (transactionType.equals("purchasedSharesType.purchased")) { + Assert.assertEquals("25", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("52.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("52.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + Assert.assertEquals("01 Jan 2016", simple.format(date)); + } else if (transactionType.equals("charge.payment")) { + Assert.assertEquals("2.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("0", String.valueOf(transaction.get("amountPaid"))); + Date transactionDate = DateUtils.getDateOfTenant() ; + Assert.assertEquals(simple.format(transactionDate), simple.format(date)); + } + } + + Map summaryMap = (Map) shareAccountData.get("summary"); + Assert.assertEquals("25", String.valueOf(summaryMap.get("totalApprovedShares"))); + Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares"))); + } + @Test + @SuppressWarnings("unchecked") + public void rejectShareAccount() { + shareProductHelper = new ShareProductHelper(); + final Integer productId = createShareProduct(); + Assert.assertNotNull(productId); + final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000"); + Assert.assertNotNull(savingsAccountId); + String activationCharge = ChargesHelper.getShareAccountActivationChargeJson(); + Integer activationChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, activationCharge); + String purchaseCharge = ChargesHelper.getShareAccountPurchaseChargeJson(); + Integer purchaseChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, purchaseCharge); + String redeemCharge = ChargesHelper.getShareAccountRedeemChargeJson(); + Integer redeemChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, redeemCharge); + List> charges = new ArrayList<>(); + charges.add(createCharge(activationChargeId, "2")); + charges.add(createCharge(purchaseChargeId, "2")); + charges.add(createCharge(redeemChargeId, "1")); + final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId, charges); + Assert.assertNotNull(shareAccountId); + Map shareAccountData = ShareAccountTransactionHelper + .retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + Assert.assertNotNull(shareAccountData); + + // Reject share Account + Map rejectMap = new HashMap<>(); + rejectMap.put("note", "Share Account Rejection Note"); + String rejectJson = new Gson().toJson(rejectMap); + ShareAccountTransactionHelper.postCommand("reject", shareAccountId, rejectJson, requestSpec, responseSpec); + shareAccountData = ShareAccountTransactionHelper + .retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + DateFormat simple = new SimpleDateFormat("dd MMM yyyy"); + Map statusMap = (Map) shareAccountData.get("status"); + Assert.assertEquals("shareAccountStatusType.rejected", String.valueOf(statusMap.get("code"))); + Map timelineMap = (Map) shareAccountData.get("timeline"); + List dateList = (List) timelineMap.get("rejectedDate"); + Calendar cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date rejectedDate = cal.getTime(); + Date currentTenantDate = DateUtils.getDateOfTenant() ; + Assert.assertEquals(simple.format(currentTenantDate), simple.format(rejectedDate)); + + List> transactions = (List>) shareAccountData.get("purchasedShares"); + Assert.assertNotNull(transactions); + Assert.assertEquals(2, transactions.size()); + for (int i = 0; i < transactions.size(); i++) { + Map transaction = transactions.get(i); + Map transactionTypeMap = (Map) transaction.get("type"); + dateList = (List) transaction.get("purchasedDate"); + cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date date = cal.getTime(); + String transactionType = (String) transactionTypeMap.get("code"); + if (transactionType.equals("purchasedSharesType.purchased")) { + Assert.assertEquals("25", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("52.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("50.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + Assert.assertEquals("01 Jan 2016", simple.format(date)); + } else if (transactionType.equals("charge.payment")) { + Assert.assertEquals("2.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("0", String.valueOf(transaction.get("amountPaid"))); + Date transactionDate = DateUtils.getDateOfTenant() ; + Assert.assertEquals(simple.format(transactionDate), simple.format(date)); + } + } + + Map summaryMap = (Map) shareAccountData.get("summary"); + Assert.assertEquals("0", String.valueOf(summaryMap.get("totalApprovedShares"))); + Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares"))); + } + + @Test + @SuppressWarnings("unchecked") + public void testShareAccountUndoApproval() { + DateFormat simple = new SimpleDateFormat("dd MMM yyyy"); + shareProductHelper = new ShareProductHelper(); + final Integer productId = createShareProduct(); + Assert.assertNotNull(productId); + final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000"); + Assert.assertNotNull(savingsAccountId); + String activationCharge = ChargesHelper.getShareAccountActivationChargeJson(); + Integer activationChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, activationCharge); + String purchaseCharge = ChargesHelper.getShareAccountPurchaseChargeJson(); + Integer purchaseChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, purchaseCharge); + String redeemCharge = ChargesHelper.getShareAccountRedeemChargeJson(); + Integer redeemChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, redeemCharge); + List> charges = new ArrayList<>(); + charges.add(createCharge(activationChargeId, "2")); + charges.add(createCharge(purchaseChargeId, "2")); + charges.add(createCharge(redeemChargeId, "1")); + final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId, charges); + Assert.assertNotNull(shareAccountId); + Map shareAccountData = ShareAccountTransactionHelper + .retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + Assert.assertNotNull(shareAccountData); + + // Approve share Account + Map approveMap = new HashMap<>(); + approveMap.put("note", "Share Account Approval Note"); + approveMap.put("dateFormat", "dd MMMM yyyy"); + approveMap.put("approvedDate", "01 Jan 2016"); + approveMap.put("locale", "en"); + String approve = new Gson().toJson(approveMap); + ShareAccountTransactionHelper.postCommand("approve", shareAccountId, approve, requestSpec, responseSpec); + shareAccountData = ShareAccountTransactionHelper + .retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + Map statusMap = (Map) shareAccountData.get("status"); + Assert.assertEquals("shareAccountStatusType.approved", String.valueOf(statusMap.get("code"))); + Map timelineMap = (Map) shareAccountData.get("timeline"); + List dateList = (List) timelineMap.get("approvedDate"); + Calendar cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date approvedDate = cal.getTime(); + Assert.assertEquals("01 Jan 2016", simple.format(approvedDate)); + + // Undo Approval share Account + Map undoApprovalMap = new HashMap<>(); + String undoApprovalJson = new Gson().toJson(undoApprovalMap); + ShareAccountTransactionHelper.postCommand("undoapproval", shareAccountId, undoApprovalJson, requestSpec, responseSpec); + + shareAccountData = ShareAccountTransactionHelper + .retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + + statusMap = (Map) shareAccountData.get("status"); + Assert.assertEquals("shareAccountStatusType.submitted.and.pending.approval", String.valueOf(statusMap.get("code"))); + + List> transactions = (List>) shareAccountData.get("purchasedShares"); + Assert.assertNotNull(transactions); + Assert.assertEquals(2, transactions.size()); + for (int i = 0; i < transactions.size(); i++) { + Map transaction = transactions.get(i); + Map transactionTypeMap = (Map) transaction.get("type"); + dateList = (List) transaction.get("purchasedDate"); + cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date date = cal.getTime(); + String transactionType = (String) transactionTypeMap.get("code"); + if (transactionType.equals("purchasedSharesType.purchased")) { + Assert.assertEquals("25", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("52.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + Assert.assertEquals("01 Jan 2016", simple.format(date)); + } else if (transactionType.equals("charge.payment")) { + Assert.assertEquals("2.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("0", String.valueOf(transaction.get("amountPaid"))); + Date transactionDate = DateUtils.getDateOfTenant() ; + Assert.assertEquals(simple.format(transactionDate), simple.format(date)); + } + } + + Map summaryMap = (Map) shareAccountData.get("summary"); + Assert.assertEquals("0", String.valueOf(summaryMap.get("totalApprovedShares"))); + Assert.assertEquals("25", String.valueOf(summaryMap.get("totalPendingForApprovalShares"))); + } + + @SuppressWarnings("unchecked") + @Test + public void testCreateShareAccountWithCharges() { + shareProductHelper = new ShareProductHelper(); + final Integer productId = createShareProduct(); + Assert.assertNotNull(productId); + final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec); + Assert.assertNotNull(clientId); + Integer savingsAccountId = SavingsAccountHelper.openSavingsAccount(requestSpec, responseSpec, clientId, "1000"); + Assert.assertNotNull(savingsAccountId); + String activationCharge = ChargesHelper.getShareAccountActivationChargeJson(); + Integer activationChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, activationCharge); + String purchaseCharge = ChargesHelper.getShareAccountPurchaseChargeJson(); + Integer purchaseChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, purchaseCharge); + String redeemCharge = ChargesHelper.getShareAccountRedeemChargeJson(); + Integer redeemChargeId = ChargesHelper.createCharges(requestSpec, responseSpec, redeemCharge); + List> charges = new ArrayList<>(); + charges.add(createCharge(activationChargeId, "2")); + charges.add(createCharge(purchaseChargeId, "2")); + charges.add(createCharge(redeemChargeId, "1")); + final Integer shareAccountId = createShareAccount(clientId, productId, savingsAccountId, charges); + Assert.assertNotNull(shareAccountId); + Map shareAccountData = ShareAccountTransactionHelper + .retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + Assert.assertNotNull(shareAccountData); + + Map shareAccountDataForUpdate = new HashMap<>(); + shareAccountDataForUpdate.put("requestedShares", 30); + shareAccountDataForUpdate.put("applicationDate", "02 Mar 2016"); + shareAccountDataForUpdate.put("dateFormat", "dd MMMM yyyy"); + shareAccountDataForUpdate.put("locale", "en_GB"); + shareAccountDataForUpdate.put("charges", charges); + + String updateShareAccountJsonString = new Gson().toJson(shareAccountDataForUpdate); + ShareAccountTransactionHelper.updateShareAccount(shareAccountId, updateShareAccountJsonString, requestSpec, responseSpec); + shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + List> transactions = (List>) shareAccountData.get("purchasedShares"); + Assert.assertNotNull(transactions); + Assert.assertEquals(2, transactions.size()); + DateFormat simple = new SimpleDateFormat("dd MMM yyyy"); + for (int i = 0; i < transactions.size(); i++) { + Map transaction = transactions.get(i); + Map transactionTypeMap = (Map) transaction.get("type"); + List dateList = (List) transaction.get("purchasedDate"); + Calendar cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date date = cal.getTime(); + String transactionType = (String) transactionTypeMap.get("code"); + if (transactionType.equals("purchasedSharesType.purchased")) { + Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("62.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("60.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + Assert.assertEquals("02 Mar 2016", simple.format(date)); + } else if (transactionType.equals("charge.payment")) { + Assert.assertEquals("2.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("0", String.valueOf(transaction.get("chargeAmount"))); + } + } + + //charges verification + List> chargesList = (List>) shareAccountData.get("charges") ; + for(Map chargeDef: chargesList) { + Map chargeTimeTypeMap = (Map) chargeDef.get("chargeTimeType") ; + String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ; + if(chargeTimeType.equals("chargeTimeType.activation")) { + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) { + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) { + Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid"))); + }else { + Assert.fail("Other Charge defintion found"); + } + } + + // Approve share Account + Map approveMap = new HashMap<>(); + approveMap.put("note", "Share Account Approval Note"); + approveMap.put("dateFormat", "dd MMMM yyyy"); + approveMap.put("approvedDate", "01 Jan 2016"); + approveMap.put("locale", "en"); + String approve = new Gson().toJson(approveMap); + ShareAccountTransactionHelper.postCommand("approve", shareAccountId, approve, requestSpec, responseSpec); + shareAccountData = ShareAccountTransactionHelper + .retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + Map statusMap = (Map) shareAccountData.get("status"); + Assert.assertEquals("shareAccountStatusType.approved", String.valueOf(statusMap.get("code"))); + Map timelineMap = (Map) shareAccountData.get("timeline"); + List dateList = (List) timelineMap.get("approvedDate"); + Calendar cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date approvedDate = cal.getTime(); + Assert.assertEquals("01 Jan 2016", simple.format(approvedDate)); + + //charges verification + chargesList = (List>) shareAccountData.get("charges") ; + for(Map chargeDef: chargesList) { + Map chargeTimeTypeMap = (Map) chargeDef.get("chargeTimeType") ; + String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ; + if(chargeTimeType.equals("chargeTimeType.activation")) { + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) { + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) { + Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid"))); + }else { + Assert.fail("Other Charge defintion found"); + } + } + + Map activateMap = new HashMap<>(); + activateMap.put("dateFormat", "dd MMMM yyyy"); + activateMap.put("activatedDate", "01 Jan 2016"); + activateMap.put("locale", "en"); + String activateJson = new Gson().toJson(activateMap); + ShareAccountTransactionHelper.postCommand("activate", shareAccountId, activateJson, requestSpec, responseSpec); + shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + statusMap = (Map) shareAccountData.get("status"); + Assert.assertEquals("shareAccountStatusType.active", String.valueOf(statusMap.get("code"))); + timelineMap = (Map) shareAccountData.get("timeline"); + dateList = (List) timelineMap.get("activatedDate"); + cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date activatedDate = cal.getTime(); + Assert.assertEquals("01 Jan 2016", simple.format(activatedDate)); + + transactions = (List>) shareAccountData.get("purchasedShares"); + Assert.assertNotNull(transactions); + Assert.assertEquals(2, transactions.size()); + for (int i = 0; i < transactions.size(); i++) { + Map transaction = transactions.get(i); + Map transactionTypeMap = (Map) transaction.get("type"); + dateList = (List) transaction.get("purchasedDate"); + cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date date = cal.getTime(); + String transactionType = (String) transactionTypeMap.get("code"); + if (transactionType.equals("purchasedSharesType.purchased")) { + Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("62.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("62.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + Assert.assertEquals("02 Mar 2016", simple.format(date)); + } else if (transactionType.equals("charge.payment")) { + Assert.assertEquals("2.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("01 Jan 2016", simple.format(date)); + } + } + + //charges verification + chargesList = (List>) shareAccountData.get("charges") ; + for(Map chargeDef: chargesList) { + Map chargeTimeTypeMap = (Map) chargeDef.get("chargeTimeType") ; + String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ; + if(chargeTimeType.equals("chargeTimeType.activation")) { + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) { + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) { + Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid"))); + }else { + Assert.fail("Other Charge defintion found"); + } + } + + Map summaryMap = (Map) shareAccountData.get("summary"); + Assert.assertEquals("30", String.valueOf(summaryMap.get("totalApprovedShares"))); + Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares"))); + + // apply additional shares + Map additionalSharesRequestMap = new HashMap<>(); + additionalSharesRequestMap.put("requestedDate", "01 Apr 2016"); + additionalSharesRequestMap.put("dateFormat", "dd MMMM yyyy"); + additionalSharesRequestMap.put("locale", "en"); + additionalSharesRequestMap.put("requestedShares", "15"); + String additionalSharesRequestJson = new Gson().toJson(additionalSharesRequestMap); + ShareAccountTransactionHelper.postCommand("applyadditionalshares", shareAccountId, additionalSharesRequestJson, requestSpec, + responseSpec); + shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + transactions = (List>) shareAccountData.get("purchasedShares"); + Assert.assertNotNull(transactions); + Assert.assertEquals(3, transactions.size()); + String addtionalSharesRequestId = null; + for (int i = 0; i < transactions.size(); i++) { + Map transaction = transactions.get(i); + Map transactionTypeMap = (Map) transaction.get("type"); + dateList = (List) transaction.get("purchasedDate"); + cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date date = cal.getTime(); + String transactionType = (String) transactionTypeMap.get("code"); + String transactionDate = simple.format(date); + if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("02 Mar 2016")) { + Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("62.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("62.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + } else if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("01 Apr 2016")) { + addtionalSharesRequestId = String.valueOf(transaction.get("id")); + Assert.assertEquals("15", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("32.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("30.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + Map transactionstatusMap = (Map) transaction.get("status"); + Assert.assertEquals("purchasedSharesStatusType.applied", String.valueOf(transactionstatusMap.get("code"))); + + } else if (transactionType.equals("charge.payment")) { + Assert.assertEquals("2.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("01 Jan 2016", transactionDate); + } + } + + //charges verification + chargesList = (List>) shareAccountData.get("charges") ; + for(Map chargeDef: chargesList) { + Map chargeTimeTypeMap = (Map) chargeDef.get("chargeTimeType") ; + String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ; + if(chargeTimeType.equals("chargeTimeType.activation")) { + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) { + Assert.assertEquals("4.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) { + Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid"))); + }else { + Assert.fail("Other Charge defintion found"); + } + } + + summaryMap = (Map) shareAccountData.get("summary"); + Assert.assertEquals("30", String.valueOf(summaryMap.get("totalApprovedShares"))); + Assert.assertEquals("15", String.valueOf(summaryMap.get("totalPendingForApprovalShares"))); + + // Approve additional Shares request + Map>> approveadditionalsharesMap = new HashMap<>(); + List> list = new ArrayList<>(); + Map idsMap = new HashMap<>(); + idsMap.put("id", addtionalSharesRequestId); + list.add(idsMap); + approveadditionalsharesMap.put("requestedShares", list); + String approveadditionalsharesJson = new Gson().toJson(approveadditionalsharesMap); + ShareAccountTransactionHelper.postCommand("approveadditionalshares", shareAccountId, approveadditionalsharesJson, requestSpec, + responseSpec); + + shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + transactions = (List>) shareAccountData.get("purchasedShares"); + Assert.assertNotNull(transactions); + Assert.assertEquals(3, transactions.size()); + for (int i = 0; i < transactions.size(); i++) { + Map transaction = transactions.get(i); + Map transactionTypeMap = (Map) transaction.get("type"); + dateList = (List) transaction.get("purchasedDate"); + cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date date = cal.getTime(); + String transactionType = (String) transactionTypeMap.get("code"); + String transactionDate = simple.format(date); + if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("02 Mar 2016")) { + Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("62.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("62.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + } else if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("01 Apr 2016")) { + Assert.assertEquals("15", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("32.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("32.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + Map transactionstatusMap = (Map) transaction.get("status"); + Assert.assertEquals("purchasedSharesStatusType.approved", String.valueOf(transactionstatusMap.get("code"))); + + } else if (transactionType.equals("charge.payment")) { + Assert.assertEquals("2.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("01 Jan 2016", transactionDate); + } + } + + //charges verification + chargesList = (List>) shareAccountData.get("charges") ; + for(Map chargeDef: chargesList) { + Map chargeTimeTypeMap = (Map) chargeDef.get("chargeTimeType") ; + String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ; + if(chargeTimeType.equals("chargeTimeType.activation")) { + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) { + Assert.assertEquals("4.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("4.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) { + Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid"))); + }else { + Assert.fail("Other Charge defintion found"); + } + } + + summaryMap = (Map) shareAccountData.get("summary"); + Assert.assertEquals("45", String.valueOf(summaryMap.get("totalApprovedShares"))); + Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares"))); + + // apply aditional shres and reject it + additionalSharesRequestMap = new HashMap<>(); + additionalSharesRequestMap.put("requestedDate", "01 May 2016"); + additionalSharesRequestMap.put("dateFormat", "dd MMMM yyyy"); + additionalSharesRequestMap.put("locale", "en"); + additionalSharesRequestMap.put("requestedShares", "20"); + additionalSharesRequestJson = new Gson().toJson(additionalSharesRequestMap); + ShareAccountTransactionHelper.postCommand("applyadditionalshares", shareAccountId, additionalSharesRequestJson, requestSpec, + responseSpec); + shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + transactions = (List>) shareAccountData.get("purchasedShares"); + Assert.assertNotNull(transactions); + Assert.assertEquals(4, transactions.size()); + addtionalSharesRequestId = null; + for (int i = 0; i < transactions.size(); i++) { + Map transaction = transactions.get(i); + Map transactionTypeMap = (Map) transaction.get("type"); + dateList = (List) transaction.get("purchasedDate"); + cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date date = cal.getTime(); + String transactionType = (String) transactionTypeMap.get("code"); + String transactionDate = simple.format(date); + if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("01 May 2016")) { + addtionalSharesRequestId = String.valueOf(transaction.get("id")); + Assert.assertEquals("20", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("42.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("40.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + Map transactionstatusMap = (Map) transaction.get("status"); + Assert.assertEquals("purchasedSharesStatusType.applied", String.valueOf(transactionstatusMap.get("code"))); + } + } + + //charges verification + chargesList = (List>) shareAccountData.get("charges") ; + for(Map chargeDef: chargesList) { + Map chargeTimeTypeMap = (Map) chargeDef.get("chargeTimeType") ; + String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ; + if(chargeTimeType.equals("chargeTimeType.activation")) { + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) { + Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("4.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) { + Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid"))); + }else { + Assert.fail("Other Charge defintion found"); + } + } + + summaryMap = (Map) shareAccountData.get("summary"); + Assert.assertEquals("45", String.valueOf(summaryMap.get("totalApprovedShares"))); + Assert.assertEquals("20", String.valueOf(summaryMap.get("totalPendingForApprovalShares"))); + + // rejectadditionalshares + Map>> rejectadditionalsharesMap = new HashMap<>(); + list = new ArrayList<>(); + idsMap = new HashMap<>(); + idsMap.put("id", addtionalSharesRequestId); + list.add(idsMap); + rejectadditionalsharesMap.put("requestedShares", list); + String rejectadditionalsharesJson = new Gson().toJson(rejectadditionalsharesMap); + ShareAccountTransactionHelper.postCommand("rejectadditionalshares", shareAccountId, rejectadditionalsharesJson, requestSpec, + responseSpec); + shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + transactions = (List>) shareAccountData.get("purchasedShares"); + Assert.assertNotNull(transactions); + Assert.assertEquals(4, transactions.size()); + for (int i = 0; i < transactions.size(); i++) { + Map transaction = transactions.get(i); + Map transactionTypeMap = (Map) transaction.get("type"); + dateList = (List) transaction.get("purchasedDate"); + cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date date = cal.getTime(); + String transactionType = (String) transactionTypeMap.get("code"); + String transactionDate = simple.format(date); + if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("01 May 2016")) { + addtionalSharesRequestId = String.valueOf(transaction.get("id")); + Assert.assertEquals("20", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("40.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("40.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + Map transactionstatusMap = (Map) transaction.get("status"); + Assert.assertEquals("purchasedSharesStatusType.rejected", String.valueOf(transactionstatusMap.get("code"))); + } + } + + //charges verification + chargesList = (List>) shareAccountData.get("charges") ; + for(Map chargeDef: chargesList) { + Map chargeTimeTypeMap = (Map) chargeDef.get("chargeTimeType") ; + String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ; + if(chargeTimeType.equals("chargeTimeType.activation")) { + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) { + Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) { + Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("0", String.valueOf(chargeDef.get("amountPaid"))); + }else { + Assert.fail("Other Charge defintion found"); + } + } + + summaryMap = (Map) shareAccountData.get("summary"); + Assert.assertEquals("45", String.valueOf(summaryMap.get("totalApprovedShares"))); + Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares"))); + + // redeem shares + Map redeemRequestMap = new HashMap<>(); + redeemRequestMap.put("requestedDate", "05 May 2016"); + redeemRequestMap.put("dateFormat", "dd MMMM yyyy"); + redeemRequestMap.put("locale", "en"); + redeemRequestMap.put("requestedShares", "15"); + String redeemRequestJson = new Gson().toJson(redeemRequestMap); + ShareAccountTransactionHelper.postCommand("redeemshares", shareAccountId, redeemRequestJson, requestSpec, responseSpec); + shareAccountData = ShareAccountTransactionHelper.retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + transactions = (List>) shareAccountData.get("purchasedShares"); + Assert.assertNotNull(transactions); + Assert.assertEquals(5, transactions.size()); + for (int i = 0; i < transactions.size(); i++) { + Map transaction = transactions.get(i); + Map transactionTypeMap = (Map) transaction.get("type"); + dateList = (List) transaction.get("purchasedDate"); + cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date date = cal.getTime(); + String transactionType = (String) transactionTypeMap.get("code"); + String transactionDate = simple.format(date); + if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("02 Mar 2016")) { + Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("62.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("62.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + } else if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("01 Apr 2016")) { + Assert.assertEquals("15", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("32.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("32.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + Map transactionstatusMap = (Map) transaction.get("status"); + Assert.assertEquals("purchasedSharesStatusType.approved", String.valueOf(transactionstatusMap.get("code"))); + } else if (transactionType.equals("purchasedSharesType.redeemed") && transactionDate.equals("05 May 2016")) { + Assert.assertEquals("15", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("29.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("29.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("1.0", String.valueOf(transaction.get("chargeAmount"))); + Map transactionstatusMap = (Map) transaction.get("status"); + Assert.assertEquals("purchasedSharesStatusType.approved", String.valueOf(transactionstatusMap.get("code"))); + } else if (transactionType.equals("charge.payment")) { + Assert.assertEquals("2.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("01 Jan 2016", transactionDate); + } + } + + //charges verification + chargesList = (List>) shareAccountData.get("charges") ; + for(Map chargeDef: chargesList) { + Map chargeTimeTypeMap = (Map) chargeDef.get("chargeTimeType") ; + String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ; + if(chargeTimeType.equals("chargeTimeType.activation")) { + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) { + Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) { + Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage"))); + Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountPaid"))); + }else { + Assert.fail("Other Charge defintion found"); + } + } + summaryMap = (Map) shareAccountData.get("summary"); + Assert.assertEquals("30", String.valueOf(summaryMap.get("totalApprovedShares"))); + Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares"))); + + //Close Share Account + Map closeAccountMap = new HashMap<>(); + closeAccountMap.put("note", "Share Account Close Note"); + closeAccountMap.put("dateFormat", "dd MMMM yyyy"); + closeAccountMap.put("closedDate", "10 May 2016"); + closeAccountMap.put("locale", "en"); + String closeJson = new Gson().toJson(closeAccountMap); + ShareAccountTransactionHelper.postCommand("close", shareAccountId, closeJson, requestSpec, responseSpec); + shareAccountData = ShareAccountTransactionHelper + .retrieveShareAccount(shareAccountId, requestSpec, responseSpec); + statusMap = (Map) shareAccountData.get("status"); + Assert.assertEquals("shareAccountStatusType.closed", String.valueOf(statusMap.get("code"))); + transactions = (List>) shareAccountData.get("purchasedShares"); + Assert.assertNotNull(transactions); + Assert.assertEquals(6, transactions.size()); + for (int i = 0; i < transactions.size(); i++) { + Map transaction = transactions.get(i); + Map transactionTypeMap = (Map) transaction.get("type"); + dateList = (List) transaction.get("purchasedDate"); + cal = Calendar.getInstance(); + cal.set(dateList.get(0), dateList.get(1) - 1, dateList.get(2)); + Date date = cal.getTime(); + String transactionType = (String) transactionTypeMap.get("code"); + String transactionDate = simple.format(date); + if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("02 Mar 2016")) { + Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("62.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("62.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + } else if (transactionType.equals("purchasedSharesType.purchased") && transactionDate.equals("01 Apr 2016")) { + Assert.assertEquals("15", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("32.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("32.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("purchasedPrice"))); + Map transactionstatusMap = (Map) transaction.get("status"); + Assert.assertEquals("purchasedSharesStatusType.approved", String.valueOf(transactionstatusMap.get("code"))); + } else if (transactionType.equals("purchasedSharesType.redeemed") && transactionDate.equals("05 May 2016")) { + Assert.assertEquals("15", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("29.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("29.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("1.0", String.valueOf(transaction.get("chargeAmount"))); + Map transactionstatusMap = (Map) transaction.get("status"); + Assert.assertEquals("purchasedSharesStatusType.approved", String.valueOf(transactionstatusMap.get("code"))); + }else if (transactionType.equals("purchasedSharesType.redeemed") && transactionDate.equals("10 May 2016")) { + Assert.assertEquals("30", String.valueOf(transaction.get("numberOfShares"))); + Assert.assertEquals("59.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("59.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("1.0", String.valueOf(transaction.get("chargeAmount"))); + Map transactionstatusMap = (Map) transaction.get("status"); + Assert.assertEquals("purchasedSharesStatusType.approved", String.valueOf(transactionstatusMap.get("code"))); + }else if (transactionType.equals("charge.payment")) { + Assert.assertEquals("2.0", String.valueOf(transaction.get("amount"))); + Assert.assertEquals("2.0", String.valueOf(transaction.get("amountPaid"))); + Assert.assertEquals("0", String.valueOf(transaction.get("chargeAmount"))); + Assert.assertEquals("01 Jan 2016", transactionDate); + } + } + //charges verification + chargesList = (List>) shareAccountData.get("charges") ; + for(Map chargeDef: chargesList) { + Map chargeTimeTypeMap = (Map) chargeDef.get("chargeTimeType") ; + String chargeTimeType = String.valueOf(chargeTimeTypeMap.get("code")) ; + if(chargeTimeType.equals("chargeTimeType.activation")) { + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharespurchase")) { + Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("6.0", String.valueOf(chargeDef.get("amountPaid"))); + }else if(chargeTimeType.equals("chargeTimeType.sharesredeem")) { + Assert.assertEquals("1.0", String.valueOf(chargeDef.get("amountOrPercentage"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amount"))); + Assert.assertEquals("0.0", String.valueOf(chargeDef.get("amountOutstanding"))); + Assert.assertEquals("2.0", String.valueOf(chargeDef.get("amountPaid"))); + }else { + Assert.fail("Other Charge defintion found"); + } + } + summaryMap = (Map) shareAccountData.get("summary"); + Assert.assertEquals("0", String.valueOf(summaryMap.get("totalApprovedShares"))); + Assert.assertEquals("0", String.valueOf(summaryMap.get("totalPendingForApprovalShares"))); + } + + private Integer createShareProduct() { + String shareProductJson = shareProductHelper.build(); + return ShareProductTransactionHelper.createShareProduct(shareProductJson, requestSpec, responseSpec); + } + + private Integer createShareAccount(final Integer clientId, final Integer productId, final Integer savingsAccountId) { + String josn = new ShareAccountHelper().withClientId(String.valueOf(clientId)).withProductId(String.valueOf(productId)) + .withExternalId("External1").withSavingsAccountId(String.valueOf(savingsAccountId)).withSubmittedDate("01 Jan 2016") + .withApplicationDate("01 Jan 2016").withRequestedShares("25").build(); + return ShareAccountTransactionHelper.createShareAccount(josn, requestSpec, responseSpec); + } + + private Integer createShareAccount(final Integer clientId, final Integer productId, final Integer savingsAccountId, + List> charges) { + String josn = new ShareAccountHelper().withClientId(String.valueOf(clientId)).withProductId(String.valueOf(productId)) + .withExternalId("External1").withSavingsAccountId(String.valueOf(savingsAccountId)).withSubmittedDate("01 Jan 2016") + .withApplicationDate("01 Jan 2016").withRequestedShares("25").withCharges(charges).build(); + return ShareAccountTransactionHelper.createShareAccount(josn, requestSpec, responseSpec); + } + + private Map createCharge(final Integer chargeId, String amount) { + Map map = new HashMap<>(); + map.put("chargeId", chargeId); + map.put("amount", amount); + return map; + } +} diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountTransactionHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountTransactionHelper.java new file mode 100644 index 000000000..a4685a392 --- /dev/null +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareAccountTransactionHelper.java @@ -0,0 +1,55 @@ +/** + * 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.integrationtests.common.shares; + +import java.util.Map; + +import org.apache.fineract.integrationtests.common.Utils; + +import com.jayway.restassured.specification.RequestSpecification; +import com.jayway.restassured.specification.ResponseSpecification; + +public class ShareAccountTransactionHelper { + + private static final String SHARE_ACCOUNT_URL = "/fineract-provider/api/v1/accounts/share"; + private static final String CREATE_SHARE_ACCOUNT_URL = SHARE_ACCOUNT_URL + "?" + Utils.TENANT_IDENTIFIER; + + public static Integer createShareAccount(final String shareProductJSON, final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + return Utils.performServerPost(requestSpec, responseSpec, CREATE_SHARE_ACCOUNT_URL, shareProductJSON, "resourceId"); + } + + public static Map retrieveShareAccount(final Integer shareProductId, final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + String url = SHARE_ACCOUNT_URL + "/" + shareProductId + "?" + Utils.TENANT_IDENTIFIER; + return Utils.performServerGet(requestSpec, responseSpec, url, ""); + } + + public static Integer updateShareAccount(final Integer shareAccountId, final String shareAccountJson, + final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { + String url = SHARE_ACCOUNT_URL + "/" + shareAccountId + "?" + Utils.TENANT_IDENTIFIER; + return Utils.performServerPut(requestSpec, responseSpec, url, shareAccountJson, "resourceId"); + } + + public static Integer postCommand(final String command, final Integer shareAccountId, String jsonBody, final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + String url = SHARE_ACCOUNT_URL + "/" + shareAccountId + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER; + return Utils.performServerPost(requestSpec, responseSpec, url, jsonBody, "resourceId"); + } +} diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareDividendsTransactionHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareDividendsTransactionHelper.java new file mode 100644 index 000000000..19a1e268b --- /dev/null +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareDividendsTransactionHelper.java @@ -0,0 +1,58 @@ +/** + * 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.integrationtests.common.shares; + +import java.util.Map; + +import org.apache.fineract.integrationtests.common.Utils; + +import com.jayway.restassured.specification.RequestSpecification; +import com.jayway.restassured.specification.ResponseSpecification; + + + +public class ShareDividendsTransactionHelper { + + private static final String SHARE_PRODUCT_URL = "/fineract-provider/api/v1/shareproduct"; + private static final String DIVIDEND = "dividend" ; + + public static Integer createShareProductDividends(final Integer productId, final String dividendJson, final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + String url = SHARE_PRODUCT_URL + "/" + productId + "/" + DIVIDEND + "?" + Utils.TENANT_IDENTIFIER ; + return Utils.performServerPost(requestSpec, responseSpec, url, dividendJson, "subResourceId"); + } + + public static Integer postCommand(final String command, final Integer productId, final Integer dividendId, String jsonBody, final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + String url = SHARE_PRODUCT_URL + "/" + productId + "/"+DIVIDEND + "/"+ dividendId + "?command=" + command + "&" + Utils.TENANT_IDENTIFIER; + return Utils.performServerPut(requestSpec, responseSpec, url, jsonBody, "resourceId"); + } + + public static Map retrieveDividendDetails(final Integer productId, final Integer dividendId, final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + String url = SHARE_PRODUCT_URL + "/" + productId + "/"+DIVIDEND + "/"+ dividendId +"?" + Utils.TENANT_IDENTIFIER; + return Utils.performServerGet(requestSpec, responseSpec, url, ""); + } + + public static Map retrieveAllDividends(final Integer productId, final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + String url = SHARE_PRODUCT_URL + "/" + productId + "/"+DIVIDEND +"?" + Utils.TENANT_IDENTIFIER; + return Utils.performServerGet(requestSpec, responseSpec, url, ""); + } +} diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductHelper.java new file mode 100644 index 000000000..c59bbbc57 --- /dev/null +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductHelper.java @@ -0,0 +1,199 @@ +/** + * 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.integrationtests.common.shares; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.apache.fineract.integrationtests.common.Utils; +import org.joda.time.LocalDate; +import org.junit.Assert; + +import com.google.gson.Gson; + + +public class ShareProductHelper { + + + private static final String NONE = "1"; + private static final String CASH_BASED = "2"; + private static final String LOCALE = "en_GB"; + private static final String DIGITS_AFTER_DECIMAL = "4"; + private static final String IN_MULTIPLES_OF = "0"; + private static final String USD = "USD"; + + private String productName = Utils.randomNameGenerator("SHARE_PRODUCT_", 6); + private String shortName = Utils.randomNameGenerator("", 4); + private String description = Utils.randomNameGenerator("", 20); + private String totalShares = "10000"; + private final String currencyCode = USD; + private String sharesIssued = "10000"; + private String unitPrice = "2.0" ; + private String minimumShares = "10" ; + private String nominalShares = "20" ; + private String maximumShares = "3000" ; + private String allowDividendCalculationForInactiveClients = "true" ; + private String lockinPeriodFrequency = "1"; + private String lockinPeriodFrequencyType = "0"; + private String accountingRule = NONE; + + String minimumActivePeriodForDividends = "1"; + String minimumactiveperiodFrequencyType = "0"; + + private List> charges = null ; + private List> marketPrices = null ; + + + public String build() { + final HashMap map = new HashMap<>(); + map.put("name", this.productName); + map.put("shortName", this.shortName); + map.put("description", this.description); + map.put("currencyCode", this.currencyCode); + map.put("locale", LOCALE); + map.put("digitsAfterDecimal", DIGITS_AFTER_DECIMAL); + map.put("inMultiplesOf", IN_MULTIPLES_OF); + map.put("totalShares", this.totalShares) ; + map.put("sharesIssued", this.sharesIssued); + map.put("unitPrice", this.unitPrice) ; + map.put("minimumShares", this.minimumShares) ; + map.put("nominalShares", this.nominalShares) ; + map.put("maximumShares", this.maximumShares) ; + map.put("allowDividendCalculationForInactiveClients", this.allowDividendCalculationForInactiveClients) ; + map.put("accountingRule", this.accountingRule) ; + map.put("minimumActivePeriodForDividends", this.minimumActivePeriodForDividends) ; + map.put("minimumactiveperiodFrequencyType", this.minimumactiveperiodFrequencyType) ; + map.put("lockinPeriodFrequency", this.lockinPeriodFrequency) ; + map.put("lockinPeriodFrequencyType", this.lockinPeriodFrequencyType) ; + + if(charges != null) { + map.put("chargesSelected", charges) ; + } + + if(marketPrices != null) { + map.put("marketPricePeriods", marketPrices) ; + } + + String shareProductCreateJson = new Gson().toJson(map); + System.out.println(shareProductCreateJson); + return shareProductCreateJson; + } + + public ShareProductHelper withCashBasedAccounting() { + this.accountingRule = CASH_BASED ; + return this ; + } + + public ShareProductHelper withMarketPrice() { + this.marketPrices = new ArrayList<>() ; + LocalDate currentDate = DateUtils.getLocalDateOfTenant() ; + String[] prices = {"3.0", "4.0", "5.0", "6.0", "7.0"} ; + DateFormat simple = new SimpleDateFormat("dd MMMM yyyy"); + for(int i =0 ; i < prices.length; i++) { + currentDate = currentDate.plusMonths(2) ; + Map marketPrice = new HashMap<>() ; + marketPrice.put("fromDate", simple.format(currentDate)) ; + marketPrice.put("shareValue", prices[i]) ; + this.marketPrices.add(marketPrice) ; + } + return this ; + } + + public ShareProductHelper withCharges(final ArrayList charges) { + if(charges != null && !charges.isEmpty()) { + this.charges = new ArrayList<>() ; + for(Long chargeId: charges) { + Map charge = new HashMap<>() ; + charge.put("id", String.valueOf(chargeId.longValue())) ; + this.charges.add(charge) ; + } + } + return this ; + } + + @SuppressWarnings("unchecked") + public void verifyShareProduct(Map shareProductData) { + String productName = (String)shareProductData.get("name") ; + Assert.assertEquals(this.productName, productName); + String shortName = (String)shareProductData.get("shortName") ; + Assert.assertEquals(this.shortName, shortName); + + String description = (String)shareProductData.get("description") ; + Assert.assertEquals(this.description, description); + + Map currency = (Map)shareProductData.get("currency") ; + String currencyCode = currency.get("code") ; + Assert.assertEquals(this.currencyCode, currencyCode); + + String digitsAfterDecimal = String.valueOf(currency.get("decimalPlaces")) ; + Assert.assertEquals(DIGITS_AFTER_DECIMAL, digitsAfterDecimal); + + String inMultiplesOf = String.valueOf(currency.get("inMultiplesOf")) ; + Assert.assertEquals(IN_MULTIPLES_OF, inMultiplesOf); + + String totalShares = String.valueOf(shareProductData.get("totalShares")) ; + Assert.assertEquals(this.totalShares, totalShares); + + String sharesIssued = String.valueOf(shareProductData.get("totalSharesIssued")) ; + Assert.assertEquals(this.sharesIssued, sharesIssued); + + String unitPrice = String.valueOf(shareProductData.get("unitPrice")) ; + Assert.assertEquals(this.unitPrice, unitPrice); + + String minimumShares = String.valueOf(shareProductData.get("minimumShares")) ; + Assert.assertEquals(this.minimumShares, minimumShares); + + String nominalShares = String.valueOf(shareProductData.get("nominalShares")) ; + Assert.assertEquals(this.nominalShares, nominalShares); + + String maximumShares = String.valueOf(shareProductData.get("maximumShares")) ; + Assert.assertEquals(this.maximumShares, maximumShares); + + String allowDividendCalculationForInactiveClients = String.valueOf(shareProductData.get("allowDividendCalculationForInactiveClients")) ; + Assert.assertEquals(this.allowDividendCalculationForInactiveClients, allowDividendCalculationForInactiveClients); + + Map accountingRuleMap = (Map) shareProductData.get("accountingRule") ; + String accountingRule = String.valueOf(accountingRuleMap.get("id")) ; + Assert.assertEquals(this.accountingRule, accountingRule); + + String minimumActivePeriodForDividends = String.valueOf(shareProductData.get("minimumActivePeriod")) ; + Assert.assertEquals(this.minimumActivePeriodForDividends, minimumActivePeriodForDividends); + + Map minimumActivePeriodType = (Map) shareProductData.get("minimumActivePeriodForDividendsTypeEnum") ; + String minimumactiveperiodFrequencyType = String.valueOf(minimumActivePeriodType.get("id")) ; + Assert.assertEquals(this.minimumactiveperiodFrequencyType, minimumactiveperiodFrequencyType); + + String lockinPeriodFrequency = String.valueOf(shareProductData.get("lockinPeriod")) ; + Assert.assertEquals(this.lockinPeriodFrequency, lockinPeriodFrequency); + + Map lockinPeriodType = (Map) shareProductData.get("lockPeriodTypeEnum") ; + String lockinPeriodFrequencyType = String.valueOf(lockinPeriodType.get("id")) ; + Assert.assertEquals(this.lockinPeriodFrequencyType, lockinPeriodFrequencyType); + + ArrayList> charges = (ArrayList>)shareProductData.get("chargesSelected") ; + + ArrayList> marketPrices = (ArrayList>)shareProductData.get("marketPricePeriods") ; + + } +} diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductTransactionHelper.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductTransactionHelper.java new file mode 100644 index 000000000..2c8588fa1 --- /dev/null +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/shares/ShareProductTransactionHelper.java @@ -0,0 +1,51 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.integrationtests.common.shares; + +import java.util.Map; + +import org.apache.fineract.integrationtests.common.Utils; + +import com.jayway.restassured.specification.RequestSpecification; +import com.jayway.restassured.specification.ResponseSpecification; + + +public class ShareProductTransactionHelper { + + private static final String SHARE_PRODUCT_URL = "/fineract-provider/api/v1/products/share"; + private static final String CREATE_SHARE_PRODUCT_URL = SHARE_PRODUCT_URL + "?" + Utils.TENANT_IDENTIFIER; + + public static Integer createShareProduct(final String savingsProductJSON, final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + return Utils.performServerPost(requestSpec, responseSpec, CREATE_SHARE_PRODUCT_URL, savingsProductJSON, "resourceId"); + } + + public static Map retrieveShareProduct(final Integer shareProductId, final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + String url = SHARE_PRODUCT_URL+"/"+shareProductId+"?"+Utils.TENANT_IDENTIFIER ; + return Utils.performServerGet(requestSpec, responseSpec, url, ""); + } + + public static Integer updateShareProduct(final Integer shareProductId, final String provsioningCriteriaJson, + final RequestSpecification requestSpec, + final ResponseSpecification responseSpec) { + String url = SHARE_PRODUCT_URL+"/"+shareProductId+"?"+Utils.TENANT_IDENTIFIER ; + return Utils.performServerPut(requestSpec, responseSpec, url, provsioningCriteriaJson, "resourceId"); + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/api/AccountsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/api/AccountsApiResource.java index 56df39f60..f627c89a3 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/api/AccountsApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/api/AccountsApiResource.java @@ -18,8 +18,6 @@ */ package org.apache.fineract.portfolio.accounts.api; -import java.util.Collection; - import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -39,10 +37,13 @@ import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer; +import org.apache.fineract.infrastructure.core.service.Page; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.portfolio.accounts.constants.AccountsApiConstants; import org.apache.fineract.portfolio.accounts.data.AccountData; import org.apache.fineract.portfolio.accounts.service.AccountReadPlatformService; +import org.apache.fineract.portfolio.products.exception.ResourceNotFoundException; +import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Scope; @@ -59,21 +60,18 @@ public class AccountsApiResource { private final DefaultToApiJsonSerializer toApiJsonSerializer; private final PlatformSecurityContext platformSecurityContext; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; - private final DefaultToApiJsonSerializer toApiObjectJsonSerializer ; @Autowired public AccountsApiResource(final ApplicationContext applicationContext, final ApiRequestParameterHelper apiRequestParameterHelper, final DefaultToApiJsonSerializer toApiJsonSerializer, final PlatformSecurityContext platformSecurityContext, - final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, - final DefaultToApiJsonSerializer toApiObjectJsonSerializer) { + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { this.applicationContext = applicationContext ; this.apiRequestParameterHelper = apiRequestParameterHelper ; this.toApiJsonSerializer = toApiJsonSerializer ; this.platformSecurityContext = platformSecurityContext ; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService ; - this.toApiObjectJsonSerializer = toApiObjectJsonSerializer ; } @GET @@ -83,12 +81,16 @@ public class AccountsApiResource { public String template(@PathParam("type") final String accountType, @QueryParam("clientId") final Long clientId, @QueryParam("productId") final Long productId, @Context final UriInfo uriInfo) { - this.platformSecurityContext.authenticatedUser() ; - String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ; - AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ; - final AccountData accountData = service.retrieveTemplate(clientId, productId); - final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, accountData, service.getResponseDataParams()); + try { + this.platformSecurityContext.authenticatedUser() ; + String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ; + AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ; + final AccountData accountData = service.retrieveTemplate(clientId, productId); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, accountData, service.getResponseDataParams()); + }catch(BeansException e) { + throw new ResourceNotFoundException(); + } } @GET @@ -97,22 +99,30 @@ public class AccountsApiResource { @Produces({ MediaType.APPLICATION_JSON }) public String retrieveAccount(@PathParam("accountId") final Long accountId, @PathParam("type") final String accountType, @Context final UriInfo uriInfo) { - String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ; - final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ; - AccountData data = service.retrieveOne(accountId, settings.isTemplate()) ; - return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams()); + try { + String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ; + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ; + AccountData data = service.retrieveOne(accountId, settings.isTemplate()) ; + return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams()); + }catch(BeansException e) { + throw new ResourceNotFoundException(); + } } @GET @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveAllAccounts(@PathParam("type") final String accountType, @Context final UriInfo uriInfo) { - String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ; - AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ; - Collection data = service.retrieveAll() ; - final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams()); + public String retrieveAllAccounts(@PathParam("type") final String accountType, @QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit, @Context final UriInfo uriInfo) { + try { + String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ; + AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ; + Page data = service.retrieveAll(offset, limit) ; + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams()); + }catch(BeansException e) { + throw new ResourceNotFoundException(); + } } @POST diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/service/AccountReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/service/AccountReadPlatformService.java index 42ef5e390..f22e82ad9 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/service/AccountReadPlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accounts/service/AccountReadPlatformService.java @@ -18,9 +18,9 @@ */ package org.apache.fineract.portfolio.accounts.service; -import java.util.Collection; import java.util.Set; +import org.apache.fineract.infrastructure.core.service.Page; import org.apache.fineract.portfolio.accounts.data.AccountData; public interface AccountReadPlatformService { @@ -29,7 +29,7 @@ public interface AccountReadPlatformService { public AccountData retrieveOne(Long id, boolean includeTemplate); - public Collection retrieveAll(); + public Page retrieveAll(final Integer offSet, final Integer limit); public Set getResponseDataParams(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java index e18c2380d..e835fb056 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java @@ -35,6 +35,7 @@ import org.apache.fineract.portfolio.group.domain.Group; import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; +import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount; import org.apache.fineract.useradministration.domain.AppUser; @Entity @@ -67,6 +68,11 @@ public class Note extends AbstractAuditableCustom { @JoinColumn(name = "savings_account_id", nullable = true) private SavingsAccount savingsAccount; + @ManyToOne + @JoinColumn(name = "share_account_id", nullable = true) + private ShareAccount shareAccount; + + public static Note clientNoteFromJson(final Client client, final JsonCommand command) { final String note = command.stringValueOfParameterNamed("note"); return new Note(client, note); @@ -89,6 +95,10 @@ public class Note extends AbstractAuditableCustom { return new Note(account, note); } + public static Note shareNote(final ShareAccount account, final String note) { + return new Note(account, note); + } + public Note(final Client client, final String note) { this.client = client; this.note = note; @@ -133,6 +143,13 @@ public class Note extends AbstractAuditableCustom { this.noteTypeId = NoteType.SAVING_ACCOUNT.getValue(); } + public Note(final ShareAccount account, final String note) { + this.shareAccount = account; + this.client = account.getClient(); + this.note = note; + this.noteTypeId = NoteType.SHARE_ACCOUNT.getValue(); + } + public Map update(final JsonCommand command) { final Map actualChanges = new LinkedHashMap<>(7); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteType.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteType.java index 01bed9fcf..bd50c3606 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteType.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/NoteType.java @@ -27,8 +27,9 @@ public enum NoteType { LOAN(200, "noteType.loan", "loans"), // LOAN_TRANSACTION(300, "noteType.loan.transaction", "loanTransactions"), // SAVING_ACCOUNT(500, "noteType.saving", "savings"), // - GROUP(600, "noteType.group", "groups"); - + GROUP(600, "noteType.group", "groups"), + SHARE_ACCOUNT(700, "noteType.shares", "accounts/share"); + private Integer value; private String code; private String apiUrl; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/api/ProductsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/api/ProductsApiResource.java index 9badddae2..a94a1467b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/api/ProductsApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/api/ProductsApiResource.java @@ -30,7 +30,6 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; -import org.apache.commons.lang.StringUtils; import org.apache.fineract.commands.domain.CommandWrapper; import org.apache.fineract.commands.service.CommandWrapperBuilder; import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService; @@ -42,7 +41,9 @@ import org.apache.fineract.infrastructure.core.service.Page; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.portfolio.products.constants.ProductsApiConstants; import org.apache.fineract.portfolio.products.data.ProductData; +import org.apache.fineract.portfolio.products.exception.ResourceNotFoundException; import org.apache.fineract.portfolio.products.service.ProductReadPlatformService; +import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Scope; @@ -56,21 +57,18 @@ public class ProductsApiResource { private final ApplicationContext applicationContext; private final ApiRequestParameterHelper apiRequestParameterHelper; private final DefaultToApiJsonSerializer toApiJsonSerializer; - private final DefaultToApiJsonSerializer toApiObjectJsonSerializer; private final PlatformSecurityContext platformSecurityContext; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; @Autowired public ProductsApiResource(final ApplicationContext applicationContext, final ApiRequestParameterHelper apiRequestParameterHelper, final DefaultToApiJsonSerializer toApiJsonSerializer, final PlatformSecurityContext platformSecurityContext, - final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, - final DefaultToApiJsonSerializer toApiDividendsJsonSerializer) { + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { this.applicationContext = applicationContext; this.apiRequestParameterHelper = apiRequestParameterHelper; this.toApiJsonSerializer = toApiJsonSerializer; this.platformSecurityContext = platformSecurityContext; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; - this.toApiObjectJsonSerializer = toApiDividendsJsonSerializer; } @GET @@ -79,10 +77,14 @@ public class ProductsApiResource { @Produces({ MediaType.APPLICATION_JSON }) public String retrieveTemplate(@PathParam("type") final String productType, @Context final UriInfo uriInfo) { String serviceName = productType + ProductsApiConstants.READPLATFORM_NAME; - ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName); - ProductData data = service.retrieveTemplate(); - final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams()); + try { + ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName); + ProductData data = service.retrieveTemplate(); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams()); + }catch(BeansException e) { + throw new ResourceNotFoundException() ; + } } @GET @@ -91,30 +93,31 @@ public class ProductsApiResource { @Produces({ MediaType.APPLICATION_JSON }) public String retrieveProduct(@PathParam("productId") final Long productId, @PathParam("type") final String productType, @Context final UriInfo uriInfo) { - String serviceName = productType + ProductsApiConstants.READPLATFORM_NAME; - ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName); - final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - - ProductData data = service.retrieveOne(productId, settings.isTemplate()); - - return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams()); + try { + String serviceName = productType + ProductsApiConstants.READPLATFORM_NAME; + ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + ProductData data = service.retrieveOne(productId, settings.isTemplate()); + return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams()); + } catch (BeansException e) { + throw new ResourceNotFoundException(); + } } @GET @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveAllProducts(/* - * @PathParam("type") final String - * productType, @Context final UriInfo - * uriInfo - */ - @PathParam("type") final String productType, @QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit, + public String retrieveAllProducts(@PathParam("type") final String productType, @QueryParam("offset") final Integer offset, @QueryParam("limit") final Integer limit, @Context final UriInfo uriInfo) { - String serviceName = productType + ProductsApiConstants.READPLATFORM_NAME; - ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName); - Page data = service.retrieveAllProducts(offset, limit); - final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams()); + try { + String serviceName = productType + ProductsApiConstants.READPLATFORM_NAME; + ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName); + Page data = service.retrieveAllProducts(offset, limit); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams()); + }catch(BeansException e) { + throw new ResourceNotFoundException(); + } } @POST @@ -152,8 +155,4 @@ public class ProductsApiResource { final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); return this.toApiJsonSerializer.serialize(result); } - - private boolean is(final String commandParam, final String commandValue) { - return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue); - } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/exception/ResourceNotFoundException.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/exception/ResourceNotFoundException.java new file mode 100644 index 000000000..98135f7be --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/products/exception/ResourceNotFoundException.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.portfolio.products.exception; + +import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; + + +public class ResourceNotFoundException extends AbstractPlatformResourceNotFoundException{ + + public ResourceNotFoundException(String globalisationMessageCode, String defaultUserMessage, Object[] defaultUserMessageArgs) { + super(globalisationMessageCode, defaultUserMessage, defaultUserMessageArgs); + } + + public ResourceNotFoundException() { + super("","","") ; + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java index d14194a09..59827cb6b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java @@ -262,9 +262,18 @@ public class ShareAccount extends AbstractPersistable { public void addTransaction(final ShareAccountTransaction transaction) { transaction.setShareAccount(this); if(transaction.isPendingForApprovalTransaction()) { - this.totalSharesPending += transaction.getTotalShares() ; + if(this.totalSharesPending == null) { + this.totalSharesPending = transaction.getTotalShares() ; + }else { + this.totalSharesPending += transaction.getTotalShares() ; + } + }else if(transaction.isPurchasTransaction()) { - this.totalSharesApproved += transaction.getTotalShares() ; + if(this.totalSharesApproved == null) { + this.totalSharesApproved = transaction.getTotalShares() ; + }else { + this.totalSharesApproved += transaction.getTotalShares() ; + } } this.shareAccountTransactions.add(transaction); @@ -337,6 +346,10 @@ public class ShareAccount extends AbstractPersistable { return this.client.getDisplayName(); } + public Client getClient() { + return this.client ; + } + public String getSavingsAccountNo() { return this.savingsAccount.getAccountNumber(); } @@ -501,6 +514,10 @@ public class ShareAccount extends AbstractPersistable { return this.client.getOffice().getId(); } + public void setTotalPendingShares(final Long shares) { + this.totalSharesPending = shares ; + } + public ShareAccountTransaction getShareAccountTransaction(final ShareAccountTransaction transaction) { ShareAccountTransaction returnTrans = null; for (ShareAccountTransaction tran : this.shareAccountTransactions) { @@ -549,4 +566,12 @@ public class ShareAccount extends AbstractPersistable { public PeriodFrequencyType getLockinPeriodFrequencyType() { return this.lockinPeriodFrequencyType ; } + + public Date getActivatedDate() { + return this.activatedDate ; + } + + public Integer status() { + return this.status ; + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java index da0d784d9..fb79206c3 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java @@ -239,6 +239,10 @@ public class ShareAccountTransaction extends AbstractPersistable { } } + public void updateTransactionDate(final Date transactionDate) { + this.transactionDate = transactionDate ; + } + public boolean isActive() { return this.active ; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java index 927f6f113..78b9b3506 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java @@ -57,6 +57,7 @@ import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformS import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount; import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountCharge; import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountChargePaidBy; +import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountStatusType; import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountTransaction; import org.apache.fineract.portfolio.shareproducts.domain.ShareProduct; import org.apache.fineract.portfolio.shareproducts.domain.ShareProductRepositoryWrapper; @@ -287,37 +288,56 @@ public class ShareAccountDataSerializer { } Date existingApplicationDate = null ; + List purchaseTransactionsList = new ArrayList<>() ; + Set chargesList = new HashSet<>() ; + if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.requestedshares_paramname, element) || this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.charges_paramname, element)) { Set transactions = account.getShareAccountTransactions(); List reveralIds = new ArrayList<>(); for (ShareAccountTransaction transaction : transactions) { - transaction.setActive(false); - if(!transaction.isChargeTransaction()) { - existingApplicationDate = transaction.getPurchasedDate() ; + if (transaction.isActive()) { + reveralIds.add(transaction.getId()); + transaction.setActive(false); + if (!transaction.isChargeTransaction()) { + existingApplicationDate = transaction.getPurchasedDate(); + ShareAccountTransaction newtransaction = new ShareAccountTransaction(transaction.getPurchasedDate(), + transaction.getTotalShares(), transaction.getPurchasePrice()); + purchaseTransactionsList.add(newtransaction); + } } - reveralIds.add(transaction.getId()); } actualChanges.put("reversalIds", reveralIds); Set charges = account.getCharges() ; for(ShareAccountCharge charge: charges) { - charge.setActive(false); + if(charge.isActive()) { + charge.setActive(false); + ChargeTimeType chargeTime = null; + ChargeCalculationType chargeCalculation = null; + Boolean status = Boolean.TRUE; + ShareAccountCharge accountCharge = ShareAccountCharge.createNewWithoutShareAccount(charge.getCharge(), charge.percentageOrAmount(), chargeTime, + chargeCalculation, status); + chargesList.add(accountCharge) ; + } } } if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.requestedshares_paramname, element)) { Long requestedShares = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.requestedshares_paramname, element); + baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requestedShares).notNull(); Date applicationDate = null ; + purchaseTransactionsList.clear() ; if(this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.applicationdate_param, element)) { applicationDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.applicationdate_param, element) - .toDate(); + .toDate(); + baseDataValidator.reset().parameter(ShareAccountApiConstants.applicationdate_param).value(applicationDate).notNull(); }else { applicationDate = existingApplicationDate ; } BigDecimal unitPrice = shareProduct.deriveMarketPrice(applicationDate); ShareAccountTransaction transaction = new ShareAccountTransaction(applicationDate, requestedShares, unitPrice); - account.addTransaction(transaction); + purchaseTransactionsList.add(transaction) ; actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, "Transaction"); if(shareProduct.getMinimumClientShares() != null && requestedShares < shareProduct.getMinimumClientShares()) { @@ -329,13 +349,14 @@ public class ShareAccountDataSerializer { baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(requestedShares) .failWithCode("client.can.not.purchase.shares.morethan.product.definition", "Client can not purchase shares more than product definition"); } - }/*else if(this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.charges_paramname, element)) { - //Since we are removing all purchase transactions when either charge param or requestedShares param exists - for(ShareAccountTransaction transaction:existingTransactions) { - account.addTransaction(transaction); - } - }*/ - + } + + if(!purchaseTransactionsList.isEmpty()) { + ShareAccountTransaction transaction = purchaseTransactionsList.get(0) ; + account.addTransaction(transaction); + account.setTotalPendingShares(transaction.getTotalShares()); + } + if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.allowdividendcalculationforinactiveclients_paramname, element)) { Boolean allowdividendsForInactiveClients = this.fromApiJsonHelper.extractBooleanNamed( ShareAccountApiConstants.allowdividendcalculationforinactiveclients_paramname, element); @@ -381,17 +402,20 @@ public class ShareAccountDataSerializer { if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.charges_paramname, element)) { shareProduct = account.getShareProduct(); final MonetaryCurrency currency = shareProduct.getCurrency(); - Set charges = assembleListOfAccountCharges(element, currency.getCode()); - if (charges != null) { - for (ShareAccountCharge charge : charges) { - charge.update(account); - } - account.addCharges(charges); - if (!charges.isEmpty()) { + chargesList = assembleListOfAccountCharges(element, currency.getCode()); + if (chargesList != null) { + if (!chargesList.isEmpty()) { actualChanges.put(ShareAccountApiConstants.charges_paramname, new HashSet()); } } } + if(chargesList != null && !chargesList.isEmpty()) { + for (ShareAccountCharge charge : chargesList) { + charge.update(account); + } + account.addCharges(chargesList); + } + createChargeTransaction(account); if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } return actualChanges; @@ -406,6 +430,9 @@ public class ShareAccountDataSerializer { final List dataValidationErrors = new ArrayList<>(); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); JsonElement element = jsonCommand.parsedJson(); + if(!account.status().equals(ShareAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL.getValue())) { + baseDataValidator.failWithCodeNoParameterAddedToErrorCode("is.not.pending.for.approval"); + } LocalDate approvedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.approveddate_paramname, element); final LocalDate submittalDate = new LocalDate(account.getSubmittedDate()); if (approvedDate != null && approvedDate.isBefore(submittalDate)) { @@ -470,23 +497,15 @@ public class ShareAccountDataSerializer { public Map validateAndUndoApprove(JsonCommand jsonCommand, ShareAccount account) { Map actualChanges = new HashMap<>(); if (StringUtils.isBlank(jsonCommand.json())) { throw new InvalidJsonException(); } - // final Type typeOfMap = new TypeToken>() - // {}.getType(); - // this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, - // jsonCommand.json(), ShareAccountApiConstants.activateParameters); - // final List dataValidationErrors = new - // ArrayList<>(); - // final DataValidatorBuilder baseDataValidator = new - // DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); - // JsonElement element = jsonCommand.parsedJson(); - // String notes = - // this.fromApiJsonHelper.extractStringNamed(ShareAccountApiConstants.note_paramname, - // element); - // baseDataValidator.reset().parameter(ShareAccountApiConstants.approveddate_paramname).validateDateAfter(account.get) - // AppUser approvedUser = - // this.platformSecurityContext.authenticatedUser(); + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, jsonCommand.json(), ShareAccountApiConstants.activateParameters); + final List dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); + if(!account.status().equals(ShareAccountStatusType.APPROVED.getValue())) { + baseDataValidator.failWithCodeNoParameterAddedToErrorCode("is.not.in.approved.status"); + } account.undoApprove(); - updateTotalChargeDerivedForUndoApproval(account) ; + updateTotalChargeDerivedForUndoApproval(account); actualChanges.put(ShareAccountApiConstants.charges_paramname, Boolean.TRUE); return actualChanges; } @@ -537,6 +556,9 @@ public class ShareAccountDataSerializer { final List dataValidationErrors = new ArrayList<>(); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); JsonElement element = jsonCommand.parsedJson(); + if(!account.status().equals(ShareAccountStatusType.APPROVED.getValue())) { + baseDataValidator.failWithCodeNoParameterAddedToErrorCode("is.not.in.approved.status"); + } LocalDate activatedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.activatedate_paramname, element); baseDataValidator.reset().parameter(ShareAccountApiConstants.activatedate_paramname).value(activatedDate).notNull(); final LocalDate approvedDate = new LocalDate(account.getApprovedDate()); @@ -565,6 +587,7 @@ public class ShareAccountDataSerializer { Set transactions = account.getChargeTransactions(); for (ShareAccountTransaction transaction : transactions) { if (transaction.isChargeTransaction()) { + transaction.updateTransactionDate(account.getActivatedDate()); transaction.updateAmountPaid(transaction.amount()); } } @@ -614,6 +637,9 @@ public class ShareAccountDataSerializer { final List dataValidationErrors = new ArrayList<>(); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount"); JsonElement element = jsonCommand.parsedJson(); + if(!account.status().equals(ShareAccountStatusType.ACTIVE.getValue())) { + baseDataValidator.failWithCodeNoParameterAddedToErrorCode("is.not.in.active.state") ; + } LocalDate requestedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.requesteddate_paramname, element); baseDataValidator.reset().parameter(ShareAccountApiConstants.requesteddate_paramname).value(requestedDate).notNull(); final Long sharesRequested = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.requestedshares_paramname, element); @@ -775,11 +801,6 @@ public class ShareAccountDataSerializer { final Long sharesRequested = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.requestedshares_paramname, element); baseDataValidator.reset().parameter(ShareAccountApiConstants.requestedshares_paramname).value(sharesRequested).notNull() .longGreaterThanZero(); - - final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(element.getAsJsonObject()); - final BigDecimal unitPrice = this.fromApiJsonHelper.extractBigDecimalNamed(ShareAccountApiConstants.purchasedprice_paramname, - element, locale); - baseDataValidator.reset().parameter(ShareAccountApiConstants.purchasedprice_paramname).value(unitPrice).notNull().positiveAmount(); boolean isTransactionBeforeExistingTransactions = false ; Set transactions = account.getShareAccountTransactions() ; for(ShareAccountTransaction transaction: transactions) { @@ -797,6 +818,7 @@ public class ShareAccountDataSerializer { .failWithCodeNoParameterAddedToErrorCode("redeem.transaction.date.cannot.be.before.existing.transactions"); } if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + BigDecimal unitPrice = account.getShareProduct().deriveMarketPrice(requestedDate.toDate()) ; ShareAccountTransaction transaction = ShareAccountTransaction.createRedeemTransaction(requestedDate.toDate(), sharesRequested, unitPrice); validateRedeemRequest(account, transaction, baseDataValidator, dataValidationErrors) ; @@ -949,8 +971,6 @@ public class ShareAccountDataSerializer { account.close(closedDate.toDate(), approvedUser); handleRedeemSharesChargeTransactions(account, transaction); actualChanges.put(ShareAccountApiConstants.requestedshares_paramname, transaction); - updateTotalChargeDerived(account); - return actualChanges; } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java index 90ab5b079..8d9cbee0e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java @@ -30,10 +30,13 @@ import java.util.Set; import org.apache.fineract.infrastructure.core.data.EnumOptionData; import org.apache.fineract.infrastructure.core.domain.JdbcSupport; import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.apache.fineract.infrastructure.core.service.Page; +import org.apache.fineract.infrastructure.core.service.PaginationHelper; import org.apache.fineract.infrastructure.core.service.RoutingDataSource; import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.apache.fineract.portfolio.accountdetails.data.ShareAccountSummaryData; import org.apache.fineract.portfolio.accounts.constants.AccountsApiConstants; +import org.apache.fineract.portfolio.accounts.constants.ShareAccountApiConstants; import org.apache.fineract.portfolio.accounts.data.AccountData; import org.apache.fineract.portfolio.charge.data.ChargeData; import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService; @@ -45,17 +48,16 @@ import org.apache.fineract.portfolio.products.service.ProductReadPlatformService import org.apache.fineract.portfolio.savings.DepositAccountType; import org.apache.fineract.portfolio.savings.data.SavingsAccountData; import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformService; -import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionData; import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountApplicationTimelineData; -import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountDividendData; -import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountStatusEnumData; import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountChargeData; import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountData; +import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountDividendData; +import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountStatusEnumData; +import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionData; import org.apache.fineract.portfolio.shareaccounts.domain.PurchasedSharesStatusType; import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountStatusType; -import org.apache.fineract.portfolio.shareproducts.SharePeriodFrequencyType; -import org.apache.fineract.portfolio.shareproducts.data.ShareProductMarketPriceData; import org.apache.fineract.portfolio.shareproducts.data.ShareProductData; +import org.apache.fineract.portfolio.shareproducts.data.ShareProductMarketPriceData; import org.apache.fineract.portfolio.shareproducts.service.ShareProductDropdownReadPlatformService; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; @@ -78,7 +80,8 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat private final PurchasedSharesReadPlatformService purchasedSharesReadPlatformService; private final JdbcTemplate jdbcTemplate; private final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd"); - + private final PaginationHelper shareAccountDataPaginationHelper = new PaginationHelper<>(); + @Autowired public ShareAccountReadPlatformServiceImpl(final RoutingDataSource dataSource, final ApplicationContext applicationContext, final ChargeReadPlatformService chargeReadPlatformService, @@ -148,7 +151,7 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat ShareAccountMapper mapper = new ShareAccountMapper(charges, purchasedShares); String query = "select " + mapper.schema() + "where sa.id=?"; - ShareAccountData data = this.jdbcTemplate.queryForObject(query, mapper, new Object[] { id }); + ShareAccountData data = (ShareAccountData)this.jdbcTemplate.queryForObject(query, mapper, new Object[] { id }); String serviceName = "share" + ProductsApiConstants.READPLATFORM_NAME; ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName); final ShareProductData productData = (ShareProductData) service.retrieveOne(data.getProductId(), false); @@ -179,13 +182,30 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat } @Override - public Collection retrieveAll() { - return null; + public Page retrieveAll(final Integer offSet, final Integer limit) { + final Collection charges = null ; + final Collection purchasedShares = null ; + ShareAccountMapper mapper = new ShareAccountMapper(charges, purchasedShares) ; + StringBuilder sqlBuilder = new StringBuilder(); + sqlBuilder.append("select SQL_CALC_FOUND_ROWS "); + sqlBuilder.append(mapper.schema()); + sqlBuilder.append(" where sa.status_enum = ? "); + if (limit != null) { + sqlBuilder.append(" limit ").append(limit); + } + if (offSet != null) { + sqlBuilder.append(" offset ").append(offSet); + } + + final String sqlCountRows = "SELECT FOUND_ROWS()"; + Object[] whereClauseItemsitems = new Object[] {ShareAccountStatusType.ACTIVE.getValue()}; + return this.shareAccountDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), + whereClauseItemsitems, mapper); } @Override public Set getResponseDataParams() { - return null; + return ShareAccountApiConstants.supportedParameters; } @Override @@ -222,7 +242,7 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat return savingsCharges; } - private final static class ShareAccountMapper implements RowMapper { + private final static class ShareAccountMapper implements RowMapper { private final Collection charges; private final Collection purchasedShares; @@ -328,16 +348,14 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat final Integer lockinPeriodFrequencyTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodEnum"); if (lockinPeriodFrequencyTypeValue != null) { - final SharePeriodFrequencyType lockinPeriodType = SharePeriodFrequencyType.fromInt(lockinPeriodFrequencyTypeValue); - lockinPeriodFrequencyType = SharesEnumerations.lockinPeriodFrequencyType(lockinPeriodType); + lockinPeriodFrequencyType = SharesEnumerations.lockinPeriodFrequencyType(lockinPeriodFrequencyTypeValue); } final Integer minimumActivePeriod = JdbcSupport.getInteger(rs, "minimumactivePeriod"); EnumOptionData minimumActivePeriodType = null; final Integer minimumActivePeriodTypeValue = JdbcSupport.getInteger(rs, "minimumactivePeriodEnum"); if (minimumActivePeriodTypeValue != null) { - final SharePeriodFrequencyType minmumPeriodType = SharePeriodFrequencyType.fromInt(minimumActivePeriodTypeValue); - minimumActivePeriodType = SharesEnumerations.lockinPeriodFrequencyType(minmumPeriodType); + minimumActivePeriodType = SharesEnumerations.minimumActivePeriodFrequencyType(minimumActivePeriodTypeValue); } final String shortProductName = null; @@ -467,6 +485,7 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat schema = buff.toString(); } + @SuppressWarnings("unused") @Override public ShareAccountDividendData mapRow(ResultSet rs, int rowNum) throws SQLException { final Long id = rs.getLong("id"); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java index d4f4cd77b..4bf7a85ac 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.commons.lang.StringUtils; import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService; import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormat; import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormatRepositoryWrapper; @@ -39,6 +40,8 @@ import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.portfolio.accounts.constants.ShareAccountApiConstants; import org.apache.fineract.portfolio.client.domain.AccountNumberGenerator; +import org.apache.fineract.portfolio.note.domain.Note; +import org.apache.fineract.portfolio.note.domain.NoteRepository; import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountTransactionEnumData; import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccount; import org.apache.fineract.portfolio.shareaccounts.domain.ShareAccountChargePaidBy; @@ -67,19 +70,23 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA private final JournalEntryWritePlatformService journalEntryWritePlatformService; + private final NoteRepository noteRepository; + @Autowired public ShareAccountWritePlatformServiceJpaRepositoryImpl(final ShareAccountDataSerializer accountDataSerializer, final ShareAccountRepositoryWrapper shareAccountRepository, final ShareProductRepositoryWrapper shareProductRepository, final AccountNumberGenerator accountNumberGenerator, final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository, - final JournalEntryWritePlatformService journalEntryWritePlatformService) { + final JournalEntryWritePlatformService journalEntryWritePlatformService, + final NoteRepository noteRepository) { this.accountDataSerializer = accountDataSerializer; this.shareAccountRepository = shareAccountRepository; this.shareProductRepository = shareProductRepository ; this.accountNumberGenerator = accountNumberGenerator; this.accountNumberFormatRepository = accountNumberFormatRepository; this.journalEntryWritePlatformService = journalEntryWritePlatformService; + this.noteRepository = noteRepository ; } @Override @@ -181,6 +188,7 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA this.journalEntryWritePlatformService.revertShareAccountJournalEntries(reversalIds, transactionDate); journalEntryWritePlatformService.createJournalEntriesForShares(populateJournalEntries(account, account.getPendingForApprovalSharePurchaseTransactions())); + changes.remove("reversalIds") ; } return new CommandProcessingResultBuilder() // .withCommandId(jsonCommand.commandId()) // @@ -231,6 +239,12 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA Map changes = this.accountDataSerializer.validateAndApprove(jsonCommand, account); if (!changes.isEmpty()) { this.shareAccountRepository.save(account); + final String noteText = jsonCommand.stringValueOfParameterNamed("note"); + if (StringUtils.isNotBlank(noteText)) { + final Note note = Note.shareNote(account, noteText); + changes.put("note", noteText); + this.noteRepository.save(note); + } } Set transactions = account.getShareAccountTransactions(); Set journalTransactions = new HashSet<>(); @@ -265,6 +279,12 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA Map changes = this.accountDataSerializer.validateAndReject(jsonCommand, account); if (!changes.isEmpty()) { this.shareAccountRepository.save(account); + final String noteText = jsonCommand.stringValueOfParameterNamed("note"); + if (StringUtils.isNotBlank(noteText)) { + final Note note = Note.shareNote(account, noteText); + changes.put("note", noteText); + this.noteRepository.save(note); + } } Set transactions = account.getShareAccountTransactions(); Set journalTransactions = new HashSet<>(); @@ -293,6 +313,12 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA Map changes = this.accountDataSerializer.validateAndUndoApprove(jsonCommand, account); if (!changes.isEmpty()) { this.shareAccountRepository.save(account); + final String noteText = jsonCommand.stringValueOfParameterNamed("note"); + if (StringUtils.isNotBlank(noteText)) { + final Note note = Note.shareNote(account, noteText); + changes.put("note", noteText); + this.noteRepository.save(note); + } } Set transactions = account.getShareAccountTransactions() ; @@ -447,6 +473,12 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA Map changes = this.accountDataSerializer.validateAndClose(jsonCommand, account); if (!changes.isEmpty()) { this.shareAccountRepository.save(account); + final String noteText = jsonCommand.stringValueOfParameterNamed("note"); + if (StringUtils.isNotBlank(noteText)) { + final Note note = Note.shareNote(account, noteText); + changes.put("note", noteText); + this.noteRepository.save(note); + } ShareAccountTransaction transaction = (ShareAccountTransaction) changes .get(ShareAccountApiConstants.requestedshares_paramname); transaction = account.getShareAccountTransaction(transaction); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/SharesEnumerations.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/SharesEnumerations.java index 9be43d9f7..f6bb97603 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/SharesEnumerations.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/SharesEnumerations.java @@ -121,8 +121,39 @@ public class SharesEnumerations { return lockinPeriodFrequencyType(SharePeriodFrequencyType.fromInt(id)); } + public static EnumOptionData minimumActivePeriodFrequencyType(final int id) { + return minimumActivePeriodFrequencyType(SharePeriodFrequencyType.fromInt(id)); + } + + public static EnumOptionData minimumActivePeriodFrequencyType(final SharePeriodFrequencyType type) { + final String codePrefix = "shares.minimumactive." ; + EnumOptionData optionData = new EnumOptionData(SharePeriodFrequencyType.INVALID.getValue().longValue(), + SharePeriodFrequencyType.INVALID.getCode(), "Invalid"); + switch (type) { + case INVALID: + break; + case DAYS: + optionData = new EnumOptionData(SharePeriodFrequencyType.DAYS.getValue().longValue(), codePrefix + + SharePeriodFrequencyType.DAYS.getCode(), "Days"); + break; + case WEEKS: + optionData = new EnumOptionData(SharePeriodFrequencyType.WEEKS.getValue().longValue(), codePrefix + + SharePeriodFrequencyType.WEEKS.getCode(), "Weeks"); + break; + case MONTHS: + optionData = new EnumOptionData(SharePeriodFrequencyType.MONTHS.getValue().longValue(), codePrefix + + SharePeriodFrequencyType.MONTHS.getCode(), "Months"); + break; + case YEARS: + optionData = new EnumOptionData(SharePeriodFrequencyType.YEARS.getValue().longValue(), codePrefix + + SharePeriodFrequencyType.YEARS.getCode(), "Years"); + break; + } + return optionData; + } + public static EnumOptionData lockinPeriodFrequencyType(final SharePeriodFrequencyType type) { - final String codePrefix = "savings.lockin."; + final String codePrefix = "shares.lockin." ; EnumOptionData optionData = new EnumOptionData(SharePeriodFrequencyType.INVALID.getValue().longValue(), SharePeriodFrequencyType.INVALID.getCode(), "Invalid"); switch (type) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/serialization/ShareProductDataSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/serialization/ShareProductDataSerializer.java index 02c08d975..076861d8c 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/serialization/ShareProductDataSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/serialization/ShareProductDataSerializer.java @@ -172,6 +172,7 @@ public class ShareProductDataSerializer { sharesIssued, unitPrice, shareCapitalValue, minimumClientShares, nominalClientShares, maximumClientShares, marketPriceSet, charges, allowdividendsForInactiveClients, lockinPeriod, lockPeriodType, minimumActivePeriod, minimumActivePeriodType, createdBy, createdDate, modifiedBy, modifiedOn, accountingRuleType); + for (ShareProductMarketPrice data : marketPriceSet) { data.setShareProduct(product); } @@ -204,7 +205,7 @@ public class ShareProductDataSerializer { } private Set asembleShareMarketPrice(final JsonElement element) { - Set set = null; + Set set = new HashSet<>(); if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.marketprice_paramname, element)) { set = new HashSet<>(); JsonArray array = this.fromApiJsonHelper.extractJsonArrayNamed(ShareProductApiConstants.marketprice_paramname, element); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java index 64dc94edc..853051cfa 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java @@ -45,9 +45,9 @@ import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService; import org.apache.fineract.portfolio.products.data.ProductData; import org.apache.fineract.portfolio.products.exception.ProductNotFoundException; import org.apache.fineract.portfolio.products.service.ProductReadPlatformService; -import org.apache.fineract.portfolio.savings.service.SavingsEnumerations; -import org.apache.fineract.portfolio.shareproducts.data.ShareProductMarketPriceData; +import org.apache.fineract.portfolio.shareaccounts.service.SharesEnumerations; import org.apache.fineract.portfolio.shareproducts.data.ShareProductData; +import org.apache.fineract.portfolio.shareproducts.data.ShareProductMarketPriceData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; @@ -63,7 +63,7 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS private final ShareProductDropdownReadPlatformService shareProductDropdownReadPlatformService; private final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService; private final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService; - private final PaginationHelper provisioningEntryDataPaginationHelper = new PaginationHelper<>(); + private final PaginationHelper shareProductDataPaginationHelper = new PaginationHelper<>(); @Autowired public ShareProductReadPlatformServiceImpl(final RoutingDataSource dataSource, @@ -81,7 +81,9 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS @Override public Page retrieveAllProducts(Integer offSet, Integer limit) { - AllShareProductRowMapper mapper = new AllShareProductRowMapper(); + final Collection shareMarketCollection = null ; + final Collection charges = null ; + ShareProductRowMapper mapper = new ShareProductRowMapper(shareMarketCollection, charges); StringBuilder sqlBuilder = new StringBuilder(); sqlBuilder.append("select SQL_CALC_FOUND_ROWS "); sqlBuilder.append(mapper.schema()); @@ -94,7 +96,7 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS final String sqlCountRows = "SELECT FOUND_ROWS()"; Object[] whereClauseItemsitems = new Object[] {}; - return this.provisioningEntryDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), + return this.shareProductDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), whereClauseItemsitems, mapper); } @@ -168,6 +170,7 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS private static final class AllShareProductRowMapper implements RowMapper { + @SuppressWarnings("unused") @Override public ShareProductData mapRow(ResultSet rs, int rowNum) throws SQLException { final Long id = rs.getLong("id"); @@ -184,6 +187,7 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS private static final class MarketPriceRowMapper implements RowMapper { + @SuppressWarnings("unused") @Override public ShareProductMarketPriceData mapRow(ResultSet rs, int rowNum) throws SQLException { final Long id = rs.getLong("id"); @@ -226,6 +230,7 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS } + @SuppressWarnings("unused") @Override public ShareProductData mapRow(ResultSet rs, int rowNum) throws SQLException { final Long id = rs.getLong("id"); @@ -258,14 +263,14 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS final Integer minimumActviePeriodEnumValue = JdbcSupport.getInteger(rs, "minimum_active_period_frequency_enum"); EnumOptionData minimumActivePeriodType = null; if (minimumActviePeriodEnumValue != null) { - minimumActivePeriodType = SavingsEnumerations.lockinPeriodFrequencyType(minimumActviePeriodEnumValue); + minimumActivePeriodType = SharesEnumerations.minimumActivePeriodFrequencyType(minimumActviePeriodEnumValue); } final Integer lockinPeriodFrequency = JdbcSupport.getInteger(rs, "lockin_period_frequency"); EnumOptionData lockinPeriodFrequencyType = null; final Integer lockinPeriodFrequencyTypeValue = JdbcSupport.getInteger(rs, "lockin_period_frequency_enum"); if (lockinPeriodFrequencyTypeValue != null) { - lockinPeriodFrequencyType = SavingsEnumerations.lockinPeriodFrequencyType(lockinPeriodFrequencyTypeValue); + lockinPeriodFrequencyType = SharesEnumerations.lockinPeriodFrequencyType(lockinPeriodFrequencyTypeValue); } final Integer accountingRuleId = JdbcSupport.getInteger(rs, "accountingType"); final EnumOptionData accountingRuleType = AccountingEnumerations.accountingRuleType(accountingRuleId); diff --git a/fineract-provider/src/main/resources/sql/migrations/core_db/V307__add_share_notes.sql b/fineract-provider/src/main/resources/sql/migrations/core_db/V307__add_share_notes.sql new file mode 100644 index 000000000..9e52c3e6b --- /dev/null +++ b/fineract-provider/src/main/resources/sql/migrations/core_db/V307__add_share_notes.sql @@ -0,0 +1,2 @@ +ALTER TABLE `m_note` +ADD COLUMN `share_account_id` BIGINT(20) NULL DEFAULT NULL AFTER `savings_account_transaction_id`; \ No newline at end of file