FundingByLocationController extends GenericOCDSController { @ApiOperation("Calculates percentage of releases with planning with at least one specified location," + " that is the array planning.budget.projectLocation has to be initialzied." + "Filters out stub planning, therefore planning.budget.amount has to exist." + "Responds only to the procuring entity id filter: tender.procuringEntity._id") @RequestMapping(value = "/api/qualityPlannedFundingByLocation", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json") public List<DBObject> qualityPlannedFundingByLocation( @ModelAttribute @Valid final DefaultFilterPagingRequest filter) { DBObject project = new BasicDBObject(); project.putAll(filterProjectMap); project.put("planning.budget.projectLocation", 1); project.put("planning.budget.amount", 1); project.put(Fields.UNDERSCORE_ID, 0); DBObject group = new BasicDBObject(); group.put(Fields.UNDERSCORE_ID, null); group.put(Keys.TOTAL_PLANS_WITH_AMOUNTS, new BasicDBObject("$sum", 1)); group.put(Keys.TOTAL_PLANS_WITH_AMOUNTS_AND_LOCATION, new BasicDBObject("$sum", new BasicDBObject("$cond", Arrays.asList( new BasicDBObject("$gt", Arrays.asList( new BasicDBObject("$size", new BasicDBObject("$ifNull", Arrays.asList( "$planning.budget.projectLocation", ArrayUtils.toArray()))), 0)), 1, 0)))); DBObject project2 = new BasicDBObject(); project2.put(Fields.UNDERSCORE_ID, 0); project2.put(Keys.TOTAL_PLANS_WITH_AMOUNTS, 1); project2.put(Keys.TOTAL_PLANS_WITH_AMOUNTS_AND_LOCATION, 1); project2.put(Keys.PERCENT_PLANS_WITH_AMOUNTS_AND_LOCATION, new BasicDBObject("$multiply", Arrays.asList( new BasicDBObject("$divide", Arrays.asList("$totalPlansWithAmountsAndLocation", "$totalPlansWithAmounts")), 100))); Aggregation agg = newAggregation(new CustomProjectionOperation(project), match(where("planning.budget.amount").exists(true).andOperator(getProcuringEntityIdCriteria(filter))), new CustomGroupingOperation(group), new CustomProjectionOperation(project2) ); AggregationResults<DBObject> results = mongoTemplate.aggregate(agg, "release", DBObject.class); List<DBObject> tagCount = results.getMappedResults(); return tagCount; }  @ApiOperation(value = "Total estimated funding (tender.value) grouped by " + "tender.items.deliveryLocation and also grouped by year." + " The endpoint also returns the count of tenders for each location. " + "It responds to all filters. The year is calculated based on tender.tenderPeriod.startDate") @RequestMapping(value = "/api/fundingByTenderDeliveryLocation", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json") List<DBObject> fundingByTenderDeliveryLocation(
            @ModelAttribute @Valid final YearFilterPagingRequest filter); @ApiOperation("Calculates percentage of releases with tender with at least one specified delivery location," + " that is the array tender.items.deliveryLocation has to have items." + "Filters out stub tenders, therefore tender.tenderPeriod.startDate has to exist.") @RequestMapping(value = "/api/qualityFundingByTenderDeliveryLocation", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json") List<DBObject> qualityFundingByTenderDeliveryLocation(
            @ModelAttribute @Valid final YearFilterPagingRequest filter); @ApiOperation(value = "Planned funding by location by year. Returns the total amount of planning.budget" + " available per planning.budget.projectLocation, grouped by year. " + "This will return full location information, including geocoding data." + "Responds only to the procuring entity id filter: tender.procuringEntity._id") @RequestMapping(value = "/api/plannedFundingByLocation", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json") List<DBObject> plannedFundingByLocation(@ModelAttribute @Valid final YearFilterPagingRequest filter); @ApiOperation("Calculates percentage of releases with planning with at least one specified location," + " that is the array planning.budget.projectLocation has to be initialzied." + "Filters out stub planning, therefore planning.budget.amount has to exist." + "Responds only to the procuring entity id filter: tender.procuringEntity._id") @RequestMapping(value = "/api/qualityPlannedFundingByLocation", method = { RequestMethod.POST, RequestMethod.GET }, produces = "application/json") List<DBObject> qualityPlannedFundingByLocation(
            @ModelAttribute @Valid final DefaultFilterPagingRequest filter);  }
@Test public void qualityPlannedFundingByLocation() throws Exception { final List<DBObject> qualityPlannedFundingByLocation = fundingByLocationController .qualityPlannedFundingByLocation(new YearFilterPagingRequest()); final DBObject first = qualityPlannedFundingByLocation.get(0); int totalPlansWithAmounts = (int) first.get(FundingByLocationController.Keys.TOTAL_PLANS_WITH_AMOUNTS); int totalPlansWithAmountsAndLocation = (int) first .get(FundingByLocationController.Keys.TOTAL_PLANS_WITH_AMOUNTS_AND_LOCATION); double percentPlansWithAmountsAndLocation = (double) first .get(FundingByLocationController.Keys.PERCENT_PLANS_WITH_AMOUNTS_AND_LOCATION); Assert.assertEquals(3, totalPlansWithAmounts); Assert.assertEquals(1, totalPlansWithAmountsAndLocation); Assert.assertEquals(33.33, percentPlansWithAmountsAndLocation, 1E-2); }