registrasion/views.py
def guided_registration(request, page_number=None):
    ''' Goes through the registration process in order, making sure user sees
    all valid categories.

    The user must be logged in to see this view.

    Parameter:
        page_number:
            1) Profile form (and e-mail address?)
            2) Ticket type
            3) Remaining products
            4) Mark registration as complete

    Returns:
        render: Renders ``registrasion/guided_registration.html``,
            with the following data::

                {
                    "current_step": int(),  # The current step in the
                                            # registration
                    "sections": sections,   # A list of
                                            # GuidedRegistrationSections
                    "title": str(),         # The title of the page
                    "total_steps": int(),   # The total number of steps
                }

    '''

    PAGE_PROFILE = 1
    PAGE_TICKET = 2
    PAGE_PRODUCTS = 3
    PAGE_PRODUCTS_MAX = 4
    TOTAL_PAGES = 4

    ticket_category = inventory.Category.objects.get(
        id=settings.TICKET_PRODUCT_CATEGORY
    )
    cart = CartController.for_user(request.user)

    attendee = people.Attendee.get_instance(request.user)

    # This guided registration process is only for people who have
    # not completed registration (and has confusing behaviour if you go
    # back to it.)
    if attendee.completed_registration:
        return redirect(review)

    # Calculate the current maximum page number for this user.
    has_profile = hasattr(attendee, "attendeeprofilebase")
    if not has_profile:
        # If there's no profile, they have to go to the profile page.
        max_page = PAGE_PROFILE
        redirect_page = PAGE_PROFILE
    else:
        # We have a profile.
        # Do they have a ticket?
        products = inventory.Product.objects.filter(
            productitem__cart=cart.cart
        )
        products = products.filter(category=ticket_category)

        if products.count() == 0:
            # If no ticket, they can only see the profile or ticket page.
            max_page = PAGE_TICKET
            redirect_page = PAGE_TICKET
        else:
            # If there's a ticket, they should *see* the general products page#
            # but be able to go to the overflow page if needs be.
            max_page = PAGE_PRODUCTS_MAX
            redirect_page = PAGE_PRODUCTS

    if page_number is None or int(page_number) > max_page:
        return redirect("guided_registration", redirect_page)

    page_number = int(page_number)

    next_step = redirect("guided_registration", page_number + 1)

    with BatchController.batch(request.user):

        # This view doesn't work if the conference has sold out.
        available = ProductController.available_products(
            request.user, category=ticket_category
        )
        if not available:
            messages.error(request, "There are no more tickets available.")
            return redirect("dashboard")

        sections = []

        # Build up the list of sections
        if page_number == PAGE_PROFILE:
            # Profile bit
            title = "Attendee information"
            sections = _guided_registration_profile_and_voucher(request)
        elif page_number == PAGE_TICKET:
            # Select ticket
            title = "Select ticket type"
            sections = _guided_registration_products(
                request, GUIDED_MODE_TICKETS_ONLY
            )
        elif page_number == PAGE_PRODUCTS:
            # Select additional items
            title = "Additional items"
            sections = _guided_registration_products(
                request, GUIDED_MODE_ALL_ADDITIONAL
            )
        elif page_number == PAGE_PRODUCTS_MAX:
            # Items enabled by things on page 3 -- only shows things
            # that have not been marked as complete.
            title = "More additional items"
            sections = _guided_registration_products(
                request, GUIDED_MODE_EXCLUDE_COMPLETE
            )

        if not sections:
            # We've filled in every category
            attendee.completed_registration = True
            attendee.save()
            return redirect("review")

        if sections and request.method == "POST":
            for section in sections:
                if section.form.errors:
                    break
            else:
                # We've successfully processed everything
                return next_step

    data = {
        "current_step": page_number,
        "sections": sections,
        "title": title,
        "total_steps": TOTAL_PAGES,
    }
    return render(request, "registrasion/guided_registration.html", data)
