registrasion/reporting/views.py
def attendee_data(request, form, user_id=None):
    ''' Lists attendees for a given product/category selection along with
    profile data.'''

    status_display = {
        commerce.Cart.STATUS_ACTIVE: "Unpaid",
        commerce.Cart.STATUS_PAID: "Paid",
        commerce.Cart.STATUS_RELEASED: "Refunded",
    }

    output = []

    by_category = (
        form.cleaned_data["group_by"] == forms.GroupByForm.GROUP_BY_CATEGORY)

    products = form.cleaned_data["product"]
    categories = form.cleaned_data["category"]
    fields = form.cleaned_data["fields"]
    name_field = AttendeeProfile.name_field()

    items = commerce.ProductItem.objects.filter(
        Q(product__in=products) | Q(product__category__in=categories),
    ).exclude(
        cart__status=commerce.Cart.STATUS_RELEASED
    ).select_related(
        "cart", "cart__user", "product", "product__category",
    ).order_by("cart__status")

    # Add invoice nag link
    links = []
    invoice_mailout = reverse(views.invoice_mailout, args=[])
    invoice_mailout += "?" + request.META["QUERY_STRING"]
    links += [
        (invoice_mailout + "&status=1", "Send invoice reminders",),
        (invoice_mailout + "&status=2", "Send mail for paid invoices",),
    ]

    if items.count() > 0:
        output.append(Links("Actions", links))

    # Make sure we select all of the related fields
    related_fields = set(
        field for field in fields
        if isinstance(AttendeeProfile._meta.get_field(field), RelatedField)
    )

    # Get all of the relevant attendee profiles in one hit.
    profiles = AttendeeProfile.objects.filter(
        attendee__user__cart__productitem__in=items
    ).select_related("attendee__user").prefetch_related(*related_fields)
    by_user = {}
    for profile in profiles:
        by_user[profile.attendee.user] = profile

    cart = "attendee__user__cart"
    cart_status = cart + "__status"  # noqa
    product = cart + "__productitem__product"
    product_name = product + "__name"
    category = product + "__category"
    category_name = category + "__name"

    if by_category:
        grouping_fields = (category, category_name)
        order_by = (category, )
        first_column = "Category"
        group_name = lambda i: "%s" % (i[category_name], )  # noqa
    else:
        grouping_fields = (product, product_name, category_name)
        order_by = (category, )
        first_column = "Product"
        group_name = lambda i: "%s - %s" % (i[category_name], i[product_name])  # noqa

    # Group the responses per-field.
    for field in fields:
        concrete_field = AttendeeProfile._meta.get_field(field)
        field_verbose = concrete_field.verbose_name

        # Render the correct values for related fields
        if field in related_fields:
            # Get all of the IDs that will appear
            all_ids = profiles.order_by(field).values(field)
            all_ids = [i[field] for i in all_ids if i[field] is not None]
            # Get all of the concrete objects for those IDs
            model = concrete_field.related_model
            all_objects = model.objects.filter(id__in=all_ids)
            all_objects_by_id = dict((i.id, i) for i in all_objects)

            # Define a function to render those IDs.
            def display_field(value):
                if value in all_objects_by_id:
                    return all_objects_by_id[value]
                else:
                    return None
        else:
            def display_field(value):
                return value

        status_count = lambda status: Case(When(  # noqa
                attendee__user__cart__status=status,
                then=Value(1),
            ),
            default=Value(0),
            output_field=models.fields.IntegerField(),
        )
        paid_count = status_count(commerce.Cart.STATUS_PAID)
        unpaid_count = status_count(commerce.Cart.STATUS_ACTIVE)

        groups = profiles.order_by(
            *(order_by + (field, ))
        ).values(
            *(grouping_fields + (field, ))
        ).annotate(
            paid_count=Sum(paid_count),
            unpaid_count=Sum(unpaid_count),
        )
        output.append(ListReport(
            "Grouped by %s" % field_verbose,
            [first_column, field_verbose, "paid", "unpaid"],
            [
                (
                    group_name(group),
                    display_field(group[field]),
                    group["paid_count"] or 0,
                    group["unpaid_count"] or 0,
                )
                for group in groups
            ],
        ))

    # DO the report for individual attendees

    field_names = [
        AttendeeProfile._meta.get_field(field).verbose_name for field in fields
    ]

    def display_field(profile, field):
        field_type = AttendeeProfile._meta.get_field(field)
        attr = getattr(profile, field)

        if isinstance(field_type, models.ManyToManyField):
            return [str(i) for i in attr.all()] or ""
        else:
            return attr

    headings = ["User ID", "Name", "Email", "Product", "Item Status"]
    headings.extend(field_names)
    data = []
    for item in items:
        profile = by_user[item.cart.user]
        line = [
            item.cart.user.id,
            getattr(profile, name_field),
            profile.attendee.user.email,
            item.product,
            status_display[item.cart.status],
        ] + [
            display_field(profile, field) for field in fields
        ]
        data.append(line)

    output.append(AttendeeListReport(
        "Attendees by item with profile data", headings, data,
        link_view=attendee
    ))
    return output
