View all members' preferences. This view also includes forms to create an
    entire semester's worth of weekly workshifts.

def assign_shifts_view(request, semester):
    """
    View all members' preferences. This view also includes forms to create an
    entire semester's worth of weekly workshifts.
    """
    page_name = "Assign Shifts"

    auto_assign_shifts_form = None
    random_assign_instances_form = None
    clear_assign_form = None

    if WorkshiftPool.objects.filter(semester=semester).count():
        auto_assign_shifts_form = AutoAssignShiftForm(
            data=request.POST if AutoAssignShiftForm.name in request.POST else None,
            semester=semester,
        )
        random_assign_instances_form = RandomAssignInstancesForm(
            data=request.POST if RandomAssignInstancesForm.name in request.POST else None,
            semester=semester,
        )
        clear_assign_form = ClearAssignmentsForm(
            data=request.POST if ClearAssignmentsForm.name in request.POST else None,
            semester=semester,
        )

    forms = [auto_assign_shifts_form, random_assign_instances_form,
             clear_assign_form]

    if auto_assign_shifts_form and auto_assign_shifts_form.is_valid():
        unassigned_profiles = auto_assign_shifts_form.save()
        message = "Assigned workshifters to regular workshifts."
        if unassigned_profiles:
            message += " The following workshifters were not given " \
              "complete assignments: "
            message += ", ".join(i.user.get_full_name() for i in unassigned_profiles)
        messages.add_message(request, messages.INFO, message)
        return HttpResponseRedirect(wurl(
            "workshift:assign_shifts",
            sem_url=semester.sem_url,
        ))

    if random_assign_instances_form and random_assign_instances_form.is_valid():
        unassigned_profiles, unassigned_shifts = \
          random_assign_instances_form.save()
        message = "Assigned workshifters randomly to instances within {}." \
          .format(random_assign_instances_form.cleaned_data["pool"])
        if unassigned_profiles:
            message += "The following workshifers were not given " \
              "complete assignments: "
            message += ", ".join(i.user.get_full_name() for i in unassigned_profiles)
        messages.add_message(request, messages.INFO, message)
        return HttpResponseRedirect(wurl(
            "workshift:assign_shifts",
            sem_url=semester.sem_url,
        ))

    if clear_assign_form and clear_assign_form.is_valid():
        clear_assign_form.save()
        messages.add_message(
            request,
            messages.INFO,
            "Cleared all workshifters from their regular workshift "
            "assignments",
        )
        return HttpResponseRedirect(wurl(
            "workshift:assign_shifts",
            sem_url=semester.sem_url,
        ))

    shifts = RegularWorkshift.objects.filter(
        pool__semester=semester,
        active=True,
    ).exclude(
        workshift_type__assignment=WorkshiftType.NO_ASSIGN,
    )

    assign_forms = []
    for shift in shifts:
        form = AssignShiftForm(
            data=request.POST if "individual_assign" in request.POST else None,
            prefix="shift-{}".format(shift.pk),
            instance=shift,
            semester=semester,
        )
        assign_forms.append(form)

    if assign_forms and all(i.is_valid() for i in assign_forms):
        for form in assign_forms:
            form.save()
        messages.add_message(
            request,
            messages.INFO,
            "Workshift assignments saved.",
        )
        return HttpResponseRedirect(wurl(
            "workshift:assign_shifts",
            sem_url=semester.sem_url,
        ))

    workshifters = WorkshiftProfile.objects.filter(semester=semester)
    pools = WorkshiftPool.objects.filter(semester=semester).order_by(
        "-is_primary", "title",
    )

    pool_hours = []
    for workshifter in workshifters:
        hours_owed = []
        for pool in pools:
            hours = workshifter.pool_hours.get(pool=pool)
            hours_owed.append(hours.hours - hours.assigned_hours)

        if any(i > 0 for i in hours_owed):
            pool_hours.append(hours_owed)

    total_pool_hours = [
        sum(hours[i] for hours in pool_hours)
        for i in range(len(pool_hours[0]) if len(pool_hours) > 0 else 0)
    ]

    return render_to_response("assign_shifts.html", {
        "page_name": page_name,
        "forms": forms,
        "assign_forms": assign_forms,
        "unassigned_profiles": zip(workshifters, pool_hours),
        "pools": pools,
        "total_pool_hours": total_pool_hours,
    }, context_instance=RequestContext(request))