def create_invoice_from_cart(cart, account, user): logger.debug('create_invoice_from_cart: entering: cart=%s, account=%s, user=%s', cart, account, user) sig = sha1(repr(datetime.now())).hexdigest() invoice = Invoice(id=sig, customer=account, status=Invoice.Const.NEW) cart_items = get_cart_items(cart) items = [] for item in cart_items: logger.debug('create_invoice_from_cart: adding invoice line: item=%s', item) invoice.add_line(item.product.name, item.product.base_price, item.quantity) items.append(item.product.name) item.delete() invoice.description = " $%3.02f items - %s" % (invoice.total, ', '.join(items)) invoice.save() destroy_cart(cart) return invoice
def checkout(request, success_url=''): """ Display and/or collect payment information while displaying a summary of products to be purchased. 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. """ from models import CartItem # account = request.user.get_profile().account # # we're basically a wrapper around this view func... so lets configure it. view_func = PayPalPro(payment_template="product/checkout.html", confirm_template="paypal/express_confirmation.html", success_url=reverse('dealer-dashboard') ) try: # if there's no NEW invoice, create one from current cart try: invoice = account.invoice_set.get(status=Invoice.Const.NEW) logger.debug('checkout: [%s] found pre-existing new invoice [%s]' % (request.session.session_key, invoice.id)) except Invoice.DoesNotExist: sig = sha1(repr(datetime.now())).hexdigest() invoice = Invoice(id=sig, customer=account, status=Invoice.Const.NEW) invoice.description = "Web Purchase by '%s' on '%s'" % (request.user.email, datetime.now()) cart_items = CartItem.objects.filter(session_key__exact=request.session.session_key) for item in cart_items: invoice.add_line(item.product.name, item.product.base_price, item.quantity) item.delete() # note - we are in transaction context.. save probably has no effect... invoice.save() logger.debug('checkout: [%s] created new invoice [%s]' % (request.session.session_key, invoice.id)) # # if this is a post, we try to process the invoice. if request.method == "POST" or (request.method == "GET" and 'express' in request.GET): # change invoice status to pending invoice.status = Invoice.Const.PENDING # configure the paypal processor with invoice info. view_func.item = { "amt": invoice.total, "invnum": invoice.id, "custom": request.session.session_key, # for debugging "desc": invoice.description, "cancelurl": make_site_url(reverse('select_products')), # Express checkout cancel url "returnurl": make_site_url(reverse('dealer-dashboard')) # Express checkout return url } request.user.message_set.create(message='Thanks for your order!') except Exception as ex: transaction.rollback() errors = "Failed to create new invoice! (%s)" % ex else: transaction.commit() # view_func.context = locals() # logger.debug('checkout: session #%s: payment request for invoice [%s] submitted to paypal with item=%s, context=%s' % ( # request.session.session_key, # invoice, # view_func.item, # view_func.context) # ) return view_func(request)