def _get_group_coverage(submission_queryset, group, location_type):
    # build MongoDB aggregation pipeline
    pipeline = [
        {'$match': submission_queryset._query},
        {
            '$group': {
                '_id': {
                    'location': '$location_name_path.{}'
                    .format(location_type.name),
                    'completion': '$completion.{}'.format(group)
                },
                'total': {'$sum': 1}
            }
        },
        {
            '$project': {
                '_id': 0,
                'location': '$_id.location',
                'completion': '$_id.completion',
                'total': '$total'
            }
        }
    ]

    try:
        datasrc = Submission._get_collection().aggregate(pipeline)
    except Exception, e:
        logger.exception(e)
        raise e
def _get_global_coverage(submission_queryset):
    # build the MongoDB aggregation pipeline
    pipeline = [
        {'$match': submission_queryset._query},
        {'$group': {
            '_id': '$completion',
            'total': {'$sum': 1},
        }},
        {'$project': {
            '_id': 0,
            'completion': '$_id',
            'total': '$total'
        }}
    ]

    try:
        datasrc = Submission._get_collection().aggregate(pipeline)
    except Exception as e:
        logger.exception(e)
        raise e

    result = datasrc.get('result')
    if not result:
        return None

    groups = result[0].get('completion').keys()

    # reshape the result
    coverage = OrderedDict()
    for group in groups:
        complete = sum((r.get('total')
                       for r in result
                       if r.get('completion').get(group) == 'Complete'))
        partial = sum((r.get('total')
                      for r in result
                      if r.get('completion').get(group) == 'Partial'))
        missing = sum((r.get('total')
                      for r in result
                      if r.get('completion').get(group) == 'Missing'))
        conflict = sum((r.get('total')
                       for r in result
                       if r.get('completion').get(group) == 'Conflict'))

        coverage.update({group: {
            'Complete': complete,
            'Partial': partial,
            'Missing': missing,
            'Conflict': conflict,
            'name': group
        }})

    # find a 'logical' sort
    submission = submission_queryset.first()
    if submission:
        group_names = [g.name for g in submission.form.groups]
    else:
        group_names = groups

    coverage_list = [coverage.get(g) for g in group_names if coverage.get(g)]

    return coverage_list