FundingByLocationController extends GenericOCDSController { @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") public List<Document> qualityFundingByTenderDeliveryLocation( @ModelAttribute @Valid final YearFilterPagingRequest filter) { DBObject project = new BasicDBObject(); project.putAll(filterProjectMap); project.put(Fields.UNDERSCORE_ID, "$tender._id"); project.put("tenderItemsDeliveryLocation", new BasicDBObject("$cond", Arrays.asList(new BasicDBObject("$gt", Arrays.asList("$tender.items.deliveryLocation", null)), 1, 0))); DBObject project1 = new BasicDBObject(); project1.put(Fields.UNDERSCORE_ID, 0); project1.put(Keys.TOTAL_TENDERS_WITH_START_DATE, 1); project1.put(Keys.TOTAL_TENDERS_WITH_START_DATE_AND_LOCATION, 1); project1.put(Keys.PERCENT_TENDERS_WITH_START_DATE_AND_LOCATION, new BasicDBObject("$multiply", Arrays.asList(new BasicDBObject("$divide", Arrays.asList( "$totalTendersWithStartDateAndLocation", "$totalTendersWithStartDate")), 100))); Aggregation agg = newAggregation( match(where(MongoConstants.FieldNames.TENDER_PERIOD_START_DATE).exists(true) .andOperator(getYearDefaultFilterCriteria(filter, MongoConstants.FieldNames.TENDER_PERIOD_START_DATE))), unwind("$tender.items"), new CustomProjectionOperation(project), group(Fields.UNDERSCORE_ID_REF).max("tenderItemsDeliveryLocation").as("hasTenderItemsDeliverLocation"), group().count().as("totalTendersWithStartDate").sum("hasTenderItemsDeliverLocation") .as(Keys.TOTAL_TENDERS_WITH_START_DATE_AND_LOCATION), new CustomProjectionOperation(project1) ); return releaseAgg(agg); }  @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<Document> 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<Document> qualityFundingByTenderDeliveryLocation(
            @ModelAttribute @Valid final YearFilterPagingRequest filter);  }
@Test public void qualityFundingByTenderDeliveryLocation() throws Exception { final List<Document> qualityFundingByTenderDeliveryLocation = fundingByLocationController .qualityFundingByTenderDeliveryLocation(new YearFilterPagingRequest()); final Document first = qualityFundingByTenderDeliveryLocation.get(0); int totalTendersWithStartDate = (int) first.get(FundingByLocationController.Keys.TOTAL_TENDERS_WITH_START_DATE); int totalTendersWithStartDateAndLocation = (int) first .get(FundingByLocationController.Keys.TOTAL_TENDERS_WITH_START_DATE_AND_LOCATION); double percentTendersWithStartDateAndLocation = (double) first .get(FundingByLocationController.Keys.PERCENT_TENDERS_WITH_START_DATE_AND_LOCATION); Assert.assertEquals(3, totalTendersWithStartDate); Assert.assertEquals(1, totalTendersWithStartDateAndLocation); Assert.assertEquals(33.33, percentTendersWithStartDateAndLocation, 1E-2); }