def render_cart(request, template_name='product/cart_fragment.html'): cart = shcart.get_cart_from_request(request) cart_items = shcart.get_cart_items(cart) if request.is_ajax(): response = serializers.serialize("json", cart_items) return HttpResponse(response, content_type='application/json') return render_to_response(template_name, {'cart_items': cart_items} )
def confirm_selections(request): "Display the selected products and pricing info and identify payment mechanism." account = request.user.get_profile().account cart = shcart.get_cart_from_request(request) cart_items = shcart.get_cart_items(cart) cart_total = sum([i.extended_price for i in cart_items]) return render_to_response( "product/product_selection_review.html", locals(), context_instance=RequestContext(request) )
def select_products(request, template="product/product_selection.html", extra_context={}): "Provides the template with a product list and the cart item list, combined for users purchase." user = request.user if user is None or not user.is_authenticated(): return HttpResponseRedirect('/') ## FIXME with decorators.. account = request.user.get_profile().account # post means they've selected somethign to purchase. put the items in your 'cart' and go to confirm stage cart = shcart.get_cart_from_request(request) if request.method == 'POST': shcart.destroy_cart(cart) cart_empty = True product_quantities = [ (int(id[6:]), int(count or 0)) for (id, count) in request.POST.items() if id.startswith('count_') and int(count or 0)] logger.debug('product_quantities\n\n\n\n %s, %s, %s', product_quantities, bool(product_quantities), len(product_quantities)) if product_quantities: cart_empty = False for prod_id, qty in product_quantities: shcart.add_item(cart, prod_id, int(qty)) if '_purchase' in request.POST: if cart_empty: errors = ["You cannot checkout until you purchase at least one item!"] else: # go to confirmation page return HttpResponseRedirect(reverse("confirm_purchase_selections")) return HttpResponseRedirect(reverse('select_products')) cart_items = shcart.get_cart_items(cart) cart_total = sum([i.extended_price for i in cart_items]) item_hash = dict() for item in cart_items: item_hash[item.product_id] = item products = Product.objects.all() pricelist = [ (product, item_hash.get(product.id, 0)) for product in products] # the following won't work, since extended_price is not a database field... # cart_total = cart_items.aggregate(Sum('extended_price')).get('extended_price__sum', 0) logger.debug('cart items: %s', cart_items) context = {'pricelist': pricelist, 'cart_items': cart_items, 'cart_total': cart_total} context.update(extra_context) return render_to_response( template, context, context_instance=RequestContext(request) )
def paypal_checkout(request, collection_template='product/paypal_checkout.html', confirmation_template='product/paypal_checkout.html', success_url=None, form_class=PaymentForm, extra_context=None): """ Checkout the current shopping cart via paypal.. Template context: - phase - account - form - cart_items Checkout consists of three steps: 1) collect credit card info (while reviewing order info) - on submit we do local validation. cycle until this process succeeds or user quits. - user can select paypal checkout from the point which initiates alternate flow (managed by the paypal plugin) 2) display card info and order info for final review - on submit we - create an invoice from the currnent cart - destroy the current cart - send card / order info to payment gateway for processing - if processing succeeds - find the invoice and mark it paid - else if it fails - find the invoice and mark it 'failed'. attach failure info to invoice for tracking 3) display invoice and success/failure message If the user elects paypal checkout, there is an alternate flow. """ def item_from_invoice(inv): item = { "amt": inv.total, "invnum": inv.id, "custom": request.session.session_key, # for debugging "desc": inv.description, "cancelurl": make_site_url(reverse('select_products')), # Express checkout cancel url "returnurl": make_site_url(reverse('dealer-dashboard')) # Express checkout return url } return item phase = request.GET.get('p', 'collect') logger.debug('entered paypal_checkout: phase=%s, GET=%s, POST=%s', phase, request.GET, request.POST) # gather some info we always need account = request.user.get_profile().account cart = shcart.get_cart_from_request(request) cart_items = shcart.get_cart_items(cart) template = collection_template if request.method == 'GET': # dieplay cc form form = form_class() elif request.method == 'POST': # validate the cc form. form = form_class(request.POST, request.FILES) if phase == 'collect': logger.debug(' paypal_checkout: collect phase...') if form.is_valid(): template = confirmation_template phase = 'confirm' elif phase == 'confirm': logger.debug(' paypal_checkout: confirm phase...') if form.is_valid(): logger.debug(' paypal_checkout: confirm phase valid...') invoice = shcart.create_invoice_from_cart(cart, account, request.user) response = form._process(request, item_from_invoice(invoice)) logger.debug(' paypal_checkout: payment response: %s', response) if not response.flag: invoice.status = Invoice.Const.PAID invoice.save() register_purchase(invoice.id, invoice.customer, invoice.total, invoice.total_credit) request.user.message_set.create(message='Payment processed successfully - thanks!') if success_url: return HttpResponseRedirect(success_url) else: invoice.status = Invoice.Const.CANCELLED #invoice.notes = '%s: %s' % (response.flag_code, response.flag_info) notes = '%s: %s' % (response.flag_code, response.flag_info) invoice.save() request.user.message_set.create(message='Payment processing error - %s' % notes) return HttpResponseRedirect(reverse('invoice-detail', kwargs={'object_id': invoice.id})) else: phase = 'collect' # back up... else: return HttpResponseServerError("Internal error - illegal program state: %s" % phase) context = locals() context.pop('request') logger.debug(' paypal_checkout: exiting with context: %s', context) return render_to_response( template, context, context_instance=RequestContext(request))