Esempio n. 1
0
def _handle_voucher(request, prefix):
    ''' Handles a voucher form in the given request. Returns the voucher
    form instance, and whether the voucher code was handled. '''

    voucher_form = forms.VoucherForm(request.POST or None, prefix=prefix)
    current_cart = CartController.for_user(request.user)

    if (voucher_form.is_valid() and
            voucher_form.cleaned_data["voucher"].strip()):

        voucher = voucher_form.cleaned_data["voucher"]
        voucher = inventory.Voucher.normalise_code(voucher)

        if len(current_cart.cart.vouchers.filter(code=voucher)) > 0:
            # This voucher has already been applied to this cart.
            # Do not apply code
            handled = False
        else:
            try:
                current_cart.apply_voucher(voucher)
            except Exception as e:
                voucher_form.add_error("voucher", e)
            handled = True
    else:
        handled = False

    return (voucher_form, handled)
Esempio n. 2
0
def handle_voucher(request, prefix):
    ''' Handles a voucher form in the given request. Returns the voucher
    form instance, and whether the voucher code was handled. '''

    voucher_form = forms.VoucherForm(request.POST or None, prefix=prefix)
    current_cart = CartController.for_user(request.user)

    if (voucher_form.is_valid() and
            voucher_form.cleaned_data["voucher"].strip()):

        voucher = voucher_form.cleaned_data["voucher"]
        voucher = inventory.Voucher.normalise_code(voucher)

        if len(current_cart.cart.vouchers.filter(code=voucher)) > 0:
            # This voucher has already been applied to this cart.
            # Do not apply code
            handled = False
        else:
            try:
                current_cart.apply_voucher(voucher)
            except Exception as e:
                voucher_form.add_error("voucher", e)
            handled = True
    else:
        handled = False

    return (voucher_form, handled)
Esempio n. 3
0
def checkout(request):
    ''' Runs the checkout process for the current cart.

    If the query string contains ``fix_errors=true``, Registrasion will attempt
    to fix errors preventing the system from checking out, including by
    cancelling expired discounts and vouchers, and removing any unavailable
    products.

    Returns:
        render or redirect:
            If the invoice is generated successfully, or there's already a
            valid invoice for the current cart, redirect to ``invoice``.
            If there are errors when generating the invoice, render
            ``registrasion/checkout_errors.html`` with the following data::

                {
                    "error_list", [str, ...]  # The errors to display.
                }

    '''

    current_cart = CartController.for_user(request.user)

    if "fix_errors" in request.GET and request.GET["fix_errors"] == "true":
        current_cart.fix_simple_errors()

    try:
        current_invoice = InvoiceController.for_cart(current_cart.cart)
    except ValidationError as ve:
        return _checkout_errors(request, ve)

    return redirect("invoice", current_invoice.invoice.id)
Esempio n. 4
0
def extend_reservation(request, user_id, days=7):
    ''' Allows staff to extend the reservation on a given user's cart.
    '''

    user = User.objects.get(id=int(user_id))
    cart = CartController.for_user(user)
    cart.extend_reservation(datetime.timedelta(days=days))

    return redirect(request.META["HTTP_REFERER"])
Esempio n. 5
0
def handle_products(request, category, products, prefix):
    ''' Handles a products list form in the given request. Returns the
    form instance, the discounts applicable to this form, and whether the
    contents were handled. '''

    current_cart = CartController.for_user(request.user)

    ProductsForm = forms.ProductsForm(category, products)

    # Create initial data for each of products in category
    items = commerce.ProductItem.objects.filter(
        product__in=products,
        cart=current_cart.cart,
    ).select_related("product")
    quantities = []
    seen = set()

    for item in items:
        quantities.append((item.product, item.quantity))
        seen.add(item.product)

    zeros = set(products) - seen
    for product in zeros:
        quantities.append((product, 0))

    products_form = ProductsForm(
        request.POST or None,
        product_quantities=quantities,
        prefix=prefix,
    )

    if request.method == "POST" and products_form.is_valid():
        if products_form.has_changed():
            set_quantities_from_products_form(products_form, current_cart)

        # If category is required, the user must have at least one
        # in an active+valid cart
        if category.required:
            carts = commerce.Cart.objects.filter(user=request.user)
            items = commerce.ProductItem.objects.filter(
                product__category=category,
                cart=carts,
            )
            if len(items) == 0:
                products_form.add_error(
                    None,
                    "You must have at least one item from this category",
                )
    handled = False if products_form.errors else True

    discounts = discount.available_discounts(request.user, [], products)

    return products_form, discounts, handled
