def __init__(self, request, step, data=None, initial=None, errors=None): OrderForm.__init__(self, request, step, data, initial, errors) is_first_step = step == checkout.CHECKOUT_STEP_FIRST is_last_step = step == checkout.CHECKOUT_STEP_LAST is_payment_step = step == checkout.CHECKOUT_STEP_PAYMENT # Get list of country names countries = make_choices(get_country_names_list()) if settings.SHOP_CHECKOUT_STEPS_SPLIT: if is_first_step: # Change country widgets to a Select widget self.fields["billing_detail_country"].widget = forms.Select(choices=countries) self.fields["billing_detail_country"].initial = settings.SHOP_DEFAULT_COUNTRY self.fields["shipping_detail_country"].widget = forms.Select(choices=countries) self.fields["shipping_detail_country"].initial= settings.SHOP_DEFAULT_COUNTRY if is_payment_step: # Make card number and cvv fields use the data encrypted widget self.fields["card_number"].widget = DataEncryptedTextInput() self.fields["card_ccv"].widget = DataEncryptedPasswordInput() else: # Change country widgets to a Select widget self.fields["billing_detail_country"].widget = forms.Select(choices=countries) self.fields["billing_detail_country"].initial = settings.SHOP_DEFAULT_COUNTRY self.fields["shipping_detail_country"].widget = forms.Select(choices=countries) self.fields["shipping_detail_country"].initial= settings.SHOP_DEFAULT_COUNTRY if settings.SHOP_PAYMENT_STEP_ENABLED: # Make card number and cvv fields use the data encrypted widget self.fields["card_number"].widget = DataEncryptedTextInput() self.fields["card_ccv"].widget = DataEncryptedPasswordInput()
def test_order(self): """ Test that a completed order contains cart items and that they're removed from stock. """ # Add to cart. self._reset_variations() variation = self._product.variations.all()[0] self._add_to_cart(variation, TEST_STOCK) cart = Cart.objects.from_request(self.client) # Post order. data = { "step": len(CHECKOUT_STEPS), "billing_detail_email": "*****@*****.**", "discount_code": "", } for field_name, field in list(OrderForm(None, None).fields.items()): value = field.choices[-1][1] if hasattr(field, "choices") else "1" data.setdefault(field_name, value) self.client.post(reverse("shop_checkout"), data) try: order = Order.objects.from_request(self.client) except Order.DoesNotExist: self.fail("Couldn't create an order") items = order.items.all() variation = self._product.variations.all()[0] self.assertEqual(cart.total_quantity(), 0) self.assertEqual(len(items), 1) self.assertEqual(items[0].sku, variation.sku) self.assertEqual(items[0].quantity, TEST_STOCK) self.assertEqual(variation.num_in_stock, TEST_STOCK) self.assertEqual(order.item_total, TEST_PRICE * TEST_STOCK)
def __init__(self, request, step, data=None, initial=None, errors=None): OrderForm.__init__(self, request, step, data, initial, errors) is_first_step = step == checkout.CHECKOUT_STEP_FIRST is_last_step = step == checkout.CHECKOUT_STEP_LAST is_payment_step = step == checkout.CHECKOUT_STEP_PAYMENT # Get list of country names countries = make_choices(get_country_names_list()) if settings.SHOP_CHECKOUT_STEPS_SPLIT: if is_first_step: # Change country widgets to a Select widget self.fields["billing_detail_country"].widget = forms.Select( choices=countries) self.fields[ "billing_detail_country"].initial = settings.SHOP_DEFAULT_COUNTRY self.fields["shipping_detail_country"].widget = forms.Select( choices=countries) self.fields[ "shipping_detail_country"].initial = settings.SHOP_DEFAULT_COUNTRY if is_payment_step: # Make card number and cvv fields use the data encrypted widget self.fields["card_number"].widget = DataEncryptedTextInput() self.fields["card_ccv"].widget = DataEncryptedPasswordInput() else: # Change country widgets to a Select widget self.fields["billing_detail_country"].widget = forms.Select( choices=countries) self.fields[ "billing_detail_country"].initial = settings.SHOP_DEFAULT_COUNTRY self.fields["shipping_detail_country"].widget = forms.Select( choices=countries) self.fields[ "shipping_detail_country"].initial = settings.SHOP_DEFAULT_COUNTRY if settings.SHOP_PAYMENT_STEP_ENABLED: # Make card number and cvv fields use the data encrypted widget self.fields["card_number"].widget = DataEncryptedTextInput() self.fields["card_ccv"].widget = DataEncryptedPasswordInput()
def get_order_form(self, step): VISA = 'visa' MASTERCARD = 'mastercard' AMEX = 'amex' DISCOVER = 'discover' DEBIT = 'debit' CASH = 'cash' PAYMENT_CHOICES = ( (None, '---------'), (CASH, 'Cash'), (DEBIT, 'Debit'), (VISA, 'Visa'), (MASTERCARD, 'Mastercard'), (DISCOVER, 'Discover'), (AMEX, 'American Express'), ) kwargs = self.get_order_form_kwargs(step) form = OrderForm(**kwargs) form.fields['payment_type'] = forms.ChoiceField(choices=PAYMENT_CHOICES) return form
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)
django.setup() except AttributeError: # < 1.7 pass if sys.argv[-2:] == ["docs", "docs/build"]: import cartridge from mezzanine.utils import docs docs.build_settings_docs(docs_path, prefix="SHOP_") docs.build_changelog(docs_path, package_name="cartridge") #docs.build_modelgraph(docs_path, package_name="cartridge") try: from cartridge.shop.models import Order from cartridge.shop.forms import OrderForm fields = { "form": OrderForm(None, None).fields.keys(), "model": [f.name for f in Order._meta.fields], } for name, names in fields.items(): file_name = "order_%s_fields.rst" % name with open(os.path.join(docs_path, file_name), "w") as f: f.write(" * ``" + "``\n * ``".join(names) + "``") except Exception, e: print "Error generating docs for fields: %s" % e # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.append(os.path.abspath('.')) # -- General configuration -----------------------------------------------------
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)