class AverageTenderAndAwardPeriodsController extends GenericOCDSController {

    @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")
    public List<Document> averageTenderPeriod(@ModelAttribute @Valid final YearFilterPagingRequest filter) {

        DBObject tenderLengthDays = new BasicDBObject(
                "$divide",
                Arrays.asList(
                        new BasicDBObject(
                                "$subtract",
                                Arrays.asList(
                                        ref(MongoConstants.FieldNames.TENDER_PERIOD_END_DATE),
                                        ref(MongoConstants.FieldNames.TENDER_PERIOD_START_DATE)
                                )
                        ),
                        DAY_MS
                )
        );

        DBObject project = new BasicDBObject();
        project.put(Fields.UNDERSCORE_ID, 0);
        addYearlyMonthlyProjection(filter, project, ref(MongoConstants.FieldNames.TENDER_PERIOD_START_DATE));
        project.put("tenderLengthDays", tenderLengthDays);

        Aggregation agg = newAggregation(
                match(where(MongoConstants.FieldNames.TENDER_PERIOD_START_DATE)
                        .exists(true).and(MongoConstants.FieldNames.TENDER_PERIOD_END_DATE)
                        .exists(true).andOperator(getYearDefaultFilterCriteria(
                                filter,
                                MongoConstants.FieldNames.TENDER_PERIOD_START_DATE
                        ))),
                new CustomProjectionOperation(project),
                getYearlyMonthlyGroupingOperation(filter).avg("$tenderLengthDays").as(Keys.AVERAGE_TENDER_DAYS),
                transformYearlyGrouping(filter).andInclude(Keys.AVERAGE_TENDER_DAYS),
                getSortByYearMonth(filter), skip(filter.getSkip()), limit(filter.getPageSize())
        );

        return releaseAgg(agg);
    }

}