def attendee_data(request, form, user_id=None):
    ''' Lists attendees for a given product/category selection along with
    profile data.'''

    status_display = {
        commerce.Cart.STATUS_ACTIVE: "Unpaid",
        commerce.Cart.STATUS_PAID: "Paid",
        commerce.Cart.STATUS_RELEASED: "Refunded",
    }

    output = []

    by_category = (
        form.cleaned_data["group_by"] == forms.GroupByForm.GROUP_BY_CATEGORY)

    products = form.cleaned_data["product"]
    categories = form.cleaned_data["category"]
    fields = form.cleaned_data["fields"]
    name_field = AttendeeProfile.name_field()

    items = commerce.ProductItem.objects.filter(
        Q(product__in=products) | Q(product__category__in=categories),
    ).exclude(
        cart__status=commerce.Cart.STATUS_RELEASED
    ).select_related(
        "cart", "cart__user", "product", "product__category",
    ).order_by("cart__status")

    # Add invoice nag link
    links = []
    invoice_mailout = reverse(views.invoice_mailout, args=[])
    invoice_mailout += "?" + request.META["QUERY_STRING"]
    links += [
        (invoice_mailout + "&status=1", "Send invoice reminders",),
        (invoice_mailout + "&status=2", "Send mail for paid invoices",),
    ]

    if items.count() > 0:
        output.append(Links("Actions", links))

    # Make sure we select all of the related fields
    related_fields = set(
        field for field in fields
        if isinstance(AttendeeProfile._meta.get_field(field), RelatedField)
    )

    # Get all of the relevant attendee profiles in one hit.
    profiles = AttendeeProfile.objects.filter(
        attendee__user__cart__productitem__in=items
    ).select_related("attendee__user").prefetch_related(*related_fields)
    by_user = {}
    for profile in profiles:
        by_user[profile.attendee.user] = profile

    cart = "attendee__user__cart"
    cart_status = cart + "__status"  # noqa
    product = cart + "__productitem__product"
    product_name = product + "__name"
    category = product + "__category"
    category_name = category + "__name"

    if by_category:
        grouping_fields = (category, category_name)
        order_by = (category, )
        first_column = "Category"
        group_name = lambda i: "%s" % (i[category_name], )  # noqa
    else:
        grouping_fields = (product, product_name, category_name)
        order_by = (category, )
        first_column = "Product"
        group_name = lambda i: "%s - %s" % (i[category_name], i[product_name])  # noqa

    # Group the responses per-field.
    for field in fields:
        concrete_field = AttendeeProfile._meta.get_field(field)
        field_verbose = concrete_field.verbose_name

        # Render the correct values for related fields
        if field in related_fields:
            # Get all of the IDs that will appear
            all_ids = profiles.order_by(field).values(field)
            all_ids = [i[field] for i in all_ids if i[field] is not None]
            # Get all of the concrete objects for those IDs
            model = concrete_field.related_model
            all_objects = model.objects.filter(id__in=all_ids)
            all_objects_by_id = dict((i.id, i) for i in all_objects)

            # Define a function to render those IDs.
            def display_field(value):
                if value in all_objects_by_id:
                    return all_objects_by_id[value]
                else:
                    return None
        else:
            def display_field(value):
                return value

        status_count = lambda status: Case(When(  # noqa
                attendee__user__cart__status=status,
                then=Value(1),
            ),
            default=Value(0),
            output_field=models.fields.IntegerField(),
        )
        paid_count = status_count(commerce.Cart.STATUS_PAID)
        unpaid_count = status_count(commerce.Cart.STATUS_ACTIVE)

        groups = profiles.order_by(
            *(order_by + (field, ))
        ).values(
            *(grouping_fields + (field, ))
        ).annotate(
            paid_count=Sum(paid_count),
            unpaid_count=Sum(unpaid_count),
        )
        output.append(ListReport(
            "Grouped by %s" % field_verbose,
            [first_column, field_verbose, "paid", "unpaid"],
            [
                (
                    group_name(group),
                    display_field(group[field]),
                    group["paid_count"] or 0,
                    group["unpaid_count"] or 0,
                )
                for group in groups
            ],
        ))

    # DO the report for individual attendees

    field_names = [
        AttendeeProfile._meta.get_field(field).verbose_name for field in fields
    ]

    def display_field(profile, field):
        field_type = AttendeeProfile._meta.get_field(field)
        attr = getattr(profile, field)

        if isinstance(field_type, models.ManyToManyField):
            return [str(i) for i in attr.all()] or ""
        else:
            return attr

    headings = ["User ID", "Name", "Email", "Product", "Item Status"]
    headings.extend(field_names)
    data = []
    for item in items:
        profile = by_user[item.cart.user]
        line = [
            item.cart.user.id,
            getattr(profile, name_field),
            profile.attendee.user.email,
            item.product,
            status_display[item.cart.status],
        ] + [
            display_field(profile, field) for field in fields
        ]
        data.append(line)

    output.append(AttendeeListReport(
        "Attendees by item with profile data", headings, data,
        link_view=attendee
    ))
    return output