Esempio n. 6
0
def handle_products(request, category, products, prefix):
    ''' Handles a products list form in the given request. Returns the
    form instance, the discounts applicable to this form, and whether the
    contents were handled. '''

    current_cart = CartController.for_user(request.user)

    ProductsForm = forms.ProductsForm(category, products)

    # Create initial data for each of products in category
    items = commerce.ProductItem.objects.filter(
        product__in=products,
        cart=current_cart.cart,
    ).select_related("product")
    quantities = []
    seen = set()

    for item in items:
        quantities.append((item.product, item.quantity))
        seen.add(item.product)

    zeros = set(products) - seen
    for product in zeros:
        quantities.append((product, 0))

    products_form = ProductsForm(
        request.POST or None,
        product_quantities=quantities,
        prefix=prefix,
    )

    if request.method == "POST" and products_form.is_valid():
        if products_form.has_changed():
            set_quantities_from_products_form(products_form, current_cart)

        # If category is required, the user must have at least one
        # in an active+valid cart
        if category.required:
            carts = commerce.Cart.objects.filter(user=request.user)
            items = commerce.ProductItem.objects.filter(
                product__category=category,
                cart=carts,
            )
            if len(items) == 0:
                products_form.add_error(
                    None,
                    "You must have at least one item from this category",
                )
    handled = False if products_form.errors else True

    discounts = discount.available_discounts(request.user, [], products)

    return products_form, discounts, handled
Esempio n. 7
0
def checkout(request):
    ''' Runs checkout for the current cart of items, ideally generating an
    invoice. '''

    current_cart = CartController.for_user(request.user)

    if "fix_errors" in request.GET and request.GET["fix_errors"] == "true":
        current_cart.fix_simple_errors()

    try:
        current_invoice = InvoiceController.for_cart(current_cart.cart)
    except ValidationError as ve:
        return checkout_errors(request, ve)

    return redirect("invoice", current_invoice.invoice.id)
Esempio n. 8
0
def checkout(request):
    ''' Runs checkout for the current cart of items, ideally generating an
    invoice. '''

    current_cart = CartController.for_user(request.user)

    if "fix_errors" in request.GET and request.GET["fix_errors"] == "true":
        current_cart.fix_simple_errors()

    try:
        current_invoice = InvoiceController.for_cart(current_cart.cart)
    except ValidationError as ve:
        return checkout_errors(request, ve)

    return redirect("invoice", current_invoice.invoice.id)
Esempio n. 9
0
def checkout(request, user_id=None):
    ''' Runs the checkout process for the current cart.

    If the query string contains ``fix_errors=true``, Registrasion will attempt
    to fix errors preventing the system from checking out, including by
    cancelling expired discounts and vouchers, and removing any unavailable
    products.

    Arguments:
        user_id (castable to int):
            If the requesting user is staff, then the user ID can be used to
            run checkout for another user.
    Returns:
        render or redirect:
            If the invoice is generated successfully, or there's already a
            valid invoice for the current cart, redirect to ``invoice``.
            If there are errors when generating the invoice, render
            ``registrasion/checkout_errors.html`` with the following data::

                {
                    "error_list", [str, ...]  # The errors to display.
                }

    '''

    if user_id is not None:
        if request.user.is_staff:
            user = User.objects.get(id=int(user_id))
        else:
            raise Http404()
    else:
        user = request.user

    current_cart = CartController.for_user(user)

    if "fix_errors" in request.GET and request.GET["fix_errors"] == "true":
        current_cart.fix_simple_errors()

    try:
        current_invoice = InvoiceController.for_cart(current_cart.cart)
    except ValidationError as ve:
        return _checkout_errors(request, ve)

    return redirect("invoice", current_invoice.invoice.id)
