class TopTenController extends GenericOCDSController {

    @ApiOperation(value = "This endpoint should return the following data for the Top 10 suppliers (by award value)."
            + "Returns supplier id, total awarded amount of all awarded contracts, count of awarded contracts,"
            + "Ids of the procuring entities from which they have received an award, and their count. "
            + "All filters ally here, the year filter uses the awards.date field.")
    @RequestMapping(value = "/api/topTenSuppliers", method = {RequestMethod.POST,
            RequestMethod.GET},
            produces = "application/json")
    public List<Document> topTenLargestSuppliers(@ModelAttribute @Valid final YearFilterPagingRequest filter) {

        BasicDBObject project = new BasicDBObject();
        project.put(Fields.UNDERSCORE_ID, 0);
        project.put(MongoConstants.FieldNames.AWARDS_SUPPLIERS_ID, 1);
        project.put(MongoConstants.FieldNames.AWARDS_VALUE_AMOUNT, 1);
        project.put(MongoConstants.FieldNames.TENDER_PROCURING_ENTITY_ID, 1);

        BasicDBObject group = new BasicDBObject();
        group.put(Fields.UNDERSCORE_ID, ref(MongoConstants.FieldNames.AWARDS_SUPPLIERS_ID));
        group.put(
                Keys.TOTAL_AWARD_AMOUNT, new BasicDBObject("$sum", ref(MongoConstants.FieldNames.AWARDS_VALUE_AMOUNT)));
        group.put(Keys.TOTAL_CONTRACTS, new BasicDBObject("$sum", 1));
        group.put(
                Keys.PROCURING_ENTITY_IDS,
                new BasicDBObject("$addToSet", ref(MongoConstants.FieldNames.TENDER_PROCURING_ENTITY_ID))
        );


        Aggregation agg = newAggregation(
                match(where(MongoConstants.FieldNames.AWARDS_VALUE_AMOUNT).exists(true)
                        .and(MongoConstants.FieldNames.AWARDS_STATUS)
                        .is(Award.Status.active.toString())
                        .andOperator(getDefaultFilterCriteria(filter))),
                unwind("awards"),
                match(where(MongoConstants.FieldNames.AWARDS_STATUS).is(Award.Status.active.toString())),
                unwind("awards.suppliers"),
                match(getYearFilterCriteria(filter.awardFiltering(), MongoConstants.FieldNames.AWARDS_DATE)),
                new CustomProjectionOperation(project),
                new CustomGroupingOperation(group),
                sort(Direction.DESC, Keys.TOTAL_AWARD_AMOUNT),
                limit(10),
                project().and(Fields.UNDERSCORE_ID).
                        as(Keys.SUPPLIER_ID).
                        andInclude(Keys.TOTAL_AWARD_AMOUNT, Keys.TOTAL_CONTRACTS, Keys.PROCURING_ENTITY_IDS)
                        .andExclude(Fields.UNDERSCORE_ID)
                        .and(Keys.PROCURING_ENTITY_IDS).size().as(Keys.PROCURING_ENTITY_IDS_COUNT)
        );

        return releaseAgg(agg);
    }

}