def attendee_data ( request , form , user_id = None ) : status_display = { commerce . Cart . STATUS_ACTIVE : "Unpaid" , commerce . Cart . STATUS_PAID : "Paid" , commerce . Cart . STATUS_RELEASED : "Refunded" , } output = [ ] by_category = ( form . cleaned_data [ "group_by" ] == forms . GroupByForm . GROUP_BY_CATEGORY ) products = form . cleaned_data [ "product" ] categories = form . cleaned_data [ "category" ] fields = form . cleaned_data [ "fields" ] name_field = AttendeeProfile . name_field ( ) items = commerce . ProductItem . objects . filter ( Q ( product__in = products ) | Q ( product__category__in = categories ) , ) . exclude ( cart__status = commerce . Cart . STATUS_RELEASED ) . select_related ( "cart" , "cart__user" , "product" , "product__category" , ) . order_by ( "cart__status" ) # Add invoice nag link links = [ ] invoice_mailout = reverse ( views . invoice_mailout , args = [ ] ) invoice_mailout += "?" + request . META [ "QUERY_STRING" ] links += [ ( invoice_mailout + "&status=1" , "Send invoice reminders" , ) , ( invoice_mailout + "&status=2" , "Send mail for paid invoices" , ) , ] if items . count ( ) > 0 : output . append ( Links ( "Actions" , links ) ) # Make sure we select all of the related fields related_fields = set ( field for field in fields if isinstance ( AttendeeProfile . _meta . get_field ( field ) , RelatedField ) ) # Get all of the relevant attendee profiles in one hit. profiles = AttendeeProfile . objects . filter ( attendee__user__cart__productitem__in = items ) . select_related ( "attendee__user" ) . prefetch_related ( * related_fields ) by_user = { } for profile in profiles : by_user [ profile . attendee . user ] = profile cart = "attendee__user__cart" cart_status = cart + "__status" # noqa product = cart + "__productitem__product" product_name = product + "__name" category = product + "__category" category_name = category + "__name" if by_category : grouping_fields = ( category , category_name ) order_by = ( category , ) first_column = "Category" group_name = lambda i : "%s" % ( i [ category_name ] , ) # noqa else : grouping_fields = ( product , product_name , category_name ) order_by = ( category , ) first_column = "Product" group_name = lambda i : "%s - %s" % ( i [ category_name ] , i [ product_name ] ) # noqa # Group the responses per-field. for field in fields : concrete_field = AttendeeProfile . _meta . get_field ( field ) field_verbose = concrete_field . verbose_name # Render the correct values for related fields if field in related_fields : # Get all of the IDs that will appear all_ids = profiles . order_by ( field ) . values ( field ) all_ids = [ i [ field ] for i in all_ids if i [ field ] is not None ] # Get all of the concrete objects for those IDs model = concrete_field . related_model all_objects = model . objects . filter ( id__in = all_ids ) all_objects_by_id = dict ( ( i . id , i ) for i in all_objects ) # Define a function to render those IDs. def display_field ( value ) : if value in all_objects_by_id : return all_objects_by_id [ value ] else : return None else : def display_field ( value ) : return value status_count = lambda status : Case ( When ( # noqa attendee__user__cart__status = status , then = Value ( 1 ) , ) , default = Value ( 0 ) , output_field = models . fields . IntegerField ( ) , ) paid_count = status_count ( commerce . Cart . STATUS_PAID ) unpaid_count = status_count ( commerce . Cart . STATUS_ACTIVE ) groups = profiles . order_by ( * ( order_by + ( field , ) ) ) . values ( * ( grouping_fields + ( field , ) ) ) . annotate ( paid_count = Sum ( paid_count ) , unpaid_count = Sum ( unpaid_count ) , ) output . append ( ListReport ( "Grouped by %s" % field_verbose , [ first_column , field_verbose , "paid" , "unpaid" ] , [ ( group_name ( group ) , display_field ( group [ field ] ) , group [ "paid_count" ] or 0 , group [ "unpaid_count" ] or 0 , ) for group in groups ] , ) ) # DO the report for individual attendees field_names = [ AttendeeProfile . _meta . get_field ( field ) . verbose_name for field in fields ] def display_field ( profile , field ) : field_type = AttendeeProfile . _meta . get_field ( field ) attr = getattr ( profile , field ) if isinstance ( field_type , models . ManyToManyField ) : return [ str ( i ) for i in attr . all ( ) ] or "" else : return attr headings = [ "User ID" , "Name" , "Email" , "Product" , "Item Status" ] headings . extend ( field_names ) data = [ ] for item in items : profile = by_user [ item . cart . user ] line = [ item . cart . user . id , getattr ( profile , name_field ) , profile . attendee . user . email , item . product , status_display [ item . cart . status ] , ] + [ display_field ( profile , field ) for field in fields ] data . append ( line ) output . append ( AttendeeListReport ( "Attendees by item with profile data" , headings , data , link_view = attendee ) ) return output
Lists attendees for a given product/category selection along with
    profile data.
Lists attendees for a given product / category selection along with profile data .