Java tutorial
/* * eGov SmartCity eGovernance suite aims to improve the internal efficiency,transparency, * accountability and the service delivery of the government organizations. * * Copyright (C) 2017 eGovernments Foundation * * The updated version of eGov suite of products as by eGovernments Foundation * is available at http://www.egovernments.org * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/ or * http://www.gnu.org/licenses/gpl.html . * * In addition to the terms of the GPL license to be adhered to in using this * program, the following additional terms are to be complied with: * * 1) All versions of this program, verbatim or modified must carry this * Legal Notice. * Further, all user interfaces, including but not limited to citizen facing interfaces, * Urban Local Bodies interfaces, dashboards, mobile applications, of the program and any * derived works should carry eGovernments Foundation logo on the top right corner. * * For the logo, please refer http://egovernments.org/html/logo/egov_logo.png. * For any further queries on attribution, including queries on brand guidelines, * please contact contact@egovernments.org * * 2) Any misrepresentation of the origin of the material is prohibited. It * is required that all modified versions of this material be marked in * reasonable ways as different from the original version. * * 3) This license does not grant any rights to any user of the program * with regards to rights under trademark law for use of the trade names * or trademarks of eGovernments Foundation. * * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. * */ package org.egov.ptis.service.es; import org.apache.commons.lang3.StringUtils; import org.egov.commons.CFinancialYear; import org.egov.commons.service.CFinancialYearService; import org.egov.infra.admin.master.entity.es.CityIndex; import org.egov.infra.utils.DateUtils; import org.egov.ptis.bean.dashboard.CollReceiptDetails; import org.egov.ptis.bean.dashboard.CollTableData; import org.egov.ptis.bean.dashboard.CollectionAnalysis; import org.egov.ptis.bean.dashboard.CollectionDetails; import org.egov.ptis.bean.dashboard.CollectionDetailsRequest; import org.egov.ptis.bean.dashboard.CollectionTrend; import org.egov.ptis.bean.dashboard.DayWiseCollection; import org.egov.ptis.bean.dashboard.DemandCollectionMIS; import org.egov.ptis.bean.dashboard.MonthlyDCB; import org.egov.ptis.bean.dashboard.ReceiptTableData; import org.egov.ptis.bean.dashboard.ReceiptsTrend; import org.egov.ptis.bean.dashboard.WeeklyDCB; import org.egov.ptis.constants.PropertyTaxConstants; import org.egov.ptis.domain.entity.es.BillCollectorIndex; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.aggregations.AggregationBuilder; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; import org.elasticsearch.search.aggregations.bucket.terms.StringTerms; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.metrics.sum.Sum; import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.SortOrder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.ResultsExtractor; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import static org.egov.ptis.constants.PropertyTaxConstants.*; @Service public class CollectionIndexElasticSearchService { private static final String CURRENT_TOTAL = "current_total"; private static final String ADVANCE = "advance"; private static final String REBATE = "rebate"; private static final String CURR_INTEREST_DMD = "curr_interest_dmd"; private static final String ARREAR_INTEREST_DMD = "arrear_interest_dmd"; private static final String CURR_DMD = "curr_dmd"; private static final String ARREARDMD = "arrear_dmd"; private static final String DECEMBER = "December"; private static final String NOVEMBER = "November"; private static final String OCTOBER = "October"; private static final String SEPTEMBER = "September"; private static final String AUGUST = "August"; private static final String JULY = "July"; private static final String JUNE = "June"; private static final String MAY = "May"; private static final String APRIL = "April"; private static final String MARCH = "March"; private static final String FEBRUARY = "Feburary"; private static final String JANUARY = "January"; private static final String LY_ADVANCE = "lyAdvance"; private static final String LY_REBATE = "lyRebate"; private static final String LY_CURRENT_CESS = "lyCurrentCess"; private static final String LY_CURRENT_AMOUNT = "lyCurrentAmount"; private static final String LY_ARREAR_CESS = "lyArrearCess"; private static final String LY_ARREAR_AMOUNT = "lyArrearAmount"; private static final String LY_PENALTY = "lyPenalty"; private static final String LY_LATE_PAYMENT_PENALTY = "lyLatePaymentPenalty"; private static final String CY_ADVANCE = "cyAdvance"; private static final String CY_REBATE = "cyRebate"; private static final String CY_PENALTY = "cyPenalty"; private static final String CY_LATE_PAYMENT_PENALTY = "cyLatePaymentPenalty"; private static final String CY_CURRENT_CESS = "cyCurrentCess"; private static final String CY_CURRENT_AMOUNT = "cyCurrentAmount"; private static final String CY_ARREAR_CESS = "cyArrearCess"; private static final String CY_ARREAR_AMOUNT = "cyArrearAmount"; private static final String CURRENT_INT_DMD = "currentIntDmd"; private static final String ARREAR_INT_DMD = "arrearIntDmd"; private static final String IS_EXEMPTED = "isExempted"; private static final String IS_ACTIVE = "isActive"; private static final String IS_UNDER_COURTCASE = "isUnderCourtcase"; private static final String CONSUMER_TYPE = "consumerType"; private static final String LATE_PAYMENT_CHARGES = "latePaymentCharges"; private static final String CURR_CESS = "curr_cess"; private static final String ARREAR_CESS_CONST = "arrear_cess"; private static final String CURR_AMOUNT = "curr_amount"; private static final String ARREAR_AMOUNT_CONST = "arrear_amount"; private static final String CURRENT_DMD = "currentDmd"; private static final String ARREAR_DMD = "arrearDmd"; private static final String CURRENT_CESS = "currentCess"; private static final String ARREAR_CESS = "arrearCess"; private static final String CURRENT_AMOUNT = "currentAmount"; private static final String ARREAR_AMOUNT = "arrearAmount"; private static final String CONSUMER_CODE = "consumerCode"; private static final String RECEIPT_COUNT = "receipt_count"; private static final String DATE_AGG = "date_agg"; private static final String BY_CITY = "by_city"; private static final String REVENUE_WARD = "revenueWard"; private static final String CITY_NAME = "cityName"; private static final String CITY_CODE = "cityCode"; private static final String CITY_GRADE = "cityGrade"; private static final String DISTRICT_NAME = "districtName"; private static final String REGION_NAME = "regionName"; private static final String BILLING_SERVICE = "billingService"; private static final String TOTAL_DEMAND = "totalDemand"; private static final String TOTAL_AMOUNT = "totalAmount"; private static final String COLLECTIONTOTAL = "collectiontotal"; private static final String CANCELLED = "Cancelled"; private static final String STATUS = "status"; private static final String RECEIPT_DATE = "receiptDate"; @Autowired private CFinancialYearService cFinancialYearService; @Autowired private ElasticsearchTemplate elasticsearchTemplate; /** * Gives the consolidated collection for the dates and billing service * * @param fromDate * @param toDate * @param billingService * @return BigDecimal */ public BigDecimal getConsolidatedCollForYears(Date fromDate, Date toDate, String billingService) { BoolQueryBuilder boolQuery = QueryBuilders.boolQuery() .must(QueryBuilders.rangeQuery(RECEIPT_DATE).gte(DATEFORMATTER_YYYY_MM_DD.format(fromDate)) .lte(DATEFORMATTER_YYYY_MM_DD.format(toDate)).includeUpper(false)) .mustNot(QueryBuilders.matchQuery(STATUS, CANCELLED)); if (COLLECION_BILLING_SERVICE_WTMS.equalsIgnoreCase(billingService)) boolQuery = boolQuery.must(QueryBuilders.matchQuery(BILLING_SERVICE, billingService)); else boolQuery = boolQuery.must(QueryBuilders.boolQuery().filter(QueryBuilders.termsQuery(BILLING_SERVICE, Arrays.asList(COLLECION_BILLING_SERVICE_PT, COLLECION_BILLING_SERVICE_VLT)))); SearchQuery searchQueryColl = new NativeSearchQueryBuilder().withIndices(COLLECTION_INDEX_NAME) .withQuery(boolQuery).addAggregation(AggregationBuilders.sum(COLLECTIONTOTAL).field(TOTAL_AMOUNT)) .build(); Aggregations collAggr = elasticsearchTemplate.query(searchQueryColl, new ResultsExtractor<Aggregations>() { @Override public Aggregations extract(SearchResponse response) { return response.getAggregations(); } }); Sum aggr = collAggr.get(COLLECTIONTOTAL); return BigDecimal.valueOf(aggr.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP); } /** * Gives the consolidated collection for the current Fin year and last fin year * * @param billingService * @return Map */ public Map<String, BigDecimal> getFinYearsCollByService(String billingService) { /** * As per Elastic Search functionality, to get the total collections between 2 dates, add a day to the endDate and fetch * the results */ Map<String, BigDecimal> consolidatedCollValues = new HashMap<>(); CFinancialYear currFinYear = cFinancialYearService.getFinancialYearByDate(new Date()); // For current year results consolidatedCollValues.put("cytdColln", getConsolidatedCollForYears(currFinYear.getStartingDate(), DateUtils.addDays(new Date(), 1), billingService)); // For last year results consolidatedCollValues.put("lytdColln", getConsolidatedCollForYears(DateUtils.addYears(currFinYear.getStartingDate(), -1), DateUtils.addDays(DateUtils.addYears(new Date(), -1), 1), billingService)); return consolidatedCollValues; } /** * Builds query based on the input parameters sent * * @param collectionDetailsRequest * @param indexName * @param ulbCodeField * @return BoolQueryBuilder */ private BoolQueryBuilder prepareWhereClause(CollectionDetailsRequest collectionDetailsRequest, String indexName) { BoolQueryBuilder boolQuery = new BoolQueryBuilder(); if (indexName.equals(PROPERTY_TAX_INDEX_NAME)) boolQuery = QueryBuilders.boolQuery().filter(QueryBuilders.rangeQuery(TOTAL_DEMAND).from(0).to(null)); else if (indexName.equals(COLLECTION_INDEX_NAME)) boolQuery = QueryBuilders.boolQuery().filter(QueryBuilders.termsQuery(BILLING_SERVICE, Arrays.asList(COLLECION_BILLING_SERVICE_PT, COLLECION_BILLING_SERVICE_VLT))); if (StringUtils.isNotBlank(collectionDetailsRequest.getRegionName())) boolQuery = boolQuery .filter(QueryBuilders.matchQuery(REGION_NAME, collectionDetailsRequest.getRegionName())); if (StringUtils.isNotBlank(collectionDetailsRequest.getDistrictName())) boolQuery = boolQuery .filter(QueryBuilders.matchQuery(DISTRICT_NAME, collectionDetailsRequest.getDistrictName())); if (StringUtils.isNotBlank(collectionDetailsRequest.getUlbGrade())) boolQuery = boolQuery .filter(QueryBuilders.matchQuery(CITY_GRADE, collectionDetailsRequest.getUlbGrade())); if (StringUtils.isNotBlank(collectionDetailsRequest.getUlbCode())) boolQuery = boolQuery .filter(QueryBuilders.matchQuery(CITY_CODE, collectionDetailsRequest.getUlbCode())); if (StringUtils.isNotBlank(collectionDetailsRequest.getPropertyType())) boolQuery = queryForPropertyType(collectionDetailsRequest, boolQuery, indexName); if (PROPERTY_TAX_INDEX_NAME.equalsIgnoreCase(indexName) && StringUtils.isNotBlank(collectionDetailsRequest.getUsageType())) boolQuery = queryForUsageType(collectionDetailsRequest, boolQuery); return boolQuery; } private BoolQueryBuilder queryForUsageType(CollectionDetailsRequest collectionDetailsRequest, BoolQueryBuilder boolQuery) { BoolQueryBuilder usageTypeQuery = boolQuery; if (!DASHBOARD_USAGE_TYPE_ALL.equalsIgnoreCase(collectionDetailsRequest.getUsageType())) usageTypeQuery = usageTypeQuery .filter(QueryBuilders.matchQuery("propertyUsage", collectionDetailsRequest.getUsageType())); return usageTypeQuery; } public BoolQueryBuilder queryForPropertyType(CollectionDetailsRequest collectionDetailsRequest, BoolQueryBuilder boolQuery, String indexName) { BoolQueryBuilder propTypeQuery = boolQuery; /** * If property type is courtcases, consider court case assessments, * if property type is Private, consider Private and EWSHS properties * if property type is BuiltUp, consider all properties except vacant land properties */ if (DASHBOARD_PROPERTY_TYPE_COURTCASES.equalsIgnoreCase(collectionDetailsRequest.getPropertyType())) { if (PROPERTY_TAX_INDEX_NAME.equalsIgnoreCase(indexName)) propTypeQuery = propTypeQuery.filter(QueryBuilders.matchQuery(IS_UNDER_COURTCASE, true)); else propTypeQuery = propTypeQuery.filter(QueryBuilders.matchQuery("conflict", 1)); } else { if (DASHBOARD_PROPERTY_TYPE_CENTRAL_GOVT.equalsIgnoreCase(collectionDetailsRequest.getPropertyType())) propTypeQuery = propTypeQuery .filter(QueryBuilders.termsQuery(CONSUMER_TYPE, DASHBOARD_PROPERTY_TYPE_CENTRAL_GOVT_LIST)); else if (DASHBOARD_PROPERTY_TYPE_PRIVATE.equalsIgnoreCase(collectionDetailsRequest.getPropertyType())) propTypeQuery = propTypeQuery.filter(QueryBuilders.termsQuery(CONSUMER_TYPE, Arrays.asList(collectionDetailsRequest.getPropertyType(), OWNERSHIP_TYPE_EWSHS))); else if (DASHBOARD_PROPERTY_TYPE_BUILT_UP.equalsIgnoreCase(collectionDetailsRequest.getPropertyType())) propTypeQuery = propTypeQuery .filter(QueryBuilders.termsQuery(CONSUMER_TYPE, DASHBOARD_BUILT_UP_PROPERTY_TYPES)); else propTypeQuery = propTypeQuery.filter( QueryBuilders.matchQuery(CONSUMER_TYPE, collectionDetailsRequest.getPropertyType())); if (!DASHBOARD_PROPERTY_TYPE_BUILT_UP.equalsIgnoreCase(collectionDetailsRequest.getPropertyType())) { if (PROPERTY_TAX_INDEX_NAME.equalsIgnoreCase(indexName)) propTypeQuery = propTypeQuery.filter(QueryBuilders.matchQuery(IS_UNDER_COURTCASE, false)); else propTypeQuery = propTypeQuery.filter(QueryBuilders.matchQuery("conflict", 0)); } } return propTypeQuery; } /** * API sets the consolidated collections for single day and between the 2 dates * * @param collectionDetailsRequest * @param collectionIndexDetails */ public void getCompleteCollectionIndexDetails(CollectionDetailsRequest collectionDetailsRequest, CollectionDetails collectionIndexDetails) { Date fromDate; Date toDate; BigDecimal todayColl; BigDecimal tillDateColl; final CFinancialYear financialYear = cFinancialYearService.getFinancialYearByDate(new Date()); /** * As per Elastic Search functionality, to get the total collections between 2 dates, add a day to the endDate and fetch * the results For Current day's collection if dates are sent in the request, consider the toDate, else take date range * between current date +1 day */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils .addDays(DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD), 1); } else { fromDate = new Date(); toDate = DateUtils.addDays(new Date(), 1); } // Todays collection todayColl = getCollectionBetweenDates(collectionDetailsRequest, fromDate, toDate, null, null, TOTAL_AMOUNT); collectionIndexDetails.setTodayColl(todayColl); // Last year Todays day collection todayColl = getCollectionBetweenDates(collectionDetailsRequest, DateUtils.addYears(fromDate, -1), DateUtils.addYears(toDate, -1), null, null, TOTAL_AMOUNT); collectionIndexDetails.setLyTodayColl(todayColl); /** * For collections between the date ranges if dates are sent in the request, consider the same, else calculate from * current year start date till current date+1 day */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getFromDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils .addDays(DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD), 1); } else { fromDate = DateUtils.startOfDay(financialYear.getStartingDate()); toDate = DateUtils.addDays(new Date(), 1); } // Current Year till today collection tillDateColl = getCollectionBetweenDates(collectionDetailsRequest, fromDate, toDate, null, null, TOTAL_AMOUNT); collectionIndexDetails.setCytdColl(tillDateColl); BigDecimal demandColl = calculateDemandCollection(collectionDetailsRequest, fromDate, toDate); collectionIndexDetails.setDmdColl(demandColl); collectionIndexDetails.setPntlyColl(getCollectionBetweenDates(collectionDetailsRequest, fromDate, toDate, null, null, LATE_PAYMENT_CHARGES)); // Last year till same date of todays date collection tillDateColl = getCollectionBetweenDates(collectionDetailsRequest, DateUtils.addYears(fromDate, -1), DateUtils.addYears(toDate, -1), null, null, TOTAL_AMOUNT); collectionIndexDetails.setLytdColl(tillDateColl); } /** * API provides the demand collection * @param collectionDetailsRequest * @param fromDate * @param toDate * @return BigDecimal */ private BigDecimal calculateDemandCollection(CollectionDetailsRequest collectionDetailsRequest, Date fromDate, Date toDate) { return getCollectionBetweenDates(collectionDetailsRequest, fromDate, toDate, null, null, ARREAR_AMOUNT) .add(getCollectionBetweenDates(collectionDetailsRequest, fromDate, toDate, null, null, CURRENT_AMOUNT)) .add(getCollectionBetweenDates(collectionDetailsRequest, fromDate, toDate, null, null, ARREAR_CESS)) .add(getCollectionBetweenDates(collectionDetailsRequest, fromDate, toDate, null, null, CURRENT_CESS)); } /** * Returns the consolidated collections for single day and between the 2 dates * * @param collectionDetailsRequest * @param fromDate * @param toDate * @param cityName * @return BigDecimal */ public BigDecimal getCollectionBetweenDates(CollectionDetailsRequest collectionDetailsRequest, Date fromDate, Date toDate, String cityName, String wardName, String fieldName) { BoolQueryBuilder boolQuery = prepareWhereClause(collectionDetailsRequest, COLLECTION_INDEX_NAME); boolQuery = boolQuery .filter(QueryBuilders.rangeQuery(RECEIPT_DATE).gte(DATEFORMATTER_YYYY_MM_DD.format(fromDate)) .lte(DATEFORMATTER_YYYY_MM_DD.format(toDate)).includeUpper(false)) .mustNot(QueryBuilders.matchQuery(STATUS, CANCELLED)); if (StringUtils.isNotBlank(cityName)) boolQuery = boolQuery.filter(QueryBuilders.matchQuery(CITY_NAME, cityName)); else if (StringUtils.isNotBlank(wardName)) boolQuery = boolQuery.filter(QueryBuilders.matchQuery(REVENUE_WARD, wardName)); SearchQuery searchQueryColl = new NativeSearchQueryBuilder().withIndices(COLLECTION_INDEX_NAME) .withQuery(boolQuery).addAggregation(AggregationBuilders.sum(COLLECTIONTOTAL).field(fieldName)) .build(); Aggregations collAggr = elasticsearchTemplate.query(searchQueryColl, response -> response.getAggregations()); Sum aggr = collAggr.get(COLLECTIONTOTAL); return BigDecimal.valueOf(aggr.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP); } /** * Prepares Collection Table Data * * @param collectionDetailsRequest * @return List */ public List<CollTableData> getResponseTableData(CollectionDetailsRequest collectionDetailsRequest, boolean isForMISReports) { List<CollTableData> collIndDataList = new ArrayList<>(); Date fromDate; Date toDate; Date endDate; String aggregationField = StringUtils.EMPTY; if (!isForMISReports) aggregationField = REGION_NAME; Map<String, BillCollectorIndex> wardWiseBillCollectors = new HashMap<>(); Map<String, Map<String, BigDecimal>> currYrTillDateCollDivisionMap = new HashMap<>(); Map<String, Map<String, BigDecimal>> lastYrTillDateCollDivisionMap = new HashMap<>(); Map<String, Map<String, BigDecimal>> lastFinYrCollDivisionMap = new HashMap<>(); Map<String, CollTableData> tableDataMap = new HashMap<>(); final CFinancialYear financialYear = cFinancialYearService.getFinancialYearByDate(new Date()); /** * Select the grouping based on the type parameter, by default the grouping is done based on Regions. If type is region, * group by Region, if type is district, group by District, if type is ulb, group by ULB */ if (StringUtils.isNotBlank(collectionDetailsRequest.getType())) { aggregationField = getAggregrationField(collectionDetailsRequest); } /** * As per Elastic Search functionality, to get the total collections between 2 dates, add a day to the endDate and fetch * the results For Current day's collection if dates are sent in the request, consider the toDate, else take date range * between current date +1 day */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils .addDays(DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD), 1); } else { fromDate = new Date(); toDate = DateUtils.addDays(new Date(), 1); } int noOfMonths; // For total demand Map<String, BigDecimal> totalDemandMap = getCollectionAndDemandValues(collectionDetailsRequest, fromDate, toDate, PROPERTY_TAX_INDEX_NAME, TOTAL_DEMAND, aggregationField); // For current year demand Map<String, BigDecimal> currYrTotalDemandMap = getCollectionAndDemandValues(collectionDetailsRequest, fromDate, toDate, PROPERTY_TAX_INDEX_NAME, TOTAL_DEMAND, aggregationField); // For fetching individual demands StringTerms individualDmdDetails = getIndividualDemands(collectionDetailsRequest, PROPERTY_TAX_INDEX_NAME, aggregationField, false); Map<String, Map<String, BigDecimal>> demandDivisionMap = new HashMap<>(); prepareIndividualDemandsMap(individualDmdDetails, demandDivisionMap); Map<String, BigDecimal> assessmentsCountMap = getCollectionAndDemandCountResults(collectionDetailsRequest, null, null, PROPERTY_TAX_INDEX_NAME, CONSUMER_CODE, aggregationField); //Fetch collections for property type other than Courtcases // For today's collection Map<String, BigDecimal> todayCollMap = getCollectionAndDemandValues(collectionDetailsRequest, fromDate, toDate, COLLECTION_INDEX_NAME, TOTAL_AMOUNT, aggregationField); Map<String, BigDecimal> lyTodayCollMap = getCollectionAndDemandValues(collectionDetailsRequest, DateUtils.addYears(fromDate, -1), DateUtils.addYears(toDate, -1), COLLECTION_INDEX_NAME, TOTAL_AMOUNT, aggregationField); /** * For collection and demand between the date ranges if dates are sent in the request, consider fromDate and toDate+1 , * else calculate from current year start date till current date+1 day */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getFromDate(), DATE_FORMAT_YYYYMMDD); endDate = DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils.addDays(endDate, 1); } else { fromDate = DateUtils.startOfDay(financialYear.getStartingDate()); endDate = new Date(); toDate = DateUtils.addDays(endDate, 1); } noOfMonths = DateUtils.noOfMonthsBetween(fromDate, endDate) + 1; Map<String, BigDecimal> cytdCollMap = getCollectionAndDemandValues(collectionDetailsRequest, fromDate, toDate, COLLECTION_INDEX_NAME, TOTAL_AMOUNT, aggregationField); // For fetching individual collections StringTerms collBreakupForCurrYearTillDate = getIndividualCollections(collectionDetailsRequest, fromDate, toDate, COLLECTION_INDEX_NAME, aggregationField); StringTerms collBreakupForLastYearTillDate = getIndividualCollections(collectionDetailsRequest, DateUtils.addYears(fromDate, -1), DateUtils.addYears(toDate, -1), COLLECTION_INDEX_NAME, aggregationField); StringTerms collBreakupForLastFinYear = getIndividualCollections(collectionDetailsRequest, DateUtils.addYears(financialYear.getStartingDate(), -1), DateUtils.addYears(DateUtils.addDays(financialYear.getEndingDate(), 1), -1), COLLECTION_INDEX_NAME, aggregationField); prepareIndividualCollMap(collBreakupForCurrYearTillDate, currYrTillDateCollDivisionMap, true); prepareIndividualCollMap(collBreakupForLastYearTillDate, lastYrTillDateCollDivisionMap, false); prepareIndividualCollMap(collBreakupForLastFinYear, lastFinYrCollDivisionMap, false); // For last year's till today's date collections Map<String, BigDecimal> lytdCollMap = getCollectionAndDemandValues(collectionDetailsRequest, DateUtils.addYears(fromDate, -1), DateUtils.addYears(toDate, -1), COLLECTION_INDEX_NAME, TOTAL_AMOUNT, aggregationField); // For last financial year's collections Map<String, BigDecimal> lastFinYrCollMap = getCollectionAndDemandValues(collectionDetailsRequest, DateUtils.addYears(financialYear.getStartingDate(), -1), DateUtils.addYears(DateUtils.addDays(financialYear.getEndingDate(), 1), -1), COLLECTION_INDEX_NAME, TOTAL_AMOUNT, aggregationField); // Fetch ward wise Bill Collector details for ward based grouping if (DASHBOARD_GROUPING_WARDWISE.equalsIgnoreCase(collectionDetailsRequest.getType())) wardWiseBillCollectors = getWardWiseBillCollectors(collectionDetailsRequest); if (StringUtils.isBlank(collectionDetailsRequest.getPropertyType())) setDataForCollectionTab(collectionDetailsRequest, tableDataMap, aggregationField, wardWiseBillCollectors, currYrTillDateCollDivisionMap, lastYrTillDateCollDivisionMap, lastFinYrCollDivisionMap, noOfMonths, totalDemandMap, currYrTotalDemandMap, demandDivisionMap, assessmentsCountMap, todayCollMap, lyTodayCollMap, cytdCollMap, lytdCollMap, lastFinYrCollMap); else setDataForDCBTab(collectionDetailsRequest, tableDataMap, aggregationField, wardWiseBillCollectors, currYrTillDateCollDivisionMap, lastYrTillDateCollDivisionMap, lastFinYrCollDivisionMap, noOfMonths, totalDemandMap, currYrTotalDemandMap, demandDivisionMap, assessmentsCountMap, todayCollMap, lyTodayCollMap, cytdCollMap, lytdCollMap, lastFinYrCollMap); List<String> cityDetails = getCityDetails(collectionDetailsRequest, aggregationField); if (cityDetails.size() != tableDataMap.size()) { CollTableData collTableData; for (String name : cityDetails) { if (tableDataMap.get(name) == null) { collTableData = new CollTableData(); setBoundaryDateForTable(collectionDetailsRequest, name, collTableData, aggregationField, wardWiseBillCollectors); collIndDataList.add(collTableData); } else collIndDataList.add(tableDataMap.get(name)); } } else for (Map.Entry<String, CollTableData> entry : tableDataMap.entrySet()) collIndDataList.add(entry.getValue()); return collIndDataList; } private void setDataForCollectionTab(CollectionDetailsRequest collectionDetailsRequest, Map<String, CollTableData> tableDataMap, String aggregationField, Map<String, BillCollectorIndex> wardWiseBillCollectors, Map<String, Map<String, BigDecimal>> currYrTillDateCollDivisionMap, Map<String, Map<String, BigDecimal>> lastYrTillDateCollDivisionMap, Map<String, Map<String, BigDecimal>> lastFinYrCollDivisionMap, int noOfMonths, Map<String, BigDecimal> totalDemandMap, Map<String, BigDecimal> currYrTotalDemandMap, Map<String, Map<String, BigDecimal>> demandDivisionMap, Map<String, BigDecimal> assessmentsCountMap, Map<String, BigDecimal> todayCollMap, Map<String, BigDecimal> lyTodayCollMap, Map<String, BigDecimal> cytdCollMap, Map<String, BigDecimal> lytdCollMap, Map<String, BigDecimal> lastFinYrCollMap) { String name; CollTableData collIndData; BigDecimal cyArrearColl; BigDecimal cyCurrentColl; BigDecimal cyPenaltyColl; BigDecimal cyRebate; BigDecimal cyAdvance; BigDecimal lyArrearColl; BigDecimal lyCurrentColl; BigDecimal lyPenaltyColl; BigDecimal lyRebate; BigDecimal lyAdvance; BigDecimal arrearDemand; BigDecimal currentDemand; BigDecimal arrearInterestDemand; BigDecimal currentInterestDemand; BigDecimal totalAssessments; BigDecimal currentYearTotalDemand; BigDecimal lyTotalArrearColl; BigDecimal lyTotalCurrentColl; BigDecimal lyTotalPenaltyColl; BigDecimal lyTotalRebate; BigDecimal lyTotalAdvance; for (Map.Entry<String, BigDecimal> entry : cytdCollMap.entrySet()) { collIndData = new CollTableData(); totalAssessments = BigDecimal.ZERO; arrearDemand = BigDecimal.ZERO; currentDemand = BigDecimal.ZERO; arrearInterestDemand = BigDecimal.ZERO; currentInterestDemand = BigDecimal.ZERO; cyArrearColl = BigDecimal.ZERO; cyCurrentColl = BigDecimal.ZERO; cyPenaltyColl = BigDecimal.ZERO; cyRebate = BigDecimal.ZERO; cyAdvance = BigDecimal.ZERO; lyArrearColl = BigDecimal.ZERO; lyCurrentColl = BigDecimal.ZERO; lyPenaltyColl = BigDecimal.ZERO; lyRebate = BigDecimal.ZERO; lyAdvance = BigDecimal.ZERO; lyTotalArrearColl = BigDecimal.ZERO; lyTotalCurrentColl = BigDecimal.ZERO; lyTotalPenaltyColl = BigDecimal.ZERO; lyTotalRebate = BigDecimal.ZERO; lyTotalAdvance = BigDecimal.ZERO; name = entry.getKey(); if (!assessmentsCountMap.isEmpty() && assessmentsCountMap.get(name) != null) totalAssessments = assessmentsCountMap.get(name) == null ? BigDecimal.ZERO : assessmentsCountMap.get(name); if (!currYrTillDateCollDivisionMap.isEmpty() && currYrTillDateCollDivisionMap.get(name) != null) { cyArrearColl = (currYrTillDateCollDivisionMap.get(name).get(CY_ARREAR_AMOUNT) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_ARREAR_AMOUNT)) .add(currYrTillDateCollDivisionMap.get(name).get(CY_ARREAR_CESS) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_ARREAR_CESS)); cyCurrentColl = (currYrTillDateCollDivisionMap.get(name).get(CY_CURRENT_AMOUNT) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_CURRENT_AMOUNT)) .add(currYrTillDateCollDivisionMap.get(name).get(CY_CURRENT_CESS) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_CURRENT_CESS)); cyPenaltyColl = (currYrTillDateCollDivisionMap.get(name).get(CY_PENALTY) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_PENALTY)) .add(currYrTillDateCollDivisionMap.get(name).get(CY_LATE_PAYMENT_PENALTY) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_LATE_PAYMENT_PENALTY)); cyRebate = currYrTillDateCollDivisionMap.get(name).get(CY_REBATE) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_REBATE); cyAdvance = currYrTillDateCollDivisionMap.get(name).get(CY_ADVANCE) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_ADVANCE); } //For last year till date collections if (!lastYrTillDateCollDivisionMap.isEmpty() && lastYrTillDateCollDivisionMap.get(name) != null) { lyArrearColl = (lastYrTillDateCollDivisionMap.get(name).get(LY_ARREAR_AMOUNT) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_ARREAR_AMOUNT)) .add(lastYrTillDateCollDivisionMap.get(name).get(LY_ARREAR_CESS) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_ARREAR_CESS)); lyCurrentColl = (lastYrTillDateCollDivisionMap.get(name).get(LY_CURRENT_AMOUNT) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_CURRENT_AMOUNT)) .add(lastYrTillDateCollDivisionMap.get(name).get(LY_CURRENT_CESS) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_CURRENT_CESS)); lyPenaltyColl = (lastYrTillDateCollDivisionMap.get(name).get(LY_PENALTY) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_PENALTY)) .add(lastYrTillDateCollDivisionMap.get(name).get(LY_LATE_PAYMENT_PENALTY) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_LATE_PAYMENT_PENALTY)); lyRebate = lastYrTillDateCollDivisionMap.get(name).get(LY_REBATE) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_REBATE); lyAdvance = lastYrTillDateCollDivisionMap.get(name).get(LY_ADVANCE) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_ADVANCE); } //For last financial year complete collections if (!lastFinYrCollDivisionMap.isEmpty() && lastFinYrCollDivisionMap.get(name) != null) { lyTotalArrearColl = (lastFinYrCollDivisionMap.get(name).get(LY_ARREAR_AMOUNT) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_ARREAR_AMOUNT)).add( lastFinYrCollDivisionMap.get(name).get(LY_ARREAR_CESS) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_ARREAR_CESS)); lyTotalCurrentColl = (lastFinYrCollDivisionMap.get(name).get(LY_CURRENT_AMOUNT) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_CURRENT_AMOUNT)).add( lastFinYrCollDivisionMap.get(name).get(LY_CURRENT_CESS) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_CURRENT_CESS)); lyTotalPenaltyColl = (lastFinYrCollDivisionMap.get(name).get(LY_PENALTY) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_PENALTY)) .add(lastFinYrCollDivisionMap.get(name).get(LY_LATE_PAYMENT_PENALTY) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_LATE_PAYMENT_PENALTY)); lyTotalRebate = lastFinYrCollDivisionMap.get(name).get(LY_REBATE) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_REBATE); lyTotalAdvance = lastFinYrCollDivisionMap.get(name).get(LY_ADVANCE) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_ADVANCE); } if (!demandDivisionMap.isEmpty() && demandDivisionMap.get(name) != null) { arrearDemand = demandDivisionMap.get(name).get(ARREAR_DMD) == null ? BigDecimal.ZERO : demandDivisionMap.get(name).get(ARREAR_DMD); currentDemand = demandDivisionMap.get(name).get(CURRENT_DMD) == null ? BigDecimal.ZERO : demandDivisionMap.get(name).get(CURRENT_DMD); arrearInterestDemand = demandDivisionMap.get(name).get(ARREAR_INT_DMD) == null ? BigDecimal.ZERO : demandDivisionMap.get(name).get(ARREAR_INT_DMD); currentInterestDemand = demandDivisionMap.get(name).get(CURRENT_INT_DMD) == null ? BigDecimal.ZERO : demandDivisionMap.get(name).get(CURRENT_INT_DMD); } // Proportional Demand = (totalDemand/12)*noOfmonths currentYearTotalDemand = currYrTotalDemandMap.get(name) == null ? BigDecimal.valueOf(0) : currYrTotalDemandMap.get(name); setBoundaryDateForTable(collectionDetailsRequest, name, collIndData, aggregationField, wardWiseBillCollectors); setCollAmountsForTableData(collIndData, todayCollMap.get(name) == null ? BigDecimal.ZERO : todayCollMap.get(name), lyTodayCollMap.get(name) == null ? BigDecimal.ZERO : lyTodayCollMap.get(name), entry.getValue(), lytdCollMap.get(name) == null ? BigDecimal.ZERO : lytdCollMap.get(name), lastFinYrCollMap.get(name) == null ? BigDecimal.ZERO : lastFinYrCollMap.get(name)); setCurrYearTillDateCollBreakUpForTableData(collIndData, cyArrearColl, cyCurrentColl, cyPenaltyColl, cyRebate, cyAdvance); setLastYearTillDateCollBreakUpForTableData(collIndData, lyArrearColl, lyCurrentColl, lyPenaltyColl, lyRebate, lyAdvance); setLastFinYearCollBreakUpForTableData(collIndData, lyTotalArrearColl, lyTotalCurrentColl, lyTotalPenaltyColl, lyTotalRebate, lyTotalAdvance); setDemandBreakUpForTableData(collIndData, arrearDemand, currentDemand, arrearInterestDemand, currentInterestDemand, noOfMonths); setDemandAmountsForTableData(name, collIndData, totalAssessments, currentYearTotalDemand, noOfMonths, totalDemandMap); tableDataMap.put(name, collIndData); } } private void setDataForDCBTab(CollectionDetailsRequest collectionDetailsRequest, Map<String, CollTableData> tableDataMap, String aggregationField, Map<String, BillCollectorIndex> wardWiseBillCollectors, Map<String, Map<String, BigDecimal>> currYrTillDateCollDivisionMap, Map<String, Map<String, BigDecimal>> lastYrTillDateCollDivisionMap, Map<String, Map<String, BigDecimal>> lastFinYrCollDivisionMap, int noOfMonths, Map<String, BigDecimal> totalDemandMap, Map<String, BigDecimal> currYrTotalDemandMap, Map<String, Map<String, BigDecimal>> demandDivisionMap, Map<String, BigDecimal> assessmentsCountMap, Map<String, BigDecimal> todayCollMap, Map<String, BigDecimal> lyTodayCollMap, Map<String, BigDecimal> cytdCollMap, Map<String, BigDecimal> lytdCollMap, Map<String, BigDecimal> lastFinYrCollMap) { String name; CollTableData collIndData; BigDecimal cyArrearColl; BigDecimal cyCurrentColl; BigDecimal cyPenaltyColl; BigDecimal cyRebate; BigDecimal cyAdvance; BigDecimal lyArrearColl; BigDecimal lyCurrentColl; BigDecimal lyPenaltyColl; BigDecimal lyRebate; BigDecimal lyAdvance; BigDecimal arrearDemand; BigDecimal currentDemand; BigDecimal arrearInterestDemand; BigDecimal currentInterestDemand; BigDecimal totalAssessments; BigDecimal cytdColl; BigDecimal lyTotalArrearColl; BigDecimal lyTotalCurrentColl; BigDecimal lyTotalPenaltyColl; BigDecimal lyTotalRebate; BigDecimal lyTotalAdvance; for (Map.Entry<String, BigDecimal> entry : currYrTotalDemandMap.entrySet()) { collIndData = new CollTableData(); totalAssessments = BigDecimal.ZERO; arrearDemand = BigDecimal.ZERO; currentDemand = BigDecimal.ZERO; arrearInterestDemand = BigDecimal.ZERO; currentInterestDemand = BigDecimal.ZERO; cyArrearColl = BigDecimal.ZERO; cyCurrentColl = BigDecimal.ZERO; cyPenaltyColl = BigDecimal.ZERO; cyRebate = BigDecimal.ZERO; cyAdvance = BigDecimal.ZERO; lyArrearColl = BigDecimal.ZERO; lyCurrentColl = BigDecimal.ZERO; lyPenaltyColl = BigDecimal.ZERO; lyRebate = BigDecimal.ZERO; lyAdvance = BigDecimal.ZERO; lyTotalArrearColl = BigDecimal.ZERO; lyTotalCurrentColl = BigDecimal.ZERO; lyTotalPenaltyColl = BigDecimal.ZERO; lyTotalRebate = BigDecimal.ZERO; lyTotalAdvance = BigDecimal.ZERO; name = entry.getKey(); if (!assessmentsCountMap.isEmpty() && assessmentsCountMap.get(name) != null) totalAssessments = assessmentsCountMap.get(name) == null ? BigDecimal.ZERO : assessmentsCountMap.get(name); if (!currYrTillDateCollDivisionMap.isEmpty() && currYrTillDateCollDivisionMap.get(name) != null) { cyArrearColl = (currYrTillDateCollDivisionMap.get(name).get(CY_ARREAR_AMOUNT) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_ARREAR_AMOUNT)) .add(currYrTillDateCollDivisionMap.get(name).get(CY_ARREAR_CESS) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_ARREAR_CESS)); cyCurrentColl = (currYrTillDateCollDivisionMap.get(name).get(CY_CURRENT_AMOUNT) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_CURRENT_AMOUNT)) .add(currYrTillDateCollDivisionMap.get(name).get(CY_CURRENT_CESS) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_CURRENT_CESS)); cyPenaltyColl = (currYrTillDateCollDivisionMap.get(name).get(CY_PENALTY) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_PENALTY)) .add(currYrTillDateCollDivisionMap.get(name).get(CY_LATE_PAYMENT_PENALTY) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_LATE_PAYMENT_PENALTY)); cyRebate = currYrTillDateCollDivisionMap.get(name).get(CY_REBATE) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_REBATE); cyAdvance = currYrTillDateCollDivisionMap.get(name).get(CY_ADVANCE) == null ? BigDecimal.ZERO : currYrTillDateCollDivisionMap.get(name).get(CY_ADVANCE); } //For last year till date collections if (!lastYrTillDateCollDivisionMap.isEmpty() && lastYrTillDateCollDivisionMap.get(name) != null) { lyArrearColl = (lastYrTillDateCollDivisionMap.get(name).get(LY_ARREAR_AMOUNT) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_ARREAR_AMOUNT)) .add(lastYrTillDateCollDivisionMap.get(name).get(LY_ARREAR_CESS) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_ARREAR_CESS)); lyCurrentColl = (lastYrTillDateCollDivisionMap.get(name).get(LY_CURRENT_AMOUNT) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_CURRENT_AMOUNT)) .add(lastYrTillDateCollDivisionMap.get(name).get(LY_CURRENT_CESS) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_CURRENT_CESS)); lyPenaltyColl = (lastYrTillDateCollDivisionMap.get(name).get(LY_PENALTY) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_PENALTY)) .add(lastYrTillDateCollDivisionMap.get(name).get(LY_LATE_PAYMENT_PENALTY) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_LATE_PAYMENT_PENALTY)); lyRebate = lastYrTillDateCollDivisionMap.get(name).get(LY_REBATE) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_REBATE); lyAdvance = lastYrTillDateCollDivisionMap.get(name).get(LY_ADVANCE) == null ? BigDecimal.ZERO : lastYrTillDateCollDivisionMap.get(name).get(LY_ADVANCE); } //For last financial year complete collections if (!lastFinYrCollDivisionMap.isEmpty() && lastFinYrCollDivisionMap.get(name) != null) { lyTotalArrearColl = (lastFinYrCollDivisionMap.get(name).get(LY_ARREAR_AMOUNT) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_ARREAR_AMOUNT)).add( lastFinYrCollDivisionMap.get(name).get(LY_ARREAR_CESS) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_ARREAR_CESS)); lyTotalCurrentColl = (lastFinYrCollDivisionMap.get(name).get(LY_CURRENT_AMOUNT) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_CURRENT_AMOUNT)).add( lastFinYrCollDivisionMap.get(name).get(LY_CURRENT_CESS) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_CURRENT_CESS)); lyTotalPenaltyColl = (lastFinYrCollDivisionMap.get(name).get(LY_PENALTY) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_PENALTY)) .add(lastFinYrCollDivisionMap.get(name).get(LY_LATE_PAYMENT_PENALTY) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_LATE_PAYMENT_PENALTY)); lyTotalRebate = lastFinYrCollDivisionMap.get(name).get(LY_REBATE) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_REBATE); lyTotalAdvance = lastFinYrCollDivisionMap.get(name).get(LY_ADVANCE) == null ? BigDecimal.ZERO : lastFinYrCollDivisionMap.get(name).get(LY_ADVANCE); } if (!demandDivisionMap.isEmpty() && demandDivisionMap.get(name) != null) { arrearDemand = demandDivisionMap.get(name).get(ARREAR_DMD) == null ? BigDecimal.ZERO : demandDivisionMap.get(name).get(ARREAR_DMD); currentDemand = demandDivisionMap.get(name).get(CURRENT_DMD) == null ? BigDecimal.ZERO : demandDivisionMap.get(name).get(CURRENT_DMD); arrearInterestDemand = demandDivisionMap.get(name).get(ARREAR_INT_DMD) == null ? BigDecimal.ZERO : demandDivisionMap.get(name).get(ARREAR_INT_DMD); currentInterestDemand = demandDivisionMap.get(name).get(CURRENT_INT_DMD) == null ? BigDecimal.ZERO : demandDivisionMap.get(name).get(CURRENT_INT_DMD); } cytdColl = cytdCollMap.get(name) == null ? BigDecimal.valueOf(0) : cytdCollMap.get(name); setBoundaryDateForTable(collectionDetailsRequest, name, collIndData, aggregationField, wardWiseBillCollectors); setCollAmountsForTableData(collIndData, todayCollMap.get(name) == null ? BigDecimal.ZERO : todayCollMap.get(name), lyTodayCollMap.get(name) == null ? BigDecimal.ZERO : lyTodayCollMap.get(name), cytdColl, lytdCollMap.get(name) == null ? BigDecimal.ZERO : lytdCollMap.get(name), lastFinYrCollMap.get(name) == null ? BigDecimal.ZERO : lastFinYrCollMap.get(name)); setCurrYearTillDateCollBreakUpForTableData(collIndData, cyArrearColl, cyCurrentColl, cyPenaltyColl, cyRebate, cyAdvance); setLastYearTillDateCollBreakUpForTableData(collIndData, lyArrearColl, lyCurrentColl, lyPenaltyColl, lyRebate, lyAdvance); setLastFinYearCollBreakUpForTableData(collIndData, lyTotalArrearColl, lyTotalCurrentColl, lyTotalPenaltyColl, lyTotalRebate, lyTotalAdvance); setDemandBreakUpForTableData(collIndData, arrearDemand, currentDemand, arrearInterestDemand, currentInterestDemand, noOfMonths); setDemandAmountsForTableData(name, collIndData, totalAssessments, entry.getValue(), noOfMonths, totalDemandMap); tableDataMap.put(name, collIndData); } } private void setDemandAmountsForTableData(String name, CollTableData collIndData, BigDecimal totalAssessments, BigDecimal currentYearTotalDemand, int noOfMonths, Map<String, BigDecimal> totalDemandMap) { BigDecimal variance; // Proportional Demand = (totalDemand/12)*noOfmonths BigDecimal cytdDmd = (currentYearTotalDemand.divide(BigDecimal.valueOf(12), BigDecimal.ROUND_HALF_UP)) .multiply(BigDecimal.valueOf(noOfMonths)); collIndData.setCytdDmd(cytdDmd); if (cytdDmd != BigDecimal.valueOf(0)) { BigDecimal balance = cytdDmd.subtract(collIndData.getCytdColl()); BigDecimal performance = (collIndData.getCytdColl().multiply(PropertyTaxConstants.BIGDECIMAL_100)) .divide(cytdDmd, 1, BigDecimal.ROUND_HALF_UP); collIndData.setPerformance(performance); collIndData.setCytdBalDmd(balance); } collIndData.setTotalDmd(totalDemandMap.get(name) == null ? BigDecimal.ZERO : totalDemandMap.get(name)); collIndData.setDayTargetDemand(collIndData.getTotalDmd().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : collIndData.getTotalDmd().divide(new BigDecimal("365"), 0, BigDecimal.ROUND_HALF_UP)); collIndData.setTotalAssessments(totalAssessments); // variance = ((currentYearCollection - lastYearCollection)*100)/lastYearCollection if (collIndData.getLytdColl().compareTo(BigDecimal.ZERO) == 0) variance = PropertyTaxConstants.BIGDECIMAL_100; else variance = ((collIndData.getCytdColl().subtract(collIndData.getLytdColl())) .multiply(PropertyTaxConstants.BIGDECIMAL_100)).divide(collIndData.getLytdColl(), 1, BigDecimal.ROUND_HALF_UP); collIndData.setLyVar(variance); } private void setDemandBreakUpForTableData(CollTableData collIndData, BigDecimal arrearDemand, BigDecimal currentDemand, BigDecimal arrearInterestDemand, BigDecimal currentInterestDemand, int noOfMonths) { collIndData.setArrearDemand(arrearDemand); collIndData.setCurrentDemand(currentDemand); collIndData.setArrearInterestDemand(arrearInterestDemand); collIndData.setCurrentInterestDemand(currentInterestDemand); BigDecimal proportionalArrearDmd = (collIndData.getArrearDemand().divide(BigDecimal.valueOf(12), BigDecimal.ROUND_HALF_UP)).multiply(BigDecimal.valueOf(noOfMonths)); BigDecimal proportionalCurrDmd = (collIndData.getCurrentDemand().divide(BigDecimal.valueOf(12), BigDecimal.ROUND_HALF_UP)).multiply(BigDecimal.valueOf(noOfMonths)); collIndData.setProportionalArrearDemand(proportionalArrearDmd); collIndData.setProportionalCurrentDemand(proportionalCurrDmd); } private void setCurrYearTillDateCollBreakUpForTableData(CollTableData collIndData, BigDecimal arrearColl, BigDecimal currentColl, BigDecimal penaltyColl, BigDecimal rebate, BigDecimal advanceColl) { collIndData.setCyArrearColl(arrearColl); collIndData.setCyCurrentColl(currentColl); collIndData.setCyPenaltyColl(penaltyColl); collIndData.setCyRebate(rebate.abs()); collIndData.setCyAdvanceColl(advanceColl); } private void setLastYearTillDateCollBreakUpForTableData(CollTableData collIndData, BigDecimal arrearColl, BigDecimal currentColl, BigDecimal penaltyColl, BigDecimal rebate, BigDecimal advanceColl) { collIndData.setLyArrearColl(arrearColl); collIndData.setLyCurrentColl(currentColl); collIndData.setLyPenaltyColl(penaltyColl); collIndData.setLyRebate(rebate.abs()); collIndData.setLyAdvanceColl(advanceColl); } private void setLastFinYearCollBreakUpForTableData(CollTableData collIndData, BigDecimal lyTotalArrearColl, BigDecimal lyTotalCurrentColl, BigDecimal lyTotalPenaltyColl, BigDecimal lyTotalRebate, BigDecimal lyTotalAdvanceColl) { collIndData.setLyTotalArrearsColl(lyTotalArrearColl); collIndData.setLyTotalCurrentColl(lyTotalCurrentColl); collIndData.setLyTotalPenaltyColl(lyTotalPenaltyColl); collIndData.setLyTotalRebate(lyTotalRebate.abs()); collIndData.setLyTotalAdvanceColl(lyTotalAdvanceColl); } private void setCollAmountsForTableData(CollTableData collIndData, BigDecimal todayColl, BigDecimal lyTodayColl, BigDecimal cytdColl, BigDecimal lytdColl, BigDecimal lyTotalColl) { collIndData.setTodayColl(todayColl); collIndData.setLyTodayColl(lyTodayColl); collIndData.setCytdColl(cytdColl); collIndData.setLytdColl(lytdColl); collIndData.setLyTotalColl(lyTotalColl); } private void setBoundaryDateForTable(CollectionDetailsRequest collectionDetailsRequest, String name, CollTableData collIndData, String aggregationField, Map<String, BillCollectorIndex> wardWiseBillCollectors) { if (REGION_NAME.equals(aggregationField)) collIndData.setRegionName(name); else if (DISTRICT_NAME.equals(aggregationField)) { collIndData.setRegionName(collectionDetailsRequest.getRegionName()); collIndData.setDistrictName(name); } else if (CITY_NAME.equals(aggregationField)) { collIndData.setUlbName(name); collIndData.setDistrictName(collectionDetailsRequest.getDistrictName()); collIndData.setUlbGrade(collectionDetailsRequest.getUlbGrade()); } else if (CITY_GRADE.equals(aggregationField)) collIndData.setUlbGrade(name); else if (REVENUE_WARD.equals(aggregationField)) { collIndData.setWardName(name); // If the grouping is based on ward, set the Bill Collector name and number if (DASHBOARD_GROUPING_WARDWISE.equalsIgnoreCase(collectionDetailsRequest.getType()) && !wardWiseBillCollectors.isEmpty()) { collIndData.setBillCollector(wardWiseBillCollectors.get(name) == null ? StringUtils.EMPTY : wardWiseBillCollectors.get(name).getBillCollector()); collIndData.setBillCollMobNo(wardWiseBillCollectors.get(name) == null ? StringUtils.EMPTY : wardWiseBillCollectors.get(name).getBillCollectorMobileNo()); collIndData.setRevenueInspector(wardWiseBillCollectors.get(name) == null ? StringUtils.EMPTY : wardWiseBillCollectors.get(name).getRevenueInspector()); collIndData.setRevInspectorMobNo(wardWiseBillCollectors.get(name) == null ? StringUtils.EMPTY : wardWiseBillCollectors.get(name).getRevenueInspectorMobileNo()); collIndData.setRevenueOfficer(wardWiseBillCollectors.get(name) == null ? StringUtils.EMPTY : wardWiseBillCollectors.get(name).getRevenueOfficer()); collIndData.setRevOfficerMobNo(wardWiseBillCollectors.get(name) == null ? StringUtils.EMPTY : wardWiseBillCollectors.get(name).getRevenueOfficerMobileNo()); } } collIndData.setBoundaryName(name); } public String getAggregrationField(CollectionDetailsRequest collectionDetailsRequest) { String aggregationField = REGION_NAME; if (collectionDetailsRequest.getType().equalsIgnoreCase(DASHBOARD_GROUPING_REGIONWISE)) aggregationField = REGION_NAME; else if (collectionDetailsRequest.getType().equalsIgnoreCase(DASHBOARD_GROUPING_DISTRICTWISE)) aggregationField = DISTRICT_NAME; else if (collectionDetailsRequest.getType().equalsIgnoreCase(DASHBOARD_GROUPING_ULBWISE)) aggregationField = CITY_NAME; else if (collectionDetailsRequest.getType().equalsIgnoreCase(DASHBOARD_GROUPING_GRADEWISE)) aggregationField = CITY_GRADE; else if (collectionDetailsRequest.getType().equalsIgnoreCase(DASHBOARD_GROUPING_WARDWISE) || collectionDetailsRequest.getType().equalsIgnoreCase(DASHBOARD_GROUPING_BILLCOLLECTORWISE) || DASHBOARD_GROUPING_REVENUEINSPECTORWISE.equalsIgnoreCase(collectionDetailsRequest.getType()) || DASHBOARD_GROUPING_REVENUEOFFICERWISE.equalsIgnoreCase(collectionDetailsRequest.getType())) aggregationField = REVENUE_WARD; return aggregationField; } /** * Prepares the map for individual demands * @param individualDmdDetails * @param demandDivisionMap */ public void prepareIndividualDemandsMap(StringTerms individualDmdDetails, Map<String, Map<String, BigDecimal>> demandDivisionMap) { Map<String, BigDecimal> individualDmdMap; Sum arrearDmd; Sum currentDmd; Sum arrearInterestDmd; Sum currentInterestDmd; if (individualDmdDetails != null) { for (Terms.Bucket entry : individualDmdDetails.getBuckets()) { individualDmdMap = new HashMap<>(); arrearDmd = entry.getAggregations().get(ARREARDMD); currentDmd = entry.getAggregations().get(CURR_DMD); arrearInterestDmd = entry.getAggregations().get(ARREAR_INTEREST_DMD); currentInterestDmd = entry.getAggregations().get(CURR_INTEREST_DMD); individualDmdMap.put(ARREAR_DMD, BigDecimal.valueOf(arrearDmd.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); individualDmdMap.put(CURRENT_DMD, BigDecimal.valueOf(currentDmd.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); individualDmdMap.put(ARREAR_INT_DMD, BigDecimal.valueOf(arrearInterestDmd.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); individualDmdMap.put(CURRENT_INT_DMD, BigDecimal.valueOf(currentInterestDmd.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); demandDivisionMap.put(String.valueOf(entry.getKey()), individualDmdMap); } } } /** * Prepares the map for individual collections * @param individualCollDetails * @param collectionDivisionMap */ public void prepareIndividualCollMap(StringTerms collBreakup, Map<String, Map<String, BigDecimal>> collectionDivisionMap, boolean isForCurrYear) { if (collBreakup != null) prepareCollBreakupMap(collBreakup, collectionDivisionMap, isForCurrYear); } private void prepareCollBreakupMap(StringTerms collBreakup, Map<String, Map<String, BigDecimal>> collectionDivisionMap, boolean isForCurrYear) { Map<String, BigDecimal> individualCollMap; Sum arrearAmt; Sum currentAmt; Sum arrearCess; Sum currentCess; Sum penaltyAmt; Sum latePaymentPenaltyAmt; Sum rebate; Sum advance; String arrearAmtKey; String currentAmtKey; String arrearCessKey; String currentCessKey; String penaltyAmtKey; String latePaymentPenaltyAmtKey; String rebateAmtKey; String advanceAmtKey; if (isForCurrYear) { arrearAmtKey = CY_ARREAR_AMOUNT; currentAmtKey = CY_CURRENT_AMOUNT; arrearCessKey = CY_ARREAR_CESS; currentCessKey = CY_CURRENT_CESS; penaltyAmtKey = CY_PENALTY; latePaymentPenaltyAmtKey = CY_LATE_PAYMENT_PENALTY; rebateAmtKey = CY_REBATE; advanceAmtKey = CY_ADVANCE; } else { arrearAmtKey = LY_ARREAR_AMOUNT; currentAmtKey = LY_CURRENT_AMOUNT; arrearCessKey = LY_ARREAR_CESS; currentCessKey = LY_CURRENT_CESS; penaltyAmtKey = LY_PENALTY; latePaymentPenaltyAmtKey = LY_LATE_PAYMENT_PENALTY; rebateAmtKey = LY_REBATE; advanceAmtKey = LY_ADVANCE; } for (Terms.Bucket entry : collBreakup.getBuckets()) { individualCollMap = new HashMap<>(); arrearAmt = entry.getAggregations().get(ARREAR_AMOUNT_CONST); currentAmt = entry.getAggregations().get(CURR_AMOUNT); arrearCess = entry.getAggregations().get(ARREAR_CESS_CONST); currentCess = entry.getAggregations().get(CURR_CESS); penaltyAmt = entry.getAggregations().get("penalty"); latePaymentPenaltyAmt = entry.getAggregations().get("latePaymentPenalty"); rebate = entry.getAggregations().get(REBATE); advance = entry.getAggregations().get(ADVANCE); individualCollMap.put(arrearAmtKey, BigDecimal.valueOf(arrearAmt.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); individualCollMap.put(currentAmtKey, BigDecimal.valueOf(currentAmt.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); individualCollMap.put(arrearCessKey, BigDecimal.valueOf(arrearCess.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); individualCollMap.put(currentCessKey, BigDecimal.valueOf(currentCess.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); individualCollMap.put(penaltyAmtKey, BigDecimal.valueOf(penaltyAmt.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); individualCollMap.put(latePaymentPenaltyAmtKey, BigDecimal.valueOf(latePaymentPenaltyAmt.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); individualCollMap.put(rebateAmtKey, BigDecimal.valueOf(rebate.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); individualCollMap.put(advanceAmtKey, BigDecimal.valueOf(advance.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); collectionDivisionMap.put(String.valueOf(entry.getKey()), individualCollMap); } } /** * Provides collection and demand results * * @param collectionDetailsRequest * @param fromDate * @param toDate * @param indexName * @param fieldName * @param ulbCodeField * @param aggregationField * @return Map */ public Map<String, BigDecimal> getCollectionAndDemandValues(CollectionDetailsRequest collectionDetailsRequest, Date fromDate, Date toDate, String indexName, String fieldName, String aggregationField) { BoolQueryBuilder boolQuery = prepareWhereClause(collectionDetailsRequest, indexName); if (indexName.equals(COLLECTION_INDEX_NAME)) boolQuery = boolQuery .filter(QueryBuilders.rangeQuery(RECEIPT_DATE).gte(DATEFORMATTER_YYYY_MM_DD.format(fromDate)) .lte(DATEFORMATTER_YYYY_MM_DD.format(toDate)).includeUpper(false)) .mustNot(QueryBuilders.matchQuery(STATUS, CANCELLED)); else boolQuery = boolQuery.filter(QueryBuilders.matchQuery(IS_ACTIVE, true)) .filter(QueryBuilders.matchQuery(IS_EXEMPTED, false)); AggregationBuilder aggregation = AggregationBuilders.terms(BY_CITY).field(aggregationField).size(120) .subAggregation(AggregationBuilders.sum("total").field(fieldName)); SearchQuery searchQueryColl = new NativeSearchQueryBuilder().withIndices(indexName).withQuery(boolQuery) .addAggregation(aggregation).build(); Aggregations collAggr = elasticsearchTemplate.query(searchQueryColl, new ResultsExtractor<Aggregations>() { @Override public Aggregations extract(SearchResponse response) { return response.getAggregations(); } }); StringTerms cityAggr = collAggr.get(BY_CITY); Map<String, BigDecimal> cytdCollMap = new HashMap<>(); for (Terms.Bucket entry : cityAggr.getBuckets()) { Sum aggr = entry.getAggregations().get("total"); cytdCollMap.put(String.valueOf(entry.getKey()), BigDecimal.valueOf(aggr.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); } return cytdCollMap; } /** * Provides collection break-up of total amount * @param collectionDetailsRequest * @param fromDate * @param toDate * @param indexName * @param aggregationField * @return StringTerms */ public StringTerms getIndividualCollections(CollectionDetailsRequest collectionDetailsRequest, Date fromDate, Date toDate, String indexName, String aggregationField) { BoolQueryBuilder boolQuery = prepareWhereClause(collectionDetailsRequest, indexName); if (indexName.equals(COLLECTION_INDEX_NAME)) boolQuery = boolQuery .filter(QueryBuilders.rangeQuery(RECEIPT_DATE).gte(DATEFORMATTER_YYYY_MM_DD.format(fromDate)) .lte(DATEFORMATTER_YYYY_MM_DD.format(toDate)).includeUpper(false)) .mustNot(QueryBuilders.matchQuery(STATUS, CANCELLED)); else boolQuery = boolQuery.filter(QueryBuilders.matchQuery(IS_ACTIVE, true)) .filter(QueryBuilders.matchQuery(IS_EXEMPTED, false)); AggregationBuilder aggregation = AggregationBuilders.terms(BY_CITY).field(aggregationField).size(120) .subAggregation(AggregationBuilders.sum(ARREAR_AMOUNT_CONST).field(ARREAR_AMOUNT)) .subAggregation(AggregationBuilders.sum(CURR_AMOUNT).field(CURRENT_AMOUNT)) .subAggregation(AggregationBuilders.sum(ARREAR_CESS_CONST).field(ARREAR_CESS)) .subAggregation(AggregationBuilders.sum(CURR_CESS).field(CURRENT_CESS)) .subAggregation(AggregationBuilders.sum("penalty").field("penaltyAmount")) .subAggregation(AggregationBuilders.sum("latePaymentPenalty").field(LATE_PAYMENT_CHARGES)) .subAggregation(AggregationBuilders.sum(REBATE).field("reductionAmount")) .subAggregation(AggregationBuilders.sum(ADVANCE).field("advanceAmount")); SearchQuery searchQueryColl = new NativeSearchQueryBuilder().withIndices(indexName).withQuery(boolQuery) .addAggregation(aggregation).build(); Aggregations collAggr = elasticsearchTemplate.query(searchQueryColl, response -> response.getAggregations()); return collAggr.get(BY_CITY); } /** * Provides demand break-up of total amount * @param collectionDetailsRequest * @param indexName * @param aggregationField * @return StringTerms */ public StringTerms getIndividualDemands(CollectionDetailsRequest collectionDetailsRequest, String indexName, String aggregationField, boolean isForMis) { AggregationBuilder aggregation; BoolQueryBuilder boolQuery = prepareWhereClause(collectionDetailsRequest, indexName); boolQuery = boolQuery.filter(QueryBuilders.matchQuery(IS_ACTIVE, true)) .filter(QueryBuilders.matchQuery(IS_EXEMPTED, false)); if (isForMis) aggregation = AggregationBuilders.terms(BY_CITY).field(aggregationField).size(120) .subAggregation(AggregationBuilders.sum(ARREARDMD).field("arrearDemand")) .subAggregation(AggregationBuilders.sum(CURR_DMD).field("annualDemand")) .subAggregation(AggregationBuilders.sum(ARREAR_INTEREST_DMD).field("arrearInterestDemand")) .subAggregation(AggregationBuilders.sum(CURR_INTEREST_DMD).field("currentInterestDemand")) .subAggregation(AggregationBuilders.sum("total_dmd").field(TOTAL_DEMAND)) .subAggregation(AggregationBuilders.sum("adjustment").field("adjustment")) .subAggregation(AggregationBuilders.sum("arrear_coll").field("arrearCollection")) .subAggregation(AggregationBuilders.sum("curr_coll").field("annualCollection")) .subAggregation( AggregationBuilders.sum("arrear_interest_coll").field("arrearInterestCollection")) .subAggregation( AggregationBuilders.sum("curr_interest_coll").field("currentInterestCollection")) .subAggregation(AggregationBuilders.sum(ADVANCE).field(ADVANCE)) .subAggregation(AggregationBuilders.sum(REBATE).field(REBATE)) .subAggregation(AggregationBuilders.sum("total_coll").field("totalCollection")); else aggregation = AggregationBuilders.terms(BY_CITY).field(aggregationField).size(120) .subAggregation(AggregationBuilders.sum(ARREARDMD).field("arrearDemand")) .subAggregation(AggregationBuilders.sum(CURR_DMD).field("annualDemand")) .subAggregation(AggregationBuilders.sum(ARREAR_INTEREST_DMD).field("arrearInterestDemand")) .subAggregation(AggregationBuilders.sum(CURR_INTEREST_DMD).field("currentInterestDemand")); SearchQuery searchQueryColl = new NativeSearchQueryBuilder().withIndices(indexName).withQuery(boolQuery) .addAggregation(aggregation).build(); Aggregations collAggr = elasticsearchTemplate.query(searchQueryColl, new ResultsExtractor<Aggregations>() { @Override public Aggregations extract(SearchResponse response) { return response.getAggregations(); } }); return collAggr.get(BY_CITY); } /** * Prepares month-wise collections for 3 consecutive years - from current year * * @param collectionDetailsRequest * @return List */ public List<CollectionTrend> getMonthwiseCollectionDetails(CollectionDetailsRequest collectionDetailsRequest) { List<CollectionTrend> collTrendsList = new ArrayList<>(); Date fromDate; Date toDate; Date dateForMonth; String[] dateArr; Integer month; Sum aggregateSum; String aggregationField = StringUtils.EMPTY; CFinancialYear financialYear; Map<Integer, String> monthValuesMap = DateUtils.getAllMonthsWithFullNames(); String monthName; List<Map<String, BigDecimal>> yearwiseMonthlyCollList = new ArrayList<>(); Map<String, BigDecimal> monthwiseColl; if (StringUtils.isNotBlank(collectionDetailsRequest.getType())) aggregationField = getAggregrationField(collectionDetailsRequest); /** * For month-wise collections between the date ranges if dates are sent in the request, consider fromDate and toDate+1 , * else calculate from current year start date till current date+1 day */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getFromDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils .addDays(DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD), 1); financialYear = cFinancialYearService.getFinancialYearByDate(fromDate); } else { financialYear = cFinancialYearService.getFinancialYearByDate(new Date()); fromDate = DateUtils.startOfDay(financialYear.getStartingDate()); toDate = DateUtils.addDays(new Date(), 1); } Date finYearStartDate = financialYear.getStartingDate(); Date finYearEndDate = financialYear.getEndingDate(); for (int count = 0; count <= 2; count++) { monthwiseColl = new LinkedHashMap<>(); Aggregations collAggr = getMonthwiseCollectionsForConsecutiveYears(collectionDetailsRequest, fromDate, toDate, false, null, aggregationField); Histogram dateaggs = collAggr.get(DATE_AGG); for (Histogram.Bucket entry : dateaggs.getBuckets()) { dateArr = entry.getKeyAsString().split("T"); dateForMonth = DateUtils.getDate(dateArr[0], DATE_FORMAT_YYYYMMDD); month = Integer.valueOf(dateArr[0].split("-", 3)[1]); monthName = monthValuesMap.get(month); aggregateSum = entry.getAggregations().get(CURRENT_TOTAL); // If the total amount is greater than 0 and the month belongs // to respective financial year, add values to the map if (DateUtils.between(dateForMonth, finYearStartDate, finYearEndDate) && BigDecimal.valueOf(aggregateSum.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP) .compareTo(BigDecimal.ZERO) > 0) monthwiseColl.put(monthName, BigDecimal.valueOf(aggregateSum.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); } yearwiseMonthlyCollList.add(monthwiseColl); /** * If dates are passed in request, get result for the date range, else get results for entire financial year */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.addYears(fromDate, -1); toDate = DateUtils.addYears(toDate, -1); } else { fromDate = DateUtils.addYears(finYearStartDate, -1); toDate = DateUtils.addYears(DateUtils.addDays(finYearEndDate, 1), -1); } finYearStartDate = DateUtils.addYears(finYearStartDate, -1); finYearEndDate = DateUtils.addYears(finYearEndDate, -1); } populateCollTrends(collectionDetailsRequest, collTrendsList, yearwiseMonthlyCollList); return collTrendsList; } private void populateCollTrends(CollectionDetailsRequest collectionDetailsRequest, List<CollectionTrend> collTrendsList, List<Map<String, BigDecimal>> yearwiseMonthlyCollList) { CollectionTrend collTrend; /** * If dates are passed in request, get result for the date range, else get results for all 12 months */ if (StringUtils.isBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isBlank(collectionDetailsRequest.getToDate())) { for (Map.Entry<Integer, String> entry : DateUtils.getAllFinancialYearMonthsWithFullNames().entrySet()) { collTrend = new CollectionTrend(); setCollTrends(collTrend, entry.getValue(), yearwiseMonthlyCollList.get(0).get(entry.getValue()) == null ? BigDecimal.ZERO : yearwiseMonthlyCollList.get(0).get(entry.getValue()), yearwiseMonthlyCollList.get(1).get(entry.getValue()) == null ? BigDecimal.ZERO : yearwiseMonthlyCollList.get(1).get(entry.getValue()), yearwiseMonthlyCollList.get(2).get(entry.getValue()) == null ? BigDecimal.ZERO : yearwiseMonthlyCollList.get(2).get(entry.getValue())); collTrendsList.add(collTrend); } } else { for (Map.Entry<String, BigDecimal> entry : yearwiseMonthlyCollList.get(0).entrySet()) { collTrend = new CollectionTrend(); setCollTrends(collTrend, entry.getKey(), entry.getValue(), yearwiseMonthlyCollList.get(1).get(entry.getKey()) == null ? BigDecimal.ZERO : yearwiseMonthlyCollList.get(1).get(entry.getKey()), yearwiseMonthlyCollList.get(2).get(entry.getKey()) == null ? BigDecimal.ZERO : yearwiseMonthlyCollList.get(2).get(entry.getKey())); collTrendsList.add(collTrend); } } } private void setCollTrends(CollectionTrend collTrend, String month, BigDecimal cyColl, BigDecimal lyColl, BigDecimal pyColl) { collTrend.setMonth(month); collTrend.setCyColl(cyColl); collTrend.setLyColl(lyColl); collTrend.setPyColl(pyColl); } /** * Provides month-wise collections for consecutive years * * @param collectionDetailsRequest * @param fromDate * @param toDate * @return SearchResponse */ private Aggregations getMonthwiseCollectionsForConsecutiveYears( CollectionDetailsRequest collectionDetailsRequest, Date fromDate, Date toDate, boolean isForMISReports, String intervalType, String aggregationField) { AggregationBuilder aggregationBuilder; BoolQueryBuilder boolQuery = prepareWhereClause(collectionDetailsRequest, COLLECTION_INDEX_NAME); boolQuery = boolQuery .filter(QueryBuilders.rangeQuery(RECEIPT_DATE).gte(DATEFORMATTER_YYYY_MM_DD.format(fromDate)) .lte(DATEFORMATTER_YYYY_MM_DD.format(toDate)).includeUpper(false)) .mustNot(QueryBuilders.matchQuery(STATUS, CANCELLED)); //In case of MIS APIs, grouping will be done based on interval type if (isForMISReports) { DateHistogramInterval interval = null; if (StringUtils.isNotBlank(intervalType)) { if (MONTH.equalsIgnoreCase(intervalType)) interval = DateHistogramInterval.MONTH; else if (WEEK.equalsIgnoreCase(intervalType)) interval = DateHistogramInterval.WEEK; else if (DAY.equalsIgnoreCase(intervalType)) interval = DateHistogramInterval.DAY; } aggregationBuilder = AggregationBuilders.terms(BY_CITY).field(aggregationField).size(120) .subAggregation( AggregationBuilders.dateHistogram(DATE_AGG).field(RECEIPT_DATE).interval(interval) .subAggregation(AggregationBuilders.sum(CURRENT_TOTAL).field(TOTAL_AMOUNT))); } else aggregationBuilder = AggregationBuilders.dateHistogram(DATE_AGG).field(RECEIPT_DATE) .interval(DateHistogramInterval.MONTH) .subAggregation(AggregationBuilders.sum(CURRENT_TOTAL).field(TOTAL_AMOUNT)); SearchQuery searchQueryColl = new NativeSearchQueryBuilder().withIndices(COLLECTION_INDEX_NAME) .withQuery(boolQuery).addAggregation(aggregationBuilder).build(); return elasticsearchTemplate.query(searchQueryColl, response -> response.getAggregations()); } /** * Provides receipts count * * @param collectionDetailsRequest * @param receiptDetails */ public void getTotalReceiptsCount(CollectionDetailsRequest collectionDetailsRequest, CollReceiptDetails receiptDetails) { Date fromDate; Date toDate; CFinancialYear financialYear = cFinancialYearService.getFinancialYearByDate(new Date()); /** * As per Elastic Search functionality, to get the total collections between 2 dates, add a day to the endDate and fetch * the results For Current day's collection if dates are sent in the request, consider the dates as toDate and toDate+1, * else take date range between current date +1 day */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils .addDays(DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD), 1); } else { fromDate = new Date(); toDate = DateUtils.addDays(new Date(), 1); } // Todays receipts count Long receiptsCount = getTotalReceiptCountsForDates(collectionDetailsRequest, fromDate, toDate); receiptDetails.setTodayRcptsCount(receiptsCount); /** * For collections between the date ranges if dates are sent in the request, consider the same, else calculate from * current year start date till current date+1 day */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getFromDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils .addDays(DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD), 1); } else { fromDate = DateUtils.startOfDay(financialYear.getStartingDate()); toDate = DateUtils.addDays(new Date(), 1); } // Current Year till today receipt count receiptsCount = getTotalReceiptCountsForDates(collectionDetailsRequest, fromDate, toDate); receiptDetails.setCytdRcptsCount(receiptsCount); // Receipts count for last year's same date receiptsCount = getTotalReceiptCountsForDates(collectionDetailsRequest, DateUtils.addYears(fromDate, -1), DateUtils.addYears(toDate, -1)); receiptDetails.setLytdRcptsCount(receiptsCount); } /** * Gives the total count of receipts * * @param collectionDetailsRequest * @param fromDate * @param toDate * @return receipt count */ private Long getTotalReceiptCountsForDates(CollectionDetailsRequest collectionDetailsRequest, Date fromDate, Date toDate) { BoolQueryBuilder boolQuery = prepareWhereClause(collectionDetailsRequest, COLLECTION_INDEX_NAME); boolQuery = boolQuery .filter(QueryBuilders.rangeQuery(RECEIPT_DATE).gte(DATEFORMATTER_YYYY_MM_DD.format(fromDate)) .lte(DATEFORMATTER_YYYY_MM_DD.format(toDate)).includeUpper(false)) .mustNot(QueryBuilders.matchQuery(STATUS, CANCELLED)); SearchQuery searchQueryColl = new NativeSearchQueryBuilder().withIndices(COLLECTION_INDEX_NAME) .withQuery(boolQuery).addAggregation(AggregationBuilders.count(RECEIPT_COUNT).field(CONSUMER_CODE)) .build(); Aggregations collCountAggr = elasticsearchTemplate.query(searchQueryColl, new ResultsExtractor<Aggregations>() { @Override public Aggregations extract(SearchResponse response) { return response.getAggregations(); } }); ValueCount aggr = collCountAggr.get(RECEIPT_COUNT); return Long.valueOf(aggr.getValue()); } /** * Gives month-wise receipts count * * @param collectionDetailsRequest * @return list */ public List<ReceiptsTrend> getMonthwiseReceiptsTrend(CollectionDetailsRequest collectionDetailsRequest) { List<ReceiptsTrend> rcptTrendsList = new ArrayList<>(); ReceiptsTrend rcptsTrend; Date fromDate; Date toDate; Date dateForMonth; String[] dateArr; Integer month; Long rcptCount; String monthName; Map<String, Long> monthwiseCount; CFinancialYear financialYear = cFinancialYearService.getFinancialYearByDate(new Date()); Date finYearStartDate = financialYear.getStartingDate(); Date finYearEndDate = financialYear.getEndingDate(); Map<Integer, String> monthValuesMap = DateUtils.getAllMonthsWithFullNames(); List<Map<String, Long>> yearwiseMonthlyCountList = new ArrayList<>(); /** * For month-wise collections between the date ranges if dates are sent in the request, consider fromDate and toDate+1 , * else calculate from current year start date till current date+1 day */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getFromDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils .addDays(DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD), 1); } else { fromDate = DateUtils.startOfDay(financialYear.getStartingDate()); toDate = DateUtils.addDays(new Date(), 1); } for (int count = 0; count <= 2; count++) { monthwiseCount = new LinkedHashMap<>(); Aggregations collAggregation = getReceiptsCountForConsecutiveYears(collectionDetailsRequest, fromDate, toDate); Histogram dateaggs = collAggregation.get(DATE_AGG); for (Histogram.Bucket entry : dateaggs.getBuckets()) { dateArr = entry.getKeyAsString().split("T"); dateForMonth = DateUtils.getDate(dateArr[0], DATE_FORMAT_YYYYMMDD); month = Integer.valueOf(dateArr[0].split("-", 3)[1]); monthName = monthValuesMap.get(month); rcptCount = entry.getDocCount(); // If the receipt count is greater than 0 and the month belongs // to respective financial year, add values to the map if (DateUtils.between(dateForMonth, finYearStartDate, finYearEndDate) && rcptCount > 0) monthwiseCount.put(monthName, rcptCount); } yearwiseMonthlyCountList.add(monthwiseCount); /** * If dates are passed in request, get result for the date range, else get results for entire financial year */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.addYears(fromDate, -1); toDate = DateUtils.addYears(toDate, -1); } else { fromDate = DateUtils.addYears(finYearStartDate, -1); toDate = DateUtils.addYears(finYearEndDate, -1); } finYearStartDate = DateUtils.addYears(finYearStartDate, -1); finYearEndDate = DateUtils.addYears(finYearEndDate, -1); } /** * If dates are passed in request, get result for the date range, else get results for all 12 months */ if (StringUtils.isBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isBlank(collectionDetailsRequest.getToDate())) { for (Map.Entry<Integer, String> entry : DateUtils.getAllFinancialYearMonthsWithFullNames().entrySet()) { rcptsTrend = new ReceiptsTrend(); rcptsTrend.setMonth(entry.getValue()); rcptsTrend.setCyRcptsCount(yearwiseMonthlyCountList.get(0).get(rcptsTrend.getMonth()) == null ? 0L : yearwiseMonthlyCountList.get(0).get(rcptsTrend.getMonth())); rcptsTrend.setLyRcptsCount(yearwiseMonthlyCountList.get(1).get(rcptsTrend.getMonth()) == null ? 0L : yearwiseMonthlyCountList.get(1).get(rcptsTrend.getMonth())); rcptsTrend.setPyRcptsCount(yearwiseMonthlyCountList.get(2).get(rcptsTrend.getMonth()) == null ? 0L : yearwiseMonthlyCountList.get(2).get(rcptsTrend.getMonth())); rcptTrendsList.add(rcptsTrend); } } else { for (Map.Entry<String, Long> entry : yearwiseMonthlyCountList.get(0).entrySet()) { rcptsTrend = new ReceiptsTrend(); rcptsTrend.setMonth(entry.getKey()); rcptsTrend.setCyRcptsCount(entry.getValue()); rcptsTrend.setLyRcptsCount(yearwiseMonthlyCountList.get(1).get(rcptsTrend.getMonth()) == null ? 0L : yearwiseMonthlyCountList.get(1).get(rcptsTrend.getMonth())); rcptsTrend.setPyRcptsCount(yearwiseMonthlyCountList.get(2).get(rcptsTrend.getMonth()) == null ? 0L : yearwiseMonthlyCountList.get(2).get(rcptsTrend.getMonth())); rcptTrendsList.add(rcptsTrend); } } return rcptTrendsList; } /** * Provides month-wise receipts count for consecutive years * * @param collectionDetailsRequest * @param fromDate * @param toDate * @return SearchResponse */ private Aggregations getReceiptsCountForConsecutiveYears(CollectionDetailsRequest collectionDetailsRequest, Date fromDate, Date toDate) { BoolQueryBuilder boolQuery = prepareWhereClause(collectionDetailsRequest, COLLECTION_INDEX_NAME); boolQuery = boolQuery.mustNot(QueryBuilders.matchQuery(STATUS, CANCELLED)); AggregationBuilder monthAggregation = AggregationBuilders.dateHistogram(DATE_AGG).field(RECEIPT_DATE) .interval(DateHistogramInterval.MONTH) .subAggregation(AggregationBuilders.count(RECEIPT_COUNT).field("receiptNumber")); SearchQuery searchQueryColl = new NativeSearchQueryBuilder().withIndices(COLLECTION_INDEX_NAME) .withQuery(boolQuery.filter( QueryBuilders.rangeQuery(RECEIPT_DATE).gte(DATEFORMATTER_YYYY_MM_DD.format(fromDate)) .lte(DATEFORMATTER_YYYY_MM_DD.format(toDate)).includeUpper(false))) .addAggregation(monthAggregation).build(); return elasticsearchTemplate.query(searchQueryColl, new ResultsExtractor<Aggregations>() { @Override public Aggregations extract(SearchResponse response) { return response.getAggregations(); } }); } /** * Populates Receipt Table Details * * @param collectionDetailsRequest * @return list */ public List<ReceiptTableData> getReceiptTableData(CollectionDetailsRequest collectionDetailsRequest) { ReceiptTableData receiptData; List<ReceiptTableData> receiptDataList = new ArrayList<>(); Date fromDate; Date toDate; String name; BigDecimal variance; String aggregationField = REGION_NAME; final CFinancialYear financialYear = cFinancialYearService.getFinancialYearByDate(new Date()); /** * Select the grouping based on the type parameter, by default the grouping is done based on Regions. If type is region, * group by Region, if type is district, group by District, if type is ulb, group by ULB */ if (StringUtils.isNotBlank(collectionDetailsRequest.getType())) { if (collectionDetailsRequest.getType().equalsIgnoreCase(DASHBOARD_GROUPING_REGIONWISE)) aggregationField = REGION_NAME; else if (collectionDetailsRequest.getType().equalsIgnoreCase(DASHBOARD_GROUPING_DISTRICTWISE)) aggregationField = DISTRICT_NAME; else if (collectionDetailsRequest.getType().equalsIgnoreCase(DASHBOARD_GROUPING_ULBWISE)) aggregationField = CITY_NAME; else if (collectionDetailsRequest.getType().equalsIgnoreCase(DASHBOARD_GROUPING_GRADEWISE)) aggregationField = CITY_GRADE; else if (collectionDetailsRequest.getType().equalsIgnoreCase(DASHBOARD_GROUPING_WARDWISE)) aggregationField = REVENUE_WARD; } /** * For Current day's collection if dates are sent in the request, consider the toDate, else take date range between * current date +1 day */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getFromDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils .addDays(DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD), 1); } else { fromDate = new Date(); toDate = DateUtils.addDays(new Date(), 1); } Map<String, BigDecimal> currDayCollMap = getCollectionAndDemandCountResults(collectionDetailsRequest, fromDate, toDate, COLLECTION_INDEX_NAME, CONSUMER_CODE, aggregationField); /** * For collections between the date ranges if dates are sent in the request, consider the same, else calculate from * current year start date till current date+1 day */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getFromDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils .addDays(DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD), 1); } else { fromDate = DateUtils.startOfDay(financialYear.getStartingDate()); toDate = DateUtils.addDays(new Date(), 1); } Map<String, BigDecimal> cytdCollMap = getCollectionAndDemandCountResults(collectionDetailsRequest, fromDate, toDate, COLLECTION_INDEX_NAME, CONSUMER_CODE, aggregationField); // For last year's till date collections Map<String, BigDecimal> lytdCollMap = getCollectionAndDemandCountResults(collectionDetailsRequest, DateUtils.addYears(fromDate, -1), DateUtils.addYears(toDate, -1), COLLECTION_INDEX_NAME, CONSUMER_CODE, aggregationField); for (Map.Entry<String, BigDecimal> entry : cytdCollMap.entrySet()) { receiptData = new ReceiptTableData(); name = entry.getKey(); if (aggregationField.equals(REGION_NAME)) receiptData.setRegionName(name); else if (aggregationField.equals(DISTRICT_NAME)) { receiptData.setRegionName(collectionDetailsRequest.getRegionName()); receiptData.setDistrictName(name); } else if (aggregationField.equals(CITY_NAME)) { receiptData.setUlbName(name); receiptData.setDistrictName(collectionDetailsRequest.getDistrictName()); receiptData.setUlbGrade(collectionDetailsRequest.getUlbGrade()); } else if (aggregationField.equals(CITY_GRADE)) receiptData.setUlbGrade(name); else if (aggregationField.equals(REVENUE_WARD)) receiptData.setWardName(name); receiptData.setCytdColl(entry.getValue()); receiptData.setCurrDayColl( currDayCollMap.get(name) == null ? BigDecimal.valueOf(0) : currDayCollMap.get(name)); receiptData.setLytdColl(lytdCollMap.get(name) == null ? BigDecimal.valueOf(0) : lytdCollMap.get(name)); // variance = ((currentYearCollection // -lastYearCollection)*100)/lastYearCollection if (receiptData.getLytdColl().compareTo(BigDecimal.ZERO) == 0) variance = PropertyTaxConstants.BIGDECIMAL_100; else variance = ((receiptData.getCytdColl().subtract(receiptData.getLytdColl())) .multiply(PropertyTaxConstants.BIGDECIMAL_100)).divide(receiptData.getLytdColl(), 1, BigDecimal.ROUND_HALF_UP); receiptData.setLyVar(variance); receiptDataList.add(receiptData); } return receiptDataList; } public Map<String, BigDecimal> getCollectionAndDemandCountResults( CollectionDetailsRequest collectionDetailsRequest, Date fromDate, Date toDate, String indexName, String fieldName, String aggregationField) { BoolQueryBuilder boolQuery = prepareWhereClause(collectionDetailsRequest, indexName); if (indexName.equals(COLLECTION_INDEX_NAME)) boolQuery = boolQuery .filter(QueryBuilders.rangeQuery(RECEIPT_DATE).gte(DATEFORMATTER_YYYY_MM_DD.format(fromDate)) .lte(DATEFORMATTER_YYYY_MM_DD.format(toDate)).includeUpper(false)) .mustNot(QueryBuilders.matchQuery(STATUS, CANCELLED)); else if (indexName.equals(PROPERTY_TAX_INDEX_NAME)) boolQuery = boolQuery.filter(QueryBuilders.matchQuery(IS_ACTIVE, true)) .filter(QueryBuilders.matchQuery(IS_EXEMPTED, false)); AggregationBuilder aggregation = AggregationBuilders.terms(BY_CITY).field(aggregationField).size(120) .subAggregation(AggregationBuilders.count("total_count").field(fieldName)); SearchQuery searchQueryColl = new NativeSearchQueryBuilder().withIndices(indexName).withQuery(boolQuery) .addAggregation(aggregation).build(); Aggregations collAggr = elasticsearchTemplate.query(searchQueryColl, new ResultsExtractor<Aggregations>() { @Override public Aggregations extract(SearchResponse response) { return response.getAggregations(); } }); StringTerms cityAggr = collAggr.get(BY_CITY); Map<String, BigDecimal> cytdCollMap = new HashMap<>(); for (Terms.Bucket entry : cityAggr.getBuckets()) { ValueCount aggr = entry.getAggregations().get("total_count"); cytdCollMap.put(String.valueOf(entry.getKey()), BigDecimal.valueOf(aggr.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); } return cytdCollMap; } /** * Populates Receipt Table Details for type - Bill Collector * * @param collectionDetailsRequest * @return list */ public List<CollTableData> getResponseTableDataForBillCollector( CollectionDetailsRequest collectionDetailsRequest) { Map<String, CollTableData> wardReceiptDetails = new HashMap<>(); Map<String, List<CollTableData>> billCollectorWiseMap = new LinkedHashMap<>(); List<CollTableData> collDetails = new ArrayList<>(); List<CollTableData> billCollectorWiseTableData = new ArrayList<>(); CollTableData collTableData; String userNameAndNumber = StringUtils.EMPTY; /** * Fetch the Ward-wise data */ List<CollTableData> wardWiseData = getResponseTableData(collectionDetailsRequest, false); for (CollTableData tableData : wardWiseData) { wardReceiptDetails.put(tableData.getWardName(), tableData); } /** * prepare bill collector wise collection table data */ List<BillCollectorIndex> billCollectorsList = getBillCollectorDetails(collectionDetailsRequest); for (BillCollectorIndex billCollIndex : billCollectorsList) { if (wardReceiptDetails.get(billCollIndex.getRevenueWard()) != null && StringUtils.isNotBlank(billCollIndex.getRevenueWard())) { if (DASHBOARD_GROUPING_BILLCOLLECTORWISE.equalsIgnoreCase(collectionDetailsRequest.getType())) userNameAndNumber = billCollIndex.getBillCollector().concat("~") .concat(StringUtils.isBlank(billCollIndex.getBillCollectorMobileNo()) ? StringUtils.EMPTY : billCollIndex.getBillCollectorMobileNo()); else if (DASHBOARD_GROUPING_REVENUEINSPECTORWISE .equalsIgnoreCase(collectionDetailsRequest.getType())) userNameAndNumber = (StringUtils.isBlank(billCollIndex.getRevenueInspector()) ? StringUtils.EMPTY : billCollIndex.getRevenueInspector()) .concat("~") .concat(StringUtils.isBlank(billCollIndex.getRevenueInspectorMobileNo()) ? StringUtils.EMPTY : billCollIndex.getRevenueInspectorMobileNo()); else if (DASHBOARD_GROUPING_REVENUEOFFICERWISE.equalsIgnoreCase(collectionDetailsRequest.getType())) userNameAndNumber = (StringUtils.isBlank(billCollIndex.getRevenueOfficer()) ? StringUtils.EMPTY : billCollIndex.getRevenueOfficer()) .concat("~") .concat(StringUtils.isBlank(billCollIndex.getRevenueOfficerMobileNo()) ? StringUtils.EMPTY : billCollIndex.getRevenueOfficerMobileNo()); if (billCollectorWiseMap.isEmpty()) { collDetails.add(wardReceiptDetails.get(billCollIndex.getRevenueWard())); billCollectorWiseMap.put(userNameAndNumber, collDetails); } else { if (!billCollectorWiseMap.containsKey(userNameAndNumber)) { collDetails = new ArrayList<>(); collDetails.add(wardReceiptDetails.get(billCollIndex.getRevenueWard())); billCollectorWiseMap.put(userNameAndNumber, collDetails); } else { billCollectorWiseMap.get(userNameAndNumber) .add(wardReceiptDetails.get(billCollIndex.getRevenueWard())); } } } } for (Entry<String, List<CollTableData>> entry : billCollectorWiseMap.entrySet()) { collTableData = new CollTableData(); setTableValuesForBillCollector(collTableData, entry, collectionDetailsRequest.getType()); billCollectorWiseTableData.add(collTableData); } return billCollectorWiseTableData; } private void setTableValuesForBillCollector(CollTableData collTableData, Entry<String, List<CollTableData>> entry, String aggregationLevel) { BigDecimal currDayColl = BigDecimal.ZERO; BigDecimal cytdColl = BigDecimal.ZERO; BigDecimal lytdColl = BigDecimal.ZERO; BigDecimal cytdDmd = BigDecimal.ZERO; BigDecimal performance; BigDecimal totalDmd = BigDecimal.ZERO; BigDecimal variance; BigDecimal cyArrearColl = BigDecimal.ZERO; BigDecimal cyCurrentColl = BigDecimal.ZERO; BigDecimal cyPenaltyColl = BigDecimal.ZERO; BigDecimal cyRebate = BigDecimal.ZERO; BigDecimal cyAdvance = BigDecimal.ZERO; BigDecimal lyArrearColl = BigDecimal.ZERO; BigDecimal lyCurrentColl = BigDecimal.ZERO; BigDecimal lyPenaltyColl = BigDecimal.ZERO; BigDecimal lyRebate = BigDecimal.ZERO; BigDecimal lyAdvance = BigDecimal.ZERO; BigDecimal arrearDmd = BigDecimal.ZERO; BigDecimal currentDmd = BigDecimal.ZERO; BigDecimal proportionalArrearDmd = BigDecimal.ZERO; BigDecimal proportionalCurrentDmd = BigDecimal.ZERO; BigDecimal dayTargetDmd = BigDecimal.ZERO; BigDecimal lyTodayColl = BigDecimal.ZERO; BigDecimal totalAssessments = BigDecimal.ZERO; BigDecimal arrearInterestDemand = BigDecimal.ZERO; BigDecimal currentInterestDemand = BigDecimal.ZERO; BigDecimal lyTotalArrearColl = BigDecimal.ZERO; BigDecimal lyTotalCurrentColl = BigDecimal.ZERO; BigDecimal lyTotalPenaltyColl = BigDecimal.ZERO; BigDecimal lyTotalRebate = BigDecimal.ZERO; BigDecimal lyTotalAdvance = BigDecimal.ZERO; BigDecimal lyTotalColl = BigDecimal.ZERO; String[] userNameNumberArr = entry.getKey().split("~"); for (CollTableData tableData : entry.getValue()) { currDayColl = currDayColl .add(tableData.getTodayColl() == null ? BigDecimal.ZERO : tableData.getTodayColl()); cytdColl = cytdColl.add(tableData.getCytdColl() == null ? BigDecimal.ZERO : tableData.getCytdColl()); cytdDmd = cytdDmd.add(tableData.getCytdDmd() == null ? BigDecimal.ZERO : tableData.getCytdDmd()); totalDmd = totalDmd.add(tableData.getTotalDmd() == null ? BigDecimal.ZERO : tableData.getTotalDmd()); lytdColl = lytdColl.add(tableData.getLytdColl() == null ? BigDecimal.ZERO : tableData.getLytdColl()); lyTotalColl = lyTotalColl .add(tableData.getLyTotalColl() == null ? BigDecimal.ZERO : tableData.getLyTotalColl()); cyArrearColl = cyArrearColl .add(tableData.getCyArrearColl() == null ? BigDecimal.ZERO : tableData.getCyArrearColl()); cyCurrentColl = cyCurrentColl .add(tableData.getCyCurrentColl() == null ? BigDecimal.ZERO : tableData.getCyCurrentColl()); cyPenaltyColl = cyPenaltyColl .add(tableData.getCyPenaltyColl() == null ? BigDecimal.ZERO : tableData.getCyPenaltyColl()); cyRebate = cyRebate.add(tableData.getCyRebate() == null ? BigDecimal.ZERO : tableData.getCyRebate()); cyAdvance = cyAdvance .add(tableData.getCyAdvanceColl() == null ? BigDecimal.ZERO : tableData.getCyAdvanceColl()); lyArrearColl = lyArrearColl .add(tableData.getLyArrearColl() == null ? BigDecimal.ZERO : tableData.getLyArrearColl()); lyCurrentColl = lyCurrentColl .add(tableData.getLyCurrentColl() == null ? BigDecimal.ZERO : tableData.getLyCurrentColl()); lyPenaltyColl = lyPenaltyColl .add(tableData.getLyPenaltyColl() == null ? BigDecimal.ZERO : tableData.getLyPenaltyColl()); lyRebate = lyRebate.add(tableData.getLyRebate() == null ? BigDecimal.ZERO : tableData.getLyRebate()); lyAdvance = lyAdvance .add(tableData.getLyAdvanceColl() == null ? BigDecimal.ZERO : tableData.getLyAdvanceColl()); lyTotalArrearColl = lyTotalArrearColl.add(tableData.getLyTotalArrearsColl() == null ? BigDecimal.ZERO : tableData.getLyTotalArrearsColl()); lyTotalCurrentColl = lyTotalCurrentColl.add(tableData.getLyTotalCurrentColl() == null ? BigDecimal.ZERO : tableData.getLyTotalCurrentColl()); lyTotalPenaltyColl = lyTotalPenaltyColl.add(tableData.getLyTotalPenaltyColl() == null ? BigDecimal.ZERO : tableData.getLyTotalPenaltyColl()); lyTotalRebate = lyTotalRebate .add(tableData.getLyTotalRebate() == null ? BigDecimal.ZERO : tableData.getLyTotalRebate()); lyTotalAdvance = lyTotalAdvance.add(tableData.getLyTotalAdvanceColl() == null ? BigDecimal.ZERO : tableData.getLyTotalAdvanceColl()); arrearDmd = arrearDmd .add(tableData.getArrearDemand() == null ? BigDecimal.ZERO : tableData.getArrearDemand()); currentDmd = currentDmd .add(tableData.getCurrentDemand() == null ? BigDecimal.ZERO : tableData.getCurrentDemand()); proportionalArrearDmd = proportionalArrearDmd .add(tableData.getProportionalArrearDemand() == null ? BigDecimal.ZERO : tableData.getProportionalArrearDemand()); proportionalCurrentDmd = proportionalCurrentDmd .add(tableData.getProportionalCurrentDemand() == null ? BigDecimal.ZERO : tableData.getProportionalCurrentDemand()); dayTargetDmd = dayTargetDmd .add(tableData.getDayTargetDemand() == null ? BigDecimal.ZERO : tableData.getDayTargetDemand()); lyTodayColl = lyTodayColl .add(tableData.getLyTodayColl() == null ? BigDecimal.ZERO : tableData.getLyTodayColl()); totalAssessments = totalAssessments.add(tableData.getTotalAssessments()); arrearInterestDemand = arrearInterestDemand .add(tableData.getArrearInterestDemand() == null ? BigDecimal.ZERO : tableData.getArrearInterestDemand()); currentInterestDemand = currentInterestDemand .add(tableData.getCurrentInterestDemand() == null ? BigDecimal.ZERO : tableData.getCurrentInterestDemand()); } if (DASHBOARD_GROUPING_BILLCOLLECTORWISE.equalsIgnoreCase(aggregationLevel)) { collTableData.setBillCollector(userNameNumberArr[0]); collTableData.setBillCollMobNo(userNameNumberArr.length > 1 ? userNameNumberArr[1] : StringUtils.EMPTY); } else if (DASHBOARD_GROUPING_REVENUEINSPECTORWISE.equalsIgnoreCase(aggregationLevel)) { collTableData.setRevenueInspector(userNameNumberArr[0]); collTableData .setRevInspectorMobNo(userNameNumberArr.length > 1 ? userNameNumberArr[1] : StringUtils.EMPTY); } else if (DASHBOARD_GROUPING_REVENUEOFFICERWISE.equalsIgnoreCase(aggregationLevel)) { collTableData.setRevenueOfficer(userNameNumberArr[0]); collTableData .setRevOfficerMobNo(userNameNumberArr.length > 1 ? userNameNumberArr[1] : StringUtils.EMPTY); } collTableData.setTodayColl(currDayColl); collTableData.setCytdColl(cytdColl); collTableData.setCytdDmd(cytdDmd); collTableData.setCytdBalDmd(cytdDmd.subtract(cytdColl)); collTableData.setTotalDmd(totalDmd); collTableData.setLytdColl(lytdColl); setCurrYearTillDateCollBreakUpForTableData(collTableData, cyArrearColl, cyCurrentColl, cyPenaltyColl, cyRebate, cyAdvance); setLastYearTillDateCollBreakUpForTableData(collTableData, lyArrearColl, lyCurrentColl, lyPenaltyColl, lyRebate, lyAdvance); setLastFinYearCollBreakUpForTableData(collTableData, lyTotalArrearColl, lyTotalCurrentColl, lyTotalPenaltyColl, lyTotalRebate, lyTotalAdvance); collTableData.setArrearDemand(arrearDmd); collTableData.setCurrentDemand(currentDmd); collTableData.setProportionalArrearDemand(proportionalArrearDmd); collTableData.setProportionalCurrentDemand(proportionalCurrentDmd); collTableData.setDayTargetDemand(dayTargetDmd); collTableData.setLyTodayColl(lyTodayColl); collTableData.setArrearInterestDemand(arrearInterestDemand); collTableData.setCurrentInterestDemand(currentInterestDemand); collTableData.setTotalAssessments(totalAssessments); if (cytdDmd != BigDecimal.valueOf(0)) { performance = (collTableData.getCytdColl().multiply(PropertyTaxConstants.BIGDECIMAL_100)) .divide(cytdDmd, 1, BigDecimal.ROUND_HALF_UP); collTableData.setPerformance(performance); } if (collTableData.getLytdColl().compareTo(BigDecimal.ZERO) == 0) variance = PropertyTaxConstants.BIGDECIMAL_100; else variance = ((collTableData.getCytdColl().subtract(collTableData.getLytdColl())) .multiply(PropertyTaxConstants.BIGDECIMAL_100)).divide(collTableData.getLytdColl(), 1, BigDecimal.ROUND_HALF_UP); collTableData.setLyVar(variance); } /** * Fetches BillCollector and revenue ward details for thgiven ulbCode * * @param collectionDetailsRequest * @return List */ public List<BillCollectorIndex> getBillCollectorDetails(CollectionDetailsRequest collectionDetailsRequest) { String sortField = REVENUE_WARD; if (DASHBOARD_GROUPING_BILLCOLLECTORWISE.equalsIgnoreCase(collectionDetailsRequest.getType())) sortField = "billCollector"; else if (DASHBOARD_GROUPING_REVENUEINSPECTORWISE.equalsIgnoreCase(collectionDetailsRequest.getType())) sortField = "revenueInspector"; else if (DASHBOARD_GROUPING_REVENUEOFFICERWISE.equalsIgnoreCase(collectionDetailsRequest.getType())) sortField = "revenueOfficer"; SearchQuery searchQueryColl = new NativeSearchQueryBuilder() .withIndices(PropertyTaxConstants.BILL_COLLECTOR_INDEX_NAME) .withQuery(QueryBuilders.boolQuery() .filter(QueryBuilders.matchQuery(CITY_CODE, collectionDetailsRequest.getUlbCode()))) .withSort(new FieldSortBuilder(sortField).order(SortOrder.ASC)) .withPageable(new PageRequest(0, 250)).build(); return elasticsearchTemplate.queryForList(searchQueryColl, BillCollectorIndex.class); } /** * Fetches Ward wise Bill Colelctor details * @param collectionDetailsRequest * @return Map */ public Map<String, BillCollectorIndex> getWardWiseBillCollectors( CollectionDetailsRequest collectionDetailsRequest) { Map<String, BillCollectorIndex> wardWiseBillCollectors = new HashMap<>(); List<BillCollectorIndex> billCollectors = getBillCollectorDetails(collectionDetailsRequest); for (BillCollectorIndex billCollector : billCollectors) { wardWiseBillCollectors.put(billCollector.getRevenueWard(), billCollector); } return wardWiseBillCollectors; } /** * Gives the total count of assessments * @param collectionDetailsRequest * @return assessments count */ public Long getTotalAssessmentsCount(CollectionDetailsRequest collectionDetailsRequest) { BoolQueryBuilder boolQuery = prepareWhereClause(collectionDetailsRequest, PROPERTY_TAX_INDEX_NAME) .filter(QueryBuilders.matchQuery(IS_ACTIVE, true)) .filter(QueryBuilders.matchQuery(IS_EXEMPTED, false)); SearchQuery searchQueryColl = new NativeSearchQueryBuilder().withIndices(PROPERTY_TAX_INDEX_NAME) .withQuery(boolQuery) .addAggregation(AggregationBuilders.count("assessment_count").field(CONSUMER_CODE)).build(); Aggregations collCountAggr = elasticsearchTemplate.query(searchQueryColl, response -> response.getAggregations()); ValueCount aggr = collCountAggr.get("assessment_count"); return Long.valueOf(aggr.getValue()); } /** * Provides city wise collection details * @param collectionDetailsRequest * @param intervalType * @return List */ public CollectionAnalysis getCollectionsForInterval(CollectionDetailsRequest collectionDetailsRequest, String intervalType) { Date fromDate = null; Date toDate = null; String aggregationField = StringUtils.EMPTY; if (StringUtils.isNotBlank(collectionDetailsRequest.getType())) aggregationField = getAggregrationField(collectionDetailsRequest); Map<Integer, String> monthValuesMap = DateUtils.getAllMonthsWithFullNames(); Map<String, Map<String, BigDecimal>> intervalwiseCollMap = new HashMap<>(); CollectionAnalysis collectionAnalysis = new CollectionAnalysis(); /** * For collections between 2 dates, consider fromDate and toDate+1 */ if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getFromDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils .addDays(DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD), 1); } CFinancialYear financialYear = cFinancialYearService.getFinancialYearByDate(fromDate); Aggregations collAggr = getMonthwiseCollectionsForConsecutiveYears(collectionDetailsRequest, fromDate, toDate, true, intervalType, aggregationField); StringTerms cityaggr = collAggr.get(BY_CITY); if (MONTH.equalsIgnoreCase(intervalType)) { prepareMonthlyCollMap(financialYear.getStartingDate(), financialYear.getEndingDate(), monthValuesMap, intervalwiseCollMap, cityaggr); setCollectionsForMonths(intervalwiseCollMap, collectionAnalysis); } else if (WEEK.equalsIgnoreCase(intervalType)) { prepareWeeklyCollMap(intervalwiseCollMap, cityaggr); setCollectionsForWeeks(intervalwiseCollMap, collectionAnalysis); } else if (DAY.equalsIgnoreCase(intervalType)) { prepareDailyCollMap(intervalwiseCollMap, cityaggr, fromDate); setCollectionsForDays(intervalwiseCollMap, collectionAnalysis); } return collectionAnalysis; } /** * Prepares month wise collection map * @param finYearStartDate * @param finYearEndDate * @param monthValuesMap * @param yearwiseMonthlyCollMap * @param cityaggr */ private void prepareMonthlyCollMap(Date finYearStartDate, Date finYearEndDate, Map<Integer, String> monthValuesMap, Map<String, Map<String, BigDecimal>> yearwiseMonthlyCollMap, StringTerms cityaggr) { Date dateForMonth; String[] dateArr; Integer month; Sum aggregateSum; String monthName; Map<String, BigDecimal> monthwiseColl; for (Terms.Bucket cityDetailsentry : cityaggr.getBuckets()) { String ulbName = cityDetailsentry.getKeyAsString(); monthwiseColl = new LinkedHashMap<>(); Histogram dateaggs = cityDetailsentry.getAggregations().get(DATE_AGG); for (Histogram.Bucket entry : dateaggs.getBuckets()) { dateArr = entry.getKeyAsString().split("T"); dateForMonth = DateUtils.getDate(dateArr[0], DATE_FORMAT_YYYYMMDD); month = Integer.valueOf(dateArr[0].split("-", 3)[1]); monthName = monthValuesMap.get(month); aggregateSum = entry.getAggregations().get(CURRENT_TOTAL); // If the total amount is greater than 0 and the month belongs // to respective financial year, add values to the map if (DateUtils.between(dateForMonth, finYearStartDate, finYearEndDate) && BigDecimal.valueOf(aggregateSum.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP) .compareTo(BigDecimal.ZERO) > 0) { monthwiseColl.put(monthName, BigDecimal.valueOf(aggregateSum.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); } } yearwiseMonthlyCollMap.put(ulbName, monthwiseColl); } } /** * Prepares weekwise collection map * @param intervalwiseCollMap * @param cityaggr */ private void prepareWeeklyCollMap(Map<String, Map<String, BigDecimal>> intervalwiseCollMap, StringTerms cityaggr) { String weekName; int noOfWeeks; String ulbName; Sum aggregateSum; Map<String, BigDecimal> weekwiseColl; for (final Terms.Bucket cityDetailsentry : cityaggr.getBuckets()) { weekwiseColl = new LinkedHashMap<>(); ulbName = cityDetailsentry.getKeyAsString(); noOfWeeks = 0; Histogram dateaggs = cityDetailsentry.getAggregations().get(DATE_AGG); for (Histogram.Bucket entry : dateaggs.getBuckets()) { if (noOfWeeks == 0) noOfWeeks = 1; weekName = "Week " + noOfWeeks; aggregateSum = entry.getAggregations().get(CURRENT_TOTAL); if (BigDecimal.valueOf(aggregateSum.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP) .compareTo(BigDecimal.ZERO) > 0) { weekwiseColl.put(weekName, BigDecimal.valueOf(aggregateSum.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); } noOfWeeks++; } intervalwiseCollMap.put(ulbName, weekwiseColl); } } /** * Prepares collection details for each day in a week * @param intervalwiseCollMap * @param cityaggr * @param fromDate */ private void prepareDailyCollMap(Map<String, Map<String, BigDecimal>> intervalwiseCollMap, StringTerms cityaggr, Date fromDate) { String day; int noOfDays; String ulbName; Sum aggregateSum; Map<String, BigDecimal> dayWiseCollFromResult; Map<String, BigDecimal> finalDayWiseColl; String resultDateStr; List<String> daysInWeek = new ArrayList<>(); Date weekStartDate = fromDate; for (int count = 0; count < 7; count++) { daysInWeek.add(PropertyTaxConstants.DATEFORMATTER_YYYY_MM_DD.format(weekStartDate)); weekStartDate = DateUtils.addDays(weekStartDate, 1); } for (final Terms.Bucket cityDetailsentry : cityaggr.getBuckets()) { dayWiseCollFromResult = new LinkedHashMap<>(); finalDayWiseColl = new LinkedHashMap<>(); ulbName = cityDetailsentry.getKeyAsString(); noOfDays = 0; Histogram dateaggs = cityDetailsentry.getAggregations().get(DATE_AGG); for (Histogram.Bucket entry : dateaggs.getBuckets()) { resultDateStr = entry.getKeyAsString().split("T")[0]; aggregateSum = entry.getAggregations().get(CURRENT_TOTAL); if (BigDecimal.valueOf(aggregateSum.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP) .compareTo(BigDecimal.ZERO) > 0) dayWiseCollFromResult.put(resultDateStr, BigDecimal.valueOf(aggregateSum.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)); } // Check collections for all days in a week, if collection is not present, 0 will be shown for the corresponding day for (String dates : daysInWeek) { if (noOfDays == 0) noOfDays = 1; day = "Day " + noOfDays; if (dayWiseCollFromResult.get(dates) == null) finalDayWiseColl.put(day, BigDecimal.ZERO); else finalDayWiseColl.put(day, dayWiseCollFromResult.get(dates)); noOfDays++; } intervalwiseCollMap.put(ulbName, finalDayWiseColl); } } /** * Provides week wise DCB details across all ULBs * @param collectionDetailsRequest * @param intervalType * @return list */ public List<WeeklyDCB> getWeekwiseDCBDetailsAcrossCities( final CollectionDetailsRequest collectionDetailsRequest, final String intervalType) { final List<WeeklyDCB> ulbWiseDetails = new ArrayList<>(); Date fromDate = null; Date toDate = null; String weekName; Sum aggregateSum; String aggregationField = StringUtils.EMPTY; Map<String, Object[]> weekwiseColl; final Map<String, Map<String, Object[]>> weeklyCollMap = new LinkedHashMap<>(); Map<String, BillCollectorIndex> wardWiseBillCollectors = new HashMap<>(); if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getFromDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils .addDays(DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD), 1); } if (StringUtils.isNotBlank(collectionDetailsRequest.getType())) aggregationField = getAggregrationField(collectionDetailsRequest); if (DASHBOARD_GROUPING_WARDWISE.equalsIgnoreCase(collectionDetailsRequest.getType())) wardWiseBillCollectors = getWardWiseBillCollectors(collectionDetailsRequest); final Map<String, BigDecimal> totalDemandMap = getCollectionAndDemandValues(collectionDetailsRequest, fromDate, toDate, PROPERTY_TAX_INDEX_NAME, TOTAL_DEMAND, aggregationField); final Aggregations collAggr = getMonthwiseCollectionsForConsecutiveYears(collectionDetailsRequest, fromDate, toDate, true, intervalType, aggregationField); final StringTerms cityaggr = collAggr.get(BY_CITY); BigDecimal totalDemand; BigDecimal weeklyDemand; int noOfWeeks; Object[] demandCollValues; for (final Terms.Bucket cityDetailsentry : cityaggr.getBuckets()) { weekwiseColl = new LinkedHashMap<>(); final String ulbName = cityDetailsentry.getKeyAsString(); noOfWeeks = 0; totalDemand = totalDemandMap.get(ulbName) == null ? BigDecimal.ZERO : totalDemandMap.get(ulbName); final Histogram dateaggs = cityDetailsentry.getAggregations().get(DATE_AGG); for (final Histogram.Bucket entry : dateaggs.getBuckets()) { if (noOfWeeks == 0) noOfWeeks = 1; demandCollValues = new Object[53]; if (totalDemand.compareTo(BigDecimal.ZERO) == 0) weeklyDemand = BigDecimal.ZERO; else weeklyDemand = totalDemand.divide(BigDecimal.valueOf(52), BigDecimal.ROUND_HALF_UP) .multiply(BigDecimal.valueOf(noOfWeeks)); weekName = "Week " + noOfWeeks; aggregateSum = entry.getAggregations().get(CURRENT_TOTAL); if (BigDecimal.valueOf(aggregateSum.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP) .compareTo(BigDecimal.ZERO) > 0) { demandCollValues[0] = BigDecimal.valueOf(aggregateSum.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP); demandCollValues[1] = weeklyDemand; weekwiseColl.put(weekName, demandCollValues); } noOfWeeks++; } weeklyCollMap.put(ulbName, weekwiseColl); } setWeeklyDCBValues(ulbWiseDetails, weeklyCollMap, wardWiseBillCollectors); return ulbWiseDetails; } /** * Sets the Demand and Collection values * @param ulbWiseDetails * @param weeklyCollMap */ private void setWeeklyDCBValues(final List<WeeklyDCB> ulbWiseDetails, final Map<String, Map<String, Object[]>> weeklyCollMap, Map<String, BillCollectorIndex> wardWiseBillCollectors) { WeeklyDCB weeklyDCB; DemandCollectionMIS demandCollectionMIS; int count; for (final Map.Entry<String, Map<String, Object[]>> entry : weeklyCollMap.entrySet()) { weeklyDCB = new WeeklyDCB(); count = 1; weeklyDCB.setBoundaryName(entry.getKey()); weeklyDCB.setBillCollectorName(wardWiseBillCollectors.get(entry.getKey()) == null ? StringUtils.EMPTY : wardWiseBillCollectors.get(entry.getKey()).getBillCollector()); for (final Map.Entry<String, Object[]> weeklyMap : entry.getValue().entrySet()) { demandCollectionMIS = new DemandCollectionMIS(); demandCollectionMIS.setCollection(new BigDecimal(weeklyMap.getValue()[0].toString())); demandCollectionMIS.setDemand(new BigDecimal(weeklyMap.getValue()[1].toString())); if (demandCollectionMIS.getDemand().compareTo(BigDecimal.ZERO) > 0) demandCollectionMIS.setPercent(demandCollectionMIS.getCollection() .divide(demandCollectionMIS.getDemand(), 2, RoundingMode.CEILING) .multiply(BIGDECIMAL_100)); if (count == 1) weeklyDCB.setWeek1DCB(demandCollectionMIS); else if (count == 2) weeklyDCB.setWeek2DCB(demandCollectionMIS); else if (count == 3) weeklyDCB.setWeek3DCB(demandCollectionMIS); else if (count == 4) weeklyDCB.setWeek4DCB(demandCollectionMIS); else if (count == 5) weeklyDCB.setWeek5DCB(demandCollectionMIS); count++; } ulbWiseDetails.add(weeklyDCB); } } /** * Provides month wise DCB details across all ULBs * @param collectionDetailsRequest * @param intervalType * @return list */ public List<MonthlyDCB> getMonthwiseDCBDetailsAcrossCities( final CollectionDetailsRequest collectionDetailsRequest, final String intervalType) { final List<MonthlyDCB> ulbWiseDetails = new ArrayList<>(); Date fromDate = null; Date toDate = null; String monthName; Sum aggregateSum; Integer month; String aggregationField = StringUtils.EMPTY; Map<String, Object[]> monthwiseColl; Map<Integer, String> monthValuesMap = DateUtils.getAllMonthsWithFullNames(); Map<String, BillCollectorIndex> wardWiseBillCollectors = new HashMap<>(); if (StringUtils.isNotBlank(collectionDetailsRequest.getType())) aggregationField = getAggregrationField(collectionDetailsRequest); if (DASHBOARD_GROUPING_WARDWISE.equalsIgnoreCase(collectionDetailsRequest.getType())) wardWiseBillCollectors = getWardWiseBillCollectors(collectionDetailsRequest); final Map<String, Map<String, Object[]>> ulbwiseMonthlyCollMap = new HashMap<>(); if (StringUtils.isNotBlank(collectionDetailsRequest.getFromDate()) && StringUtils.isNotBlank(collectionDetailsRequest.getToDate())) { fromDate = DateUtils.getDate(collectionDetailsRequest.getFromDate(), DATE_FORMAT_YYYYMMDD); toDate = DateUtils .addDays(DateUtils.getDate(collectionDetailsRequest.getToDate(), DATE_FORMAT_YYYYMMDD), 1); } final Map<String, BigDecimal> totalDemandMap = getCollectionAndDemandValues(collectionDetailsRequest, fromDate, toDate, PROPERTY_TAX_INDEX_NAME, TOTAL_DEMAND, aggregationField); final Aggregations collAggr = getMonthwiseCollectionsForConsecutiveYears(collectionDetailsRequest, fromDate, toDate, true, intervalType, aggregationField); final StringTerms cityaggr = collAggr.get(BY_CITY); BigDecimal totalDemand; BigDecimal monthlyDemand; int noOfMonths; Object[] demandCollValues; for (final Terms.Bucket cityDetailsentry : cityaggr.getBuckets()) { monthwiseColl = new LinkedHashMap<>(); final String ulbName = cityDetailsentry.getKeyAsString(); noOfMonths = 0; totalDemand = totalDemandMap.get(ulbName); if (totalDemand == null) totalDemand = BigDecimal.ZERO; final Histogram dateaggs = cityDetailsentry.getAggregations().get(DATE_AGG); for (final Histogram.Bucket entry : dateaggs.getBuckets()) { if (noOfMonths == 0) noOfMonths = 1; demandCollValues = new Object[12]; String[] dateArr = entry.getKeyAsString().split("T"); month = Integer.valueOf(dateArr[0].split("-", 3)[1]); monthName = monthValuesMap.get(month); monthlyDemand = totalDemand.divide(BigDecimal.valueOf(12), BigDecimal.ROUND_HALF_UP) .multiply(BigDecimal.valueOf(noOfMonths)); aggregateSum = entry.getAggregations().get(CURRENT_TOTAL); if (BigDecimal.valueOf(aggregateSum.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP) .compareTo(BigDecimal.ZERO) > 0) { demandCollValues[0] = BigDecimal.valueOf(aggregateSum.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP); demandCollValues[1] = monthlyDemand; monthwiseColl.put(monthName, demandCollValues); } noOfMonths++; } ulbwiseMonthlyCollMap.put(ulbName, monthwiseColl); } setMonthlyDCBValues(ulbWiseDetails, ulbwiseMonthlyCollMap, wardWiseBillCollectors); return ulbWiseDetails; } /** * Sets the Demand and Collection values * @param ulbWiseDetails * @param monthlyCollMap */ private void setMonthlyDCBValues(final List<MonthlyDCB> ulbWiseDetails, final Map<String, Map<String, Object[]>> yearwiseMonthlyCollMap, Map<String, BillCollectorIndex> wardWiseBillCollectors) { MonthlyDCB monthlyDCB; DemandCollectionMIS demandCollectionMIS; String month; for (final Map.Entry<String, Map<String, Object[]>> entry : yearwiseMonthlyCollMap.entrySet()) { monthlyDCB = new MonthlyDCB(); monthlyDCB.setBoundaryName(entry.getKey()); monthlyDCB.setBillCollectorName(wardWiseBillCollectors.get(entry.getKey()) == null ? StringUtils.EMPTY : wardWiseBillCollectors.get(entry.getKey()).getBillCollector()); for (final Map.Entry<String, Object[]> monthMap : entry.getValue().entrySet()) { demandCollectionMIS = new DemandCollectionMIS(); month = monthMap.getKey(); demandCollectionMIS.setCollection(new BigDecimal(monthMap.getValue()[0].toString())); demandCollectionMIS.setDemand(new BigDecimal(monthMap.getValue()[1].toString())); if (demandCollectionMIS.getDemand().compareTo(BigDecimal.ZERO) > 0) demandCollectionMIS.setPercent(demandCollectionMIS.getCollection() .divide(demandCollectionMIS.getDemand(), 2, RoundingMode.CEILING) .multiply(BIGDECIMAL_100)); setDCBForMonth(monthlyDCB, demandCollectionMIS, month); } ulbWiseDetails.add(monthlyDCB); } } /** * Sets Collections for each month * @param collectionMap * @param collectionAnalysis */ private void setCollectionsForMonths(Map<String, Map<String, BigDecimal>> collectionMap, CollectionAnalysis collectionAnalysis) { DemandCollectionMIS demandCollectionMIS; List<MonthlyDCB> monthlyCollDetails = new ArrayList<>(); MonthlyDCB monthlyDCB; String month; for (final Map.Entry<String, Map<String, BigDecimal>> entry : collectionMap.entrySet()) { monthlyDCB = new MonthlyDCB(); monthlyDCB.setBoundaryName(entry.getKey()); for (final Map.Entry<String, BigDecimal> monthMap : entry.getValue().entrySet()) { demandCollectionMIS = new DemandCollectionMIS(); month = monthMap.getKey(); demandCollectionMIS.setCollection(monthMap.getValue()); setDCBForMonth(monthlyDCB, demandCollectionMIS, month); } monthlyCollDetails.add(monthlyDCB); } collectionAnalysis.setMonthlyDCBDetails(monthlyCollDetails); } /** * Sets collections for each week * @param collectionMap * @param collectionAnalysis */ private void setCollectionsForWeeks(Map<String, Map<String, BigDecimal>> collectionMap, CollectionAnalysis collectionAnalysis) { int intervalCount; DemandCollectionMIS demandCollectionMIS; WeeklyDCB weeklyDCB; List<WeeklyDCB> weeklyCollDetails = new ArrayList<>(); for (Map.Entry<String, Map<String, BigDecimal>> citywise : collectionMap.entrySet()) { weeklyDCB = new WeeklyDCB(); intervalCount = 1; weeklyDCB.setBoundaryName(citywise.getKey()); for (final Map.Entry<String, BigDecimal> weeklyMap : citywise.getValue().entrySet()) { demandCollectionMIS = new DemandCollectionMIS(); demandCollectionMIS.setCollection(weeklyMap.getValue()); demandCollectionMIS.setIntervalCount(intervalCount); if (intervalCount == 1) weeklyDCB.setWeek1DCB(demandCollectionMIS); else if (intervalCount == 2) weeklyDCB.setWeek2DCB(demandCollectionMIS); else if (intervalCount == 3) weeklyDCB.setWeek3DCB(demandCollectionMIS); else if (intervalCount == 4) weeklyDCB.setWeek4DCB(demandCollectionMIS); else if (intervalCount == 5) weeklyDCB.setWeek5DCB(demandCollectionMIS); intervalCount++; } weeklyCollDetails.add(weeklyDCB); } collectionAnalysis.setWeeklyDCBDetails(weeklyCollDetails); } /** * Sets collections for each day in a week * @param collectionMap * @param collectionAnalysis */ private void setCollectionsForDays(Map<String, Map<String, BigDecimal>> collectionMap, CollectionAnalysis collectionAnalysis) { int intervalCount; DemandCollectionMIS demandCollectionMIS; DayWiseCollection dayWiseCollection; List<DayWiseCollection> dailyCollDetails = new ArrayList<>(); for (Map.Entry<String, Map<String, BigDecimal>> citywise : collectionMap.entrySet()) { dayWiseCollection = new DayWiseCollection(); intervalCount = 1; dayWiseCollection.setBoundaryName(citywise.getKey()); for (final Map.Entry<String, BigDecimal> weeklyMap : citywise.getValue().entrySet()) { demandCollectionMIS = new DemandCollectionMIS(); demandCollectionMIS.setCollection(weeklyMap.getValue()); demandCollectionMIS.setIntervalCount(intervalCount); if (intervalCount == 1) dayWiseCollection.setDay1DCB(demandCollectionMIS); else if (intervalCount == 2) dayWiseCollection.setDay2DCB(demandCollectionMIS); else if (intervalCount == 3) dayWiseCollection.setDay3DCB(demandCollectionMIS); else if (intervalCount == 4) dayWiseCollection.setDay4DCB(demandCollectionMIS); else if (intervalCount == 5) dayWiseCollection.setDay5DCB(demandCollectionMIS); else if (intervalCount == 6) dayWiseCollection.setDay6DCB(demandCollectionMIS); else if (intervalCount == 7) dayWiseCollection.setDay7DCB(demandCollectionMIS); intervalCount++; } dailyCollDetails.add(dayWiseCollection); } collectionAnalysis.setDailyCollDetails(dailyCollDetails); } /** * Sets DCB bean for each month * @param monthlyDCB * @param demandCollectionMIS * @param month */ private void setDCBForMonth(MonthlyDCB monthlyDCB, DemandCollectionMIS demandCollectionMIS, String month) { switch (month) { case APRIL: monthlyDCB.setAprilDCB(demandCollectionMIS); break; case MAY: monthlyDCB.setMayDCB(demandCollectionMIS); break; case JUNE: monthlyDCB.setJuneDCB(demandCollectionMIS); break; case JULY: monthlyDCB.setJulyDCB(demandCollectionMIS); break; case AUGUST: monthlyDCB.setAugustDCB(demandCollectionMIS); break; case SEPTEMBER: monthlyDCB.setSeptemberDCB(demandCollectionMIS); break; case OCTOBER: monthlyDCB.setOctoberDCB(demandCollectionMIS); break; case NOVEMBER: monthlyDCB.setNovemberDCB(demandCollectionMIS); break; case DECEMBER: monthlyDCB.setDecemberDCB(demandCollectionMIS); break; case JANUARY: monthlyDCB.setJanuaryDCB(demandCollectionMIS); break; case FEBRUARY: monthlyDCB.setFebruaryDCB(demandCollectionMIS); break; case MARCH: monthlyDCB.setMarchDCB(demandCollectionMIS); break; default: break; } } /** * Provides ward wise details for all cities * @param collectionDetailsRequest * @param cities * @return List */ public List<CollTableData> getWardWiseTableDataAcrossCities(CollectionDetailsRequest collectionDetailsRequest, Iterable<CityIndex> cities) { List<CollTableData> citywiseTableData = new ArrayList<>(); List<CollTableData> wardWiseData; String cityName; String regionName; String districtName; String ulbGrade; for (CityIndex city : cities) { cityName = city.getName(); collectionDetailsRequest.setUlbCode(city.getCitycode()); collectionDetailsRequest.setType(DASHBOARD_GROUPING_WARDWISE); regionName = city.getRegionname(); districtName = city.getDistrictname(); ulbGrade = city.getCitygrade(); wardWiseData = getResponseTableData(collectionDetailsRequest, false); for (CollTableData wardData : wardWiseData) { wardData.setUlbName(cityName); wardData.setRegionName(regionName); wardData.setDistrictName(districtName); wardData.setUlbGrade(ulbGrade); } citywiseTableData.addAll(wardWiseData); } return citywiseTableData; } public List<String> getCityDetails(CollectionDetailsRequest collectionDetailsRequest, String aggregationField) { List<String> nameList = new ArrayList<>(); String fieldName = StringUtils.EMPTY; int size = 0; if (REGION_NAME.equalsIgnoreCase(aggregationField)) { fieldName = "regionname"; size = 4; } else if (DISTRICT_NAME.equalsIgnoreCase(aggregationField)) { fieldName = "districtname"; size = 13; } else if (CITY_NAME.equalsIgnoreCase(aggregationField)) { fieldName = "name"; size = 112; } else if (CITY_GRADE.equalsIgnoreCase(aggregationField)) { fieldName = "citygrade"; size = 7; } if (!REVENUE_WARD.equalsIgnoreCase(aggregationField)) { BoolQueryBuilder boolQuery = prepareQueryForAgg(collectionDetailsRequest); AggregationBuilder agg = AggregationBuilders.terms("uniqueAggr").field(fieldName).size(size); SearchResponse cityResponse = elasticsearchTemplate.getClient().prepareSearch("city") .setQuery(boolQuery).setSize(size).addAggregation(agg).execute().actionGet(); Terms aggTerms = cityResponse.getAggregations().get("uniqueAggr"); for (Terms.Bucket bucket : aggTerms.getBuckets()) nameList.add(bucket.getKeyAsString()); } else { List<BillCollectorIndex> billCollectors = getBillCollectorDetails(collectionDetailsRequest); for (BillCollectorIndex billCollector : billCollectors) nameList.add(billCollector.getRevenueWard()); } return nameList; } private BoolQueryBuilder prepareQueryForAgg(CollectionDetailsRequest collectionDetailsRequest) { BoolQueryBuilder boolQuery = new BoolQueryBuilder(); if (StringUtils.isNotBlank(collectionDetailsRequest.getDistrictName())) { boolQuery = boolQuery .filter(QueryBuilders.matchQuery("districtname", collectionDetailsRequest.getDistrictName())); } if (StringUtils.isNotBlank(collectionDetailsRequest.getRegionName())) { boolQuery = boolQuery .filter(QueryBuilders.matchQuery("regionname", collectionDetailsRequest.getRegionName())); } if (StringUtils.isNotBlank(collectionDetailsRequest.getUlbGrade())) boolQuery = boolQuery .filter(QueryBuilders.matchQuery("citygrade", collectionDetailsRequest.getUlbGrade())); return boolQuery; } }