Пример #1
0
def checkout(request):
    """
    Display the order form and handle processing of each step.
    """
    
    # Do the authentication check here rather than using standard login_required
    # decorator. This means we can check for a custom LOGIN_URL and fall back
    # to our own login view.
    if settings.SHOP_CHECKOUT_ACCOUNT_REQUIRED and \
        not request.user.is_authenticated():
        return HttpResponseRedirect("%s?next=%s" % (settings.SHOP_LOGIN_URL, 
                                                    reverse("shop_checkout")))
    
    step = int(request.POST.get("step", CHECKOUT_STEP_FIRST))
    initial = initial_order_data(request)
    form = OrderForm(request, step, initial=initial)
    data = request.POST

    if request.POST.get("back") is not None:
        step -= 1
        form = OrderForm(request, step, initial=initial)
    elif request.method == "POST":
        form = OrderForm(request, step, initial=initial, data=data)
        if form.is_valid():
            checkout_errors = []
            request.session["order"] = dict(form.cleaned_data)
            for field in ("card_number", "card_expiry_month", 
                "card_expiry_year", "card_ccv"):
                del request.session["order"][field]

            # Handle shipping and discount code on first step.
            if step == CHECKOUT_STEP_FIRST:
                try:
                    billing_shipping(request, form)
                except CheckoutError, e:
                    checkout_errors.append(e)
                if hasattr(form, "discount"):
                    cart = Cart.objects.from_request(request)
                    discount_total = discount.calculate(cart.total_price())
                    request.session["free_shipping"] = discount.free_shipping
                    request.session["discount_total"] = discount_total

            # Process order on final step.
            if step == CHECKOUT_STEP_LAST and not checkout_errors:
                try:
                    payment(request, form)
                except CheckoutError, e:
                    checkout_errors.append(e)
                    if settings.SHOP_CHECKOUT_STEPS_CONFIRMATION:
                        step -= 1
                else:    
                    order = form.save(commit=False)
                    order.process(request)
                    send_order_email(request, order)
                    response = HttpResponseRedirect(reverse("shop_complete"))
                    if form.cleaned_data.get("remember") is not None:
                        remembered = "%s:%s" % (sign(order.key), order.key)
                        set_cookie(response, "remember", remembered, 
                            secure=request.is_secure())
                    else:
                        response.delete_cookie("remember")
                    return response

            # Assign checkout errors to new form if any and re-run is_valid 
            # if valid set form to next step.
            form = OrderForm(request, step, initial=initial, data=data, 
                checkout_errors=checkout_errors)
            if form.is_valid():
                step += 1
                form = OrderForm(request, step, initial=initial)
Пример #2
0
def checkout_steps(request):
    """
    Display the order form and handle processing of each step.
    """

    # Do the authentication check here rather than using standard
    # login_required decorator. This means we can check for a custom
    # LOGIN_URL and fall back to our own login view.
    authenticated = request.user.is_authenticated()
    if settings.SHOP_CHECKOUT_ACCOUNT_REQUIRED and not authenticated:
        url = "%s?next=%s" % (settings.LOGIN_URL, reverse("shop_checkout"))
        return HttpResponseRedirect(url)

    step = int(request.POST.get("step", checkout.CHECKOUT_STEP_FIRST))
    initial = checkout.initial_order_data(request)
    form = OrderForm(request, step, initial=initial)
    data = request.POST
    checkout_errors = []

    if request.POST.get("back") is not None:
        # Back button in the form was pressed - load the order form
        # for the previous step and maintain the field values entered.
        step -= 1
        form = OrderForm(request, step, initial=initial)
    elif request.method == "POST":
        form = OrderForm(request, step, initial=initial, data=data)
        if form.is_valid():
            # Copy the current form fields to the session so that
            # they're maintained if the customer leaves the checkout
            # process, but remove sensitive fields from the session
            # such as the credit card fields so that they're never
            # stored anywhere.
            request.session["order"] = dict(form.cleaned_data)
            sensitive_card_fields = ("card_number", "card_expiry_month",
                                     "card_expiry_year", "card_ccv")
            for field in sensitive_card_fields:
                del request.session["order"][field]

            # FIRST CHECKOUT STEP - handle shipping and discount code.
            if step == checkout.CHECKOUT_STEP_FIRST:
                try:
                    billship_handler(request, form)
                except checkout.CheckoutError, e:
                    checkout_errors.append(e)
                form.set_discount()

            # FINAL CHECKOUT STEP - handle payment and process order.
            if step == checkout.CHECKOUT_STEP_LAST and not checkout_errors:
                # Create and save the inital order object so that
                # the payment handler has access to all of the order
                # fields. If there is a payment error then delete the
                # order, otherwise remove the cart items from stock
                # and send the order reciept email.
                order = form.save(commit=False)
                order.setup(request)
                # Try payment.
                try:
                    payment_handler(request, form, order)
                except checkout.CheckoutError, e:
                    # Error in payment handler.
                    order.delete()
                    checkout_errors.append(e)
                    if settings.SHOP_CHECKOUT_STEPS_CONFIRMATION:
                        step -= 1
                else:
                    # Finalize order - ``order.complete()`` performs
                    # final cleanup of session and cart.
                    # ``order_handler()`` can be defined by the
                    # developer to implement custom order processing.
                    # Then send the order email to the customer.
                    order.complete(request)
                    order_handler(request, form, order)
                    checkout.send_order_email(request, order)
                    # Set the cookie for remembering address details
                    # if the "remember" checkbox was checked.
                    response = HttpResponseRedirect(reverse("shop_complete"))
                    if form.cleaned_data.get("remember") is not None:
                        remembered = "%s:%s" % (sign(order.key), order.key)
                        set_cookie(response, "remember", remembered,
                                   secure=request.is_secure())
                    else:
                        response.delete_cookie("remember")
                    return response

            # If any checkout errors, assign them to a new form and
            # re-run is_valid. If valid, then set form to the next step.
            form = OrderForm(request, step, initial=initial, data=data,
                             errors=checkout_errors)
            if form.is_valid():
                step += 1
                form = OrderForm(request, step, initial=initial)