AverageTenderAndAwardPeriodsController extends GenericOCDSController { @ApiOperation(value = "Calculates the average award period, per each year. The year is taken from " + "awards.date and the duration is taken by counting the days" + "between tender.tenderPeriod.endDate and tender.tenderPeriod.startDate. The award has to be active.") @RequestMapping(value = "/api/averageAwardPeriod", method = {RequestMethod.POST, RequestMethod.GET}, produces = "application/json") public List<Document> averageAwardPeriod(@ModelAttribute @Valid final YearFilterPagingRequest filter) { DBObject awardLengthDays = new BasicDBObject("$divide", Arrays.asList( new BasicDBObject("$subtract", Arrays.asList( ref(MongoConstants.FieldNames.AWARDS_DATE), ref(MongoConstants.FieldNames.TENDER_PERIOD_END_DATE) )), DAY_MS)); DBObject project = new BasicDBObject(); project.put(Fields.UNDERSCORE_ID, 0); addYearlyMonthlyProjection(filter, project, ref(MongoConstants.FieldNames.AWARDS_DATE)); project.put("awardLengthDays", awardLengthDays); project.put(MongoConstants.FieldNames.AWARDS_DATE, 1); project.put(MongoConstants.FieldNames.AWARDS_STATUS, 1); project.put(MongoConstants.FieldNames.TENDER_PERIOD_END_DATE, 1); Aggregation agg = newAggregation( match(where(MongoConstants.FieldNames.TENDER_PERIOD_END_DATE) .exists(true).and(MongoConstants.FieldNames.AWARDS_DATE).exists(true) .and(MongoConstants.FieldNames.AWARDS_STATUS).is(Award.Status.active.toString())), unwind("awards"), match(where(MongoConstants.FieldNames.AWARDS_DATE).exists(true) .and(MongoConstants.FieldNames.AWARDS_STATUS) .is(Award.Status.active.toString()) .andOperator(getYearDefaultFilterCriteria( filter.awardFiltering(), MongoConstants.FieldNames.AWARDS_DATE ))), new CustomOperation(new Document("$project", project)), group(getYearlyMonthlyGroupingFields(filter)).avg("$awardLengthDays").as(Keys.AVERAGE_AWARD_DAYS), transformYearlyGrouping(filter).andInclude(Keys.AVERAGE_AWARD_DAYS), getSortByYearMonth(filter), skip(filter.getSkip()), limit(filter.getPageSize()) ); return releaseAgg(agg); }  @ApiOperation(value = "Calculates the average tender period, per each year. The year is taken from " + "tender.tenderPeriod.startDate and the duration is taken by counting the days" + "between tender.tenderPeriod.endDate and tender.tenderPeriod.startDate") @RequestMapping(value = "/api/averageTenderPeriod", method = {RequestMethod.POST, RequestMethod.GET}, produces = "application/json") List<Document> averageTenderPeriod(@ModelAttribute @Valid final YearFilterPagingRequest filter); @ApiOperation(value = "Quality indicator for averageTenderPeriod endpoint, " + "showing the percentage of tenders that have start and end dates vs the total tenders in the system") @RequestMapping(value = "/api/qualityAverageTenderPeriod", method = {RequestMethod.POST, RequestMethod.GET}, produces = "application/json") List<Document> qualityAverageTenderPeriod(@ModelAttribute @Valid final DefaultFilterPagingRequest filter); @ApiOperation(value = "Calculates the average award period, per each year. The year is taken from " + "awards.date and the duration is taken by counting the days" + "between tender.tenderPeriod.endDate and tender.tenderPeriod.startDate. The award has to be active.") @RequestMapping(value = "/api/averageAwardPeriod", method = {RequestMethod.POST, RequestMethod.GET}, produces = "application/json") List<Document> averageAwardPeriod(@ModelAttribute @Valid final YearFilterPagingRequest filter); @ApiOperation(value = "Quality indicator for averageAwardPeriod endpoint, " + "showing the percentage of awards that have start and end dates vs the total tenders in the system") @RequestMapping(value = "/api/qualityAverageAwardPeriod", method = {RequestMethod.POST, RequestMethod.GET}, produces = "application/json") List<Document> qualityAverageAwardPeriod(@ModelAttribute @Valid final DefaultFilterPagingRequest filter);  }
@Test public void averageAwardPeriod() throws Exception { final List<Document> averageAwardPeriod = averageTenderAndAwardPeriodsController .averageAwardPeriod(new YearFilterPagingRequest()); final Document first = averageAwardPeriod.get(0); int year = (int) first.get(AverageTenderAndAwardPeriodsController.Keys.YEAR); double averageAwardDays = (double) first.get(AverageTenderAndAwardPeriodsController.Keys.AVERAGE_AWARD_DAYS); Assert.assertEquals(2015, year); Assert.assertEquals(365.0, averageAwardDays, 0); final Document second = averageAwardPeriod.get(1); year = (int) second.get(AverageTenderAndAwardPeriodsController.Keys.YEAR); averageAwardDays = (double) second.get(AverageTenderAndAwardPeriodsController.Keys.AVERAGE_AWARD_DAYS); Assert.assertEquals(2016, year); Assert.assertEquals(405.0, averageAwardDays, 0); }