class TenderPercentagesController extends GenericOCDSController {

    @ApiOperation("Returns the percent of tenders that were cancelled, grouped by year."
            + " The year is taken from tender.tenderPeriod.startDate. The response also contains the"
            + " total number of tenders and total number of cancelled tenders for each year.")
    @RequestMapping(value = "/api/percentTendersCancelled",
            method = {RequestMethod.POST, RequestMethod.GET}, produces = "application/json")
    public List<Document> percentTendersCancelled(@ModelAttribute @Valid final YearFilterPagingRequest filter) {

        DBObject project1 = new BasicDBObject();
        addYearlyMonthlyProjection(filter, project1, ref(MongoConstants.FieldNames.TENDER_PERIOD_START_DATE));
        project1.put(MongoConstants.FieldNames.TENDER_STATUS, 1);

        DBObject group = new BasicDBObject();
        addYearlyMonthlyReferenceToGroup(filter, group);
        group.put(Keys.TOTAL_TENDERS, new BasicDBObject("$sum", 1));
        group.put(Keys.TOTAL_CANCELLED, new BasicDBObject("$sum", new BasicDBObject(
                "$cond",
                Arrays.asList(new BasicDBObject("$eq", Arrays.asList(
                        ref(MongoConstants.FieldNames.TENDER_STATUS), Tender.Status.cancelled.toString())), 1, 0)
        )));

        DBObject project2 = new BasicDBObject();
        project2.put(Keys.TOTAL_TENDERS, 1);
        project2.put(Keys.TOTAL_CANCELLED, 1);
        project2.put(Keys.PERCENT_CANCELLED, new BasicDBObject(
                "$multiply",
                Arrays.asList(new BasicDBObject("$divide", Arrays.asList("$totalCancelled", "$totalTenders")), 100)
        ));

        Aggregation agg = newAggregation(
                match(where(MongoConstants.FieldNames.TENDER_PERIOD_START_DATE).exists(true)
                        .andOperator(getYearDefaultFilterCriteria(
                                filter,
                                MongoConstants.FieldNames.TENDER_PERIOD_START_DATE
                        ))),
                new CustomProjectionOperation(project1), new CustomGroupingOperation(group),
                new CustomProjectionOperation(project2),
                transformYearlyGrouping(filter).andInclude(Keys.TOTAL_TENDERS,
                        Keys.TOTAL_CANCELLED, Keys.PERCENT_TENDERS, Keys.PERCENT_CANCELLED
                ),
                getSortByYearMonth(filter),
                skip(filter.getSkip()), limit(filter.getPageSize())
        );

        return releaseAgg(agg);
    }

}