Esempio n. 10
0
def amend_registration(request, user_id):
    ''' Allows staff to amend a user's current registration cart, and etc etc.
    '''

    user = User.objects.get(id=int(user_id))
    current_cart = CartController.for_user(user)

    items = commerce.ProductItem.objects.filter(
        cart=current_cart.cart,
    ).select_related("product")
    initial = [{"product": i.product, "quantity": i.quantity} for i in items]

    StaffProductsFormSet = forms.staff_products_formset_factory(user)
    formset = StaffProductsFormSet(
        request.POST or None,
        initial=initial,
        prefix="products",
    )

    for item, form in zip(items, formset):
        queryset = inventory.Product.objects.filter(id=item.product.id)
        form.fields["product"].queryset = queryset

    voucher_form = forms.VoucherForm(
        request.POST or None,
        prefix="voucher",
    )

    if request.POST and formset.is_valid():

        pq = [
            (f.cleaned_data["product"], f.cleaned_data["quantity"])
            for f in formset
            if "product" in f.cleaned_data and
            f.cleaned_data["product"] is not None
        ]

        try:
            current_cart.set_quantities(pq)
            return redirect(amend_registration, user_id)
        except ValidationError as ve:
            for ve_field in ve.error_list:
                product, message = ve_field.message
                for form in formset:
                    if "product" not in form.cleaned_data:
                        # This is the empty form.
                        continue
                    if form.cleaned_data["product"] == product:
                        form.add_error("quantity", message)

    if request.POST and voucher_form.has_changed() and voucher_form.is_valid():
        try:
            current_cart.apply_voucher(voucher_form.cleaned_data["voucher"])
            return redirect(amend_registration, user_id)
        except ValidationError as ve:
            voucher_form.add_error(None, ve)

    ic = ItemController(user)
    data = {
        "user": user,
        "paid": ic.items_purchased(),
        "cancelled": ic.items_released(),
        "form": formset,
        "voucher_form": voucher_form,
    }

    return render(request, "registrasion/amend_registration.html", data)
Esempio n. 11
0
def attendee(request, form, user_id=None):
    ''' Returns a list of all manifested attendees if no attendee is specified,
    else displays the attendee manifest. '''

    if user_id is None and form.cleaned_data["user"] is not None:
        user_id = form.cleaned_data["user"]

    if user_id is None:
        return attendee_list(request)

    attendee = people.Attendee.objects.get(user__id=user_id)
    name = attendee.attendeeprofilebase.attendee_name()

    reports = []

    profile_data = []
    try:
        profile = people.AttendeeProfileBase.objects.get_subclass(
            attendee=attendee)
        fields = profile._meta.get_fields()
    except people.AttendeeProfileBase.DoesNotExist:
        fields = []

    exclude = set(["attendeeprofilebase_ptr", "id"])
    for field in fields:
        if field.name in exclude:
            # Not actually important
            continue
        if not hasattr(field, "verbose_name"):
            continue  # Not a publicly visible field
        value = getattr(profile, field.name)

        if isinstance(field, models.ManyToManyField):
            value = ", ".join(str(i) for i in value.all())

        profile_data.append((field.verbose_name, value))

    cart = CartController.for_user(attendee.user)
    reservation = cart.cart.reservation_duration + cart.cart.time_last_updated
    profile_data.append(("Current cart reserved until", reservation))

    reports.append(ListReport("Profile", ["", ""], profile_data))

    links = []
    links.append((
        reverse(views.badge, args=[user_id]),
        "View badge",
    ))
    links.append((
        reverse(views.amend_registration, args=[user_id]),
        "Amend current cart",
    ))
    links.append((
        reverse(views.extend_reservation, args=[user_id]),
        "Extend reservation",
    ))

    reports.append(Links("Actions for " + name, links))

    # Paid and pending  products
    ic = ItemController(attendee.user)
    reports.append(
        ListReport(
            "Paid Products",
            ["Product", "Quantity"],
            [(pq.product, pq.quantity) for pq in ic.items_purchased()],
        ))
    reports.append(
        ListReport(
            "Unpaid Products",
            ["Product", "Quantity"],
            [(pq.product, pq.quantity) for pq in ic.items_pending()],
        ))

    # Invoices
    invoices = commerce.Invoice.objects.filter(user=attendee.user, )
    reports.append(
        QuerysetReport(
            "Invoices",
            ["id", "get_status_display", "value"],
            invoices,
            headings=["Invoice ID", "Status", "Value"],
            link_view=views.invoice,
        ))

    # Credit Notes
    credit_notes = commerce.CreditNote.objects.filter(
        invoice__user=attendee.user, ).select_related("invoice",
                                                      "creditnoteapplication",
                                                      "creditnoterefund")

    reports.append(
        QuerysetReport(
            "Credit Notes",
            ["id", "status", "value"],
            credit_notes,
            link_view=views.credit_note,
        ))

    # All payments
    payments = commerce.PaymentBase.objects.filter(
        invoice__user=attendee.user, ).select_related("invoice")

    reports.append(
        QuerysetReport(
            "Payments",
            ["invoice__id", "id", "reference", "amount"],
            payments,
            link_view=views.invoice,
        ))

    return reports