def guided_registration(request, page_number=None):
    ''' Goes through the registration process in order, making sure user sees
    all valid categories.

    The user must be logged in to see this view.

    Parameter:
        page_number:
            1) Profile form (and e-mail address?)
            2) Ticket type
            3) Remaining products
            4) Mark registration as complete

    Returns:
        render: Renders ``registrasion/guided_registration.html``,
            with the following data::

                {
                    "current_step": int(),  # The current step in the
                                            # registration
                    "sections": sections,   # A list of
                                            # GuidedRegistrationSections
                    "title": str(),         # The title of the page
                    "total_steps": int(),   # The total number of steps
                }

    '''

    PAGE_PROFILE = 1
    PAGE_TICKET = 2
    PAGE_PRODUCTS = 3
    PAGE_PRODUCTS_MAX = 4
    TOTAL_PAGES = 4

    ticket_category = inventory.Category.objects.get(
        id=settings.TICKET_PRODUCT_CATEGORY
    )
    cart = CartController.for_user(request.user)

    attendee = people.Attendee.get_instance(request.user)

    # This guided registration process is only for people who have
    # not completed registration (and has confusing behaviour if you go
    # back to it.)
    if attendee.completed_registration:
        return redirect(review)

    # Calculate the current maximum page number for this user.
    has_profile = hasattr(attendee, "attendeeprofilebase")
    if not has_profile:
        # If there's no profile, they have to go to the profile page.
        max_page = PAGE_PROFILE
        redirect_page = PAGE_PROFILE
    else:
        # We have a profile.
        # Do they have a ticket?
        products = inventory.Product.objects.filter(
            productitem__cart=cart.cart
        )
        products = products.filter(category=ticket_category)

        if products.count() == 0:
            # If no ticket, they can only see the profile or ticket page.
            max_page = PAGE_TICKET
            redirect_page = PAGE_TICKET
        else:
            # If there's a ticket, they should *see* the general products page#
            # but be able to go to the overflow page if needs be.
            max_page = PAGE_PRODUCTS_MAX
            redirect_page = PAGE_PRODUCTS

    if page_number is None or int(page_number) > max_page:
        return redirect("guided_registration", redirect_page)

    page_number = int(page_number)

    next_step = redirect("guided_registration", page_number + 1)

    with BatchController.batch(request.user):

        # This view doesn't work if the conference has sold out.
        available = ProductController.available_products(
            request.user, category=ticket_category
        )
        if not available:
            messages.error(request, "There are no more tickets available.")
            return redirect("dashboard")

        sections = []

        # Build up the list of sections
        if page_number == PAGE_PROFILE:
            # Profile bit
            title = "Attendee information"
            sections = _guided_registration_profile_and_voucher(request)
        elif page_number == PAGE_TICKET:
            # Select ticket
            title = "Select ticket type"
            sections = _guided_registration_products(
                request, GUIDED_MODE_TICKETS_ONLY
            )
        elif page_number == PAGE_PRODUCTS:
            # Select additional items
            title = "Additional items"
            sections = _guided_registration_products(
                request, GUIDED_MODE_ALL_ADDITIONAL
            )
        elif page_number == PAGE_PRODUCTS_MAX:
            # Items enabled by things on page 3 -- only shows things
            # that have not been marked as complete.
            title = "More additional items"
            sections = _guided_registration_products(
                request, GUIDED_MODE_EXCLUDE_COMPLETE
            )

        if not sections:
            # We've filled in every category
            attendee.completed_registration = True
            attendee.save()
            return redirect("review")

        if sections and request.method == "POST":
            for section in sections:
                if section.form.errors:
                    break
            else:
                # We've successfully processed everything
                return next_step

    data = {
        "current_step": page_number,
        "sections": sections,
        "title": title,
        "total_steps": TOTAL_PAGES,
    }
    return render(request, "registrasion/guided_registration.html", data)
Goes through the registration process in order, making sure user sees
    all valid categories.

    The user must be logged in to see this view.

    Parameter:
        page_number:
            1) Profile form (and e-mail address?)
            2) Ticket type
            3) Remaining products
            4) Mark registration as complete

    Returns:
        render: Renders ``registrasion/guided_registration.html``,
            with the following data::

                {
                    "current_step": int(),  # The current step in the
                                            # registration
                    "sections": sections,   # A list of
                                            # GuidedRegistrationSections
                    "title": str(),         # The title of the page
                    "total_steps": int(),   # The total number of steps
                }