def charge_remaining_post(request): if not request.method == "POST": return bad_or_missing(request, _("No form found in request.")) data = request.POST.copy() form = CustomChargeForm(data) if form.is_valid(): data = form.cleaned_data try: orderitem = OrderItem.objects.get(pk=data["orderitem"]) except OrderItem.DoesNotExist: return bad_or_missing( request, _( "The orderitem you have requested doesn't exist, or you don't have access to it." ), ) price = data["amount"] line_price = price * orderitem.quantity orderitem.unit_price = price orderitem.line_item_price = line_price orderitem.save() order = orderitem.order if not order.shipping_cost: order.shipping_cost = Decimal("0.00") if data["shipping"]: order.shipping_cost += data["shipping"] order.recalculate_total() messages.add_message( request, messages.INFO, _("Charged for custom product and recalculated totals."), ) notes = data["notes"] if not notes: notes = "Updated total price" order.add_status(notes=notes) return HttpResponseRedirect("/admin/shop/order/%i" % order.id) else: ctx = {"form": form} return render(request, "admin/charge_remaining_confirm.html", ctx)
def charge_remaining_post(request): if not request.method == "POST": return bad_or_missing(request, _("No form found in request.")) data = request.POST.copy() form = CustomChargeForm(data) if form.is_valid(): data = form.cleaned_data try: orderitem = OrderItem.objects.get(pk=data["orderitem"]) except OrderItem.DoesNotExist: return bad_or_missing( request, _("The orderitem you have requested doesn't exist, or you don't have access to it." ), ) price = data["amount"] line_price = price * orderitem.quantity orderitem.unit_price = price orderitem.line_item_price = line_price orderitem.save() order = orderitem.order if not order.shipping_cost: order.shipping_cost = Decimal("0.00") if data["shipping"]: order.shipping_cost += data["shipping"] order.recalculate_total() messages.add_message( request, messages.INFO, _("Charged for custom product and recalculated totals."), ) notes = data["notes"] if not notes: notes = "Updated total price" order.add_status(notes=notes) return HttpResponseRedirect("/admin/shop/order/%i" % order.id) else: ctx = {"form": form} return render(request, "admin/charge_remaining_confirm.html", ctx)
def children(request, slug_parent, slug): #Display the category if it is a child try: parent = Category.objects.filter(slug=slug_parent)[0] except IndexError: return bad_or_missing(request, _('The category you have requested does not exist.')) try: category = parent.child.filter(slug=slug)[0] except IndexError: return bad_or_missing(request, _('The category you have requested does not exist.')) child_categories = category.get_all_children() return render_to_response('base_category.html', {'category': category, 'child_categories': child_categories}, RequestContext(request))
def success(request, template='checkout/success.html'): """ The order has been succesfully processed. This can be used to generate a receipt or some other confirmation """ try: order = Order.objects.from_request(request) except Order.DoesNotExist: return bad_or_missing(request, _('Your order has already been processed.')) # Track total sold for each product for item in order.orderitem_set.all(): if item.stock_updated is False: product = item.product product.total_sold += item.quantity product.items_in_stock -= item.quantity product.save() item.stock_updated = True item.save() log.debug("Set quantities for %s to %s" % (product, product.items_in_stock)) order.freeze() order.save() if 'cart' in request.session: del request.session['cart'] del request.session['orderID'] log.info("Successully processed " % (order)) context = RequestContext(request, {'order': order}) return render_to_response(template, context)
def category_view(request, slug, parent_slugs="", template="base_category.html"): """Display the category, its child categories, and its products. Parameters: - slug: slug of category - parent_slugs: ignored """ try: category = Category.objects.get(slug=slug) products = category.active_products() sale = find_best_auto_discount(products) except Category.DoesNotExist: return bad_or_missing( request, _("The category you have requested does not exist.")) child_categories = category.get_all_children() ctx = { "category": category, "child_categories": child_categories, "sale": sale, "products": products, } index_prerender.send(Product, request=request, context=ctx, category=category, object_list=products) return render(request, template, ctx)
def category_view(request, slug, parent_slugs="", template="base_category.html"): """Display the category, its child categories, and its products. Parameters: - slug: slug of category - parent_slugs: ignored """ try: category = Category.objects.get(slug=slug) products = category.active_products() sale = find_best_auto_discount(products) except Category.DoesNotExist: return bad_or_missing( request, _("The category you have requested does not exist.") ) child_categories = category.get_all_children() ctx = { "category": category, "child_categories": child_categories, "sale": sale, "products": products, } index_prerender.send( Product, request=request, context=ctx, category=category, object_list=products ) return render(request, template, ctx)
def order_tracking(request, order_id): order = None try: contact = Contact.objects.from_request(request, create=False) try: order = Order.objects.get(id__exact=order_id, contact=contact) except Order.DoesNotExist: pass except Contact.DoesNotExist: contact = None if order is None: return bad_or_missing( request, _("The order you have requested doesn't exist, or you don't have access to it." ), ) ctx = { "default_view_tax": config_value("TAX", "DEFAULT_VIEW_TAX"), "contact": contact, "order": order, } return render(request, "shop/order_tracking.html", ctx)
def order_tracking(request, order_id): order = None try: contact = Contact.objects.from_request(request, create=False) try: order = Order.objects.get(id__exact=order_id, contact=contact) except Order.DoesNotExist: pass except Contact.DoesNotExist: contact = None if order is None: return bad_or_missing( request, _("The order you have requested doesn't exist, or you don't have access to it." )) ctx = RequestContext( request, { 'default_view_tax': config_value('TAX', 'DEFAULT_VIEW_TAX'), 'contact': contact, 'order': order }) return render_to_response('shop/order_tracking.html', ctx)
def home(request, template="base_index.html"): # Display the category, its child categories, and its products. if request.method == "GET": currpage = request.GET.get('page', 1) else: currpage = 1 featured = display_featured() count = config_value('SHOP', 'NUM_PAGINATED') paginator = Paginator(featured, count) is_paged = False page = None try: paginator.validate_number(currpage) except EmptyPage: return bad_or_missing(request, _("Invalid page number")) is_paged = paginator.num_pages > 1 page = paginator.page(currpage) ctx = RequestContext( request, { 'all_products_list': page.object_list, 'is_paginated': is_paged, 'page_obj': page, 'paginator': paginator }) return render_to_response(template, ctx)
def category_view(request, slug, parent_slugs='', template='base_category.html'): """Display the category, its child categories, and its products. Parameters: - slug: slug of category - parent_slugs: ignored """ try: category = Category.objects.get(slug=slug) products = category.active_products() sale = find_best_auto_discount(products) except Category.DoesNotExist: return bad_or_missing( request, _('The category you have requested does not exist.')) child_categories = category.get_all_children() ctx = { 'category': category, 'child_categories': child_categories, 'sale': sale, 'products': products, } index_prerender.send(Product, request=request, context=ctx, category=category, object_list=products) return render_to_response(template, RequestContext(request, ctx))
def order_tracking(request, order_id): order = None try: contact = Contact.objects.from_request(request, create=False) try: order = Order.objects.get(id__exact=order_id, contact=contact) except Order.DoesNotExist: pass except Contact.DoesNotExist: contact = None if order is None: return bad_or_missing( request, _( "The order you have requested doesn't exist, or you don't have access to it." ), ) ctx = { "default_view_tax": config_value("TAX", "DEFAULT_VIEW_TAX"), "contact": contact, "order": order, } return render(request, "shop/order_tracking.html", ctx)
def success(request, checkout): """ This view handles the notification coming back from the BankPass Web system. We have both our own cookies, stored in the customer's browser, and BankPass Web's data. First, we have our Engine check that the data is authentic and not corrupted. Then we make some sanity checks to be sure that the order data (amount, ID, currency...) match what we have. If it does not, we bail out. Then we check if the outcome is successful. If it is not, we warn the user. If it is, we record the transaction and use the default success view to notify the user. """ order = checkout.order try: outcome = checkout.processor.parse_answer( request.META['QUERY_STRING']) except BPWCryptoException, e: log.error('Forged or incorrect message from BankPass: ignoring. (%s)' % request.META['QUERY_STRING']) return bad_or_missing(request, _('The message from BankPass ' 'Web appears to be forged. Cannot process payment.'))
def add(request, id=0, redirect_to="satchmo_cart"): """Add an item to the cart.""" log.debug("FORM: %s", request.POST) formdata = request.POST.copy() productslug = None if "productname" in formdata: productslug = formdata["productname"] try: product, details = product_from_post(productslug, formdata) if not (product and product.active): return _product_error( request, product, _("That product is not available at the moment.")) except (Product.DoesNotExist, MultiValueDictKeyError): log.debug("Could not find product: %s", productslug) return bad_or_missing( request, _("The product you have requested does not exist.")) try: quantity = int(formdata["quantity"]) except ValueError: return _product_error(request, product, _("Please enter a whole number.")) if quantity < 1: return _product_error(request, product, _("Please enter a positive number.")) cart = Cart.objects.from_request(request, create=True) # send a signal so that listeners can update product details before we add it to the cart. satchmo_cart_details_query.send( cart, product=product, quantity=quantity, details=details, request=request, form=formdata, ) try: added_item = cart.add_item(product, number_added=quantity, details=details) except CartAddProhibited as cap: return _product_error(request, product, cap.message) # got to here with no error, now send a signal so that listeners can also operate on this form. satchmo_cart_add_complete.send( cart, cart=cart, cartitem=added_item, product=product, request=request, form=formdata, ) satchmo_cart_changed.send(cart, cart=cart, request=request) url = reverse(redirect_to) return HttpResponseRedirect(url)
def category_view(request, slug, parent_slugs='', template='base_category.html'): """Display the category, its child categories, and its products. Parameters: - slug: slug of category - parent_slugs: ignored """ try: category = Category.objects.get(slug=slug) products = category.active_products() sale = find_best_auto_discount(products) except Category.DoesNotExist: return bad_or_missing(request, _('The category you have requested does not exist.')) child_categories = category.get_all_children() ctx = { 'category': category, 'child_categories': child_categories, 'sale': sale, 'products': products, } index_prerender.send(Product, request=request, context=ctx, category=category, object_list=products) return render_to_response(template, RequestContext(request, ctx))
def home(request, template="base_index.html"): # Display the category, its child categories, and its products. if request.method == "GET": currpage = request.GET.get("page", 1) else: currpage = 1 featured = display_featured() count = config_value("SHOP", "NUM_PAGINATED") paginator = Paginator(featured, count) is_paged = False page = None try: paginator.validate_number(currpage) except EmptyPage: return bad_or_missing(request, _("Invalid page number")) is_paged = paginator.num_pages > 1 page = paginator.page(currpage) ctx = { "all_products_list": page.object_list, "is_paginated": is_paged, "page_obj": page, "paginator": paginator, } return render(request, template, ctx)
def success(request, checkout): """ This view handles the notification coming back from the BankPass Web system. We have both our own cookies, stored in the customer's browser, and BankPass Web's data. First, we have our Engine check that the data is authentic and not corrupted. Then we make some sanity checks to be sure that the order data (amount, ID, currency...) match what we have. If it does not, we bail out. Then we check if the outcome is successful. If it is not, we warn the user. If it is, we record the transaction and use the default success view to notify the user. """ order = checkout.order try: outcome = checkout.processor.parse_answer(request.META['QUERY_STRING']) except BPWCryptoException, e: log.error('Forged or incorrect message from BankPass: ignoring. (%s)' % request.META['QUERY_STRING']) return bad_or_missing( request, _('The message from BankPass ' 'Web appears to be forged. Cannot process payment.'))
def charge_remaining_post(request): if not request.method == 'POST': return bad_or_missing(request, _("No form found in request.")) data = request.POST.copy() form = CustomChargeForm(data) if form.is_valid(): data = form.cleaned_data try: orderitem = OrderItem.objects.get(pk=data['orderitem']) except OrderItem.DoesNotExist: return bad_or_missing( request, _("The orderitem you have requested doesn't exist, or you don't have access to it." )) price = data['amount'] line_price = price * orderitem.quantity orderitem.unit_price = price orderitem.line_item_price = line_price orderitem.save() order = orderitem.order if not order.shipping_cost: order.shipping_cost = Decimal("0.00") if data['shipping']: order.shipping_cost += data['shipping'] order.recalculate_total() messages.add_message( request, messages.INFO, _('Charged for custom product and recalculated totals.')) notes = data['notes'] if not notes: notes = 'Updated total price' order.add_status(notes=notes) return HttpResponseRedirect('/admin/shop/order/%i' % order.id) else: ctx = RequestContext(request, {'form': form}) return render_to_response('admin/charge_remaining_confirm.html', ctx)
def get_product(request, category_slug, brand_slug, product_slug, selected_options=(), include_tax=NOTSET, default_view_tax=NOTSET): """Basic product view""" try: product = Product.objects.get_by_site(active=True, slug=product_slug) except Product.DoesNotExist: return bad_or_missing(request, _('The product you have requested does not exist.')) try: category = Category.objects.get(slug=category_slug) except Category.DoesNotExist: category = None brand = Brand.objects.get(slug=brand_slug) if default_view_tax == NOTSET: default_view_tax = config_value('TAX', 'DEFAULT_VIEW_TAX') if default_view_tax: include_tax = True elif include_tax == NOTSET: include_tax = default_view_tax if default_view_tax: include_tax = True subtype_names = product.get_subtypes() if 'ProductVariation' in subtype_names: selected_options = product.productvariation.unique_option_ids # Display the ConfigurableProduct that this ProductVariation belongs to. product = product.productvariation.parent.product subtype_names = product.get_subtypes() best_discount = find_best_auto_discount(product) extra_context = { 'product': product, 'category': category, 'brand': brand, 'default_view_tax': default_view_tax, 'sale': best_discount, } # Get the template context from the Product. extra_context = product.add_template_context( context=extra_context, request=request, selected_options=selected_options, include_tax=include_tax, default_view_tax=default_view_tax ) if include_tax: tax_amt = get_tax(request.user, product, 1) extra_context['product_tax'] = tax_amt extra_context['price_with_tax'] = product.unit_price + tax_amt template = find_product_template(product, producttypes=subtype_names) context = RequestContext(request, extra_context) return http.HttpResponse(template.render(context))
def children(request, slug_parent, slug): #Display the category if it is a child try: parent = Category.objects.filter(slug=slug_parent)[0] except IndexError: return bad_or_missing( request, _('The category you have requested does not exist.')) try: category = parent.child.filter(slug=slug)[0] except IndexError: return bad_or_missing( request, _('The category you have requested does not exist.')) child_categories = category.get_all_children() return render_to_response('base_category.html', { 'category': category, 'child_categories': child_categories }, RequestContext(request))
def add(request, id=0, redirect_to="satchmo_cart"): """Add an item to the cart.""" log.debug("FORM: %s", request.POST) formdata = request.POST.copy() productslug = None if "productname" in formdata: productslug = formdata["productname"] try: product, details = product_from_post(productslug, formdata) if not (product and product.active): return _product_error( request, product, _("That product is not available at the moment.") ) except (Product.DoesNotExist, MultiValueDictKeyError): log.debug("Could not find product: %s", productslug) return bad_or_missing( request, _("The product you have requested does not exist.") ) try: quantity = int(formdata["quantity"]) except ValueError: return _product_error(request, product, _("Please enter a whole number.")) if quantity < 1: return _product_error(request, product, _("Please enter a positive number.")) cart = Cart.objects.from_request(request, create=True) # send a signal so that listeners can update product details before we add it to the cart. satchmo_cart_details_query.send( cart, product=product, quantity=quantity, details=details, request=request, form=formdata, ) try: added_item = cart.add_item(product, number_added=quantity, details=details) except CartAddProhibited as cap: return _product_error(request, product, cap.message) # got to here with no error, now send a signal so that listeners can also operate on this form. satchmo_cart_add_complete.send( cart, cart=cart, cartitem=added_item, product=product, request=request, form=formdata, ) satchmo_cart_changed.send(cart, cart=cart, request=request) url = reverse(redirect_to) return HttpResponseRedirect(url)
def variation_manager(request, product_slug=""): try: product = Product.objects.get(slug=product_slug) subtypes = product.get_subtypes() if "ProductVariation" in subtypes: # got a variation, we want to work with its parent product = product.productvariation.parent.product if "ConfigurableProduct" in product.get_subtypes(): url = reverse( "satchmo_admin_variation_manager", kwargs={"product_slug": product.slug}, ) return HttpResponseRedirect(url) if "ConfigurableProduct" not in subtypes: return bad_or_missing( request, _("The product you have requested is not a Configurable Product."), ) except Product.DoesNotExist: return bad_or_missing( request, _("The product you have requested does not exist.") ) if request.method == "POST": new_data = request.POST.copy() form = VariationManagerForm(new_data, product=product) if form.is_valid(): log.debug("Saving form") form.save(request) # rebuild the form form = VariationManagerForm(product=product) else: log.debug("errors on form") else: form = VariationManagerForm(product=product) context = {"product": product, "form": form} return render( request, "admin/product/configurableproduct/variation_manager.html", context )
def variation_manager(request, product_slug=""): try: product = Product.objects.get(slug=product_slug) subtypes = product.get_subtypes() if "ProductVariation" in subtypes: # got a variation, we want to work with its parent product = product.productvariation.parent.product if "ConfigurableProduct" in product.get_subtypes(): url = reverse( "satchmo_admin_variation_manager", kwargs={"product_slug": product.slug}, ) return HttpResponseRedirect(url) if "ConfigurableProduct" not in subtypes: return bad_or_missing( request, _("The product you have requested is not a Configurable Product." ), ) except Product.DoesNotExist: return bad_or_missing( request, _("The product you have requested does not exist.")) if request.method == "POST": new_data = request.POST.copy() form = VariationManagerForm(new_data, product=product) if form.is_valid(): log.debug("Saving form") form.save(request) # rebuild the form form = VariationManagerForm(product=product) else: log.debug("errors on form") else: form = VariationManagerForm(product=product) context = {"product": product, "form": form} return render(request, "admin/product/configurableproduct/variation_manager.html", context)
def charge_remaining_post(request): if not request.method == 'POST': return bad_or_missing(request, _("No form found in request.")) data = request.POST.copy() form = CustomChargeForm(data) if form.is_valid(): data = form.cleaned_data try: orderitem = OrderItem.objects.get(pk = data['orderitem']) except OrderItem.DoesNotExist: return bad_or_missing(request, _("The orderitem you have requested doesn't exist, or you don't have access to it.")) price = data['amount'] line_price = price*orderitem.quantity orderitem.unit_price = price orderitem.line_item_price = line_price orderitem.save() #print "Orderitem price now: %s" % orderitem.line_item_price order = orderitem.order if not order.shipping_cost: order.shipping_cost = Decimal("0.00") if data['shipping']: order.shipping_cost += data['shipping'] order.recalculate_total() request.user.message_set.create(message='Charged for custom product and recalculated totals.') notes = data['notes'] if not notes: notes = 'Updated total price' order.add_status(notes=notes) return HttpResponseRedirect('/admin/contact/order/%i' % order.id) else: ctx = RequestContext(request, {'form' : form}) return render_to_response('admin/charge_remaining_confirm.html', ctx)
def add(request, id=0): """Add an item to the cart.""" #TODO: Error checking for invalid combos try: product = Product.objects.get(slug=request.POST['productname']) p_types = product.get_subtypes() details = [] if 'ConfigurableProduct' in p_types: # This happens when productname cannot be updated by javascript. cp = product.configurableproduct chosenOptions = optionset_from_post(cp, request.POST) product = cp.get_product_from_options(chosenOptions) if 'CustomProduct' in p_types: for customfield in product.customproduct.custom_text_fields.all(): details.append((customfield, request.POST["custom_%s" % customfield.slug])) template = find_product_template(product) except (Product.DoesNotExist, MultiValueDictKeyError): return bad_or_missing( request, _('The product you have requested does not exist.')) try: quantity = int(request.POST['quantity']) except ValueError: context = RequestContext( request, { 'product': product, 'error_message': _("Please enter a whole number.") }) return HttpResponse(template.render(context)) if quantity < 1: context = RequestContext( request, { 'product': product, 'error_message': _("Please enter a positive number.") }) return HttpResponse(template.render(context)) if request.session.get('cart'): cart = Cart.objects.get(id=request.session['cart']) else: cart = Cart() cart.save() # Give the cart an id cart.add_item(product, number_added=quantity, details=details) request.session['cart'] = cart.id url = urlresolvers.reverse('satchmo_cart') return HttpResponseRedirect(url)
def success(request): """ The order has been succesfully processed. This can be used to generate a receipt or some other confirmation """ try: order = Order.objects.get(id=request.session['orderID']) except KeyError: return bad_or_missing(request, _('Your order has already been processed.')) del request.session['orderID'] context = RequestContext(request, {'order': order}) return render_to_response('checkout/success.html', context)
def root(request, slug): #Display the category page if we're not dealing with a child category try: category = Category.objects.filter(slug=slug)[0] except IndexError: return bad_or_missing(request, _('The category you have requested does not exist.')) child_categories = category.get_all_children() return render_to_response('base_category.html', {'category': category, 'child_categories': child_categories}, RequestContext(request))
def root(request, slug): #Display the category page if we're not dealing with a child category try: category = Category.objects.filter(slug=slug)[0] except IndexError: return bad_or_missing( request, _('The category you have requested does not exist.')) child_categories = category.get_all_children() return render_to_response('base_category.html', { 'category': category, 'child_categories': child_categories }, RequestContext(request))
def variation_manager(request, product_slug = ""): try: product = Product.objects.get(slug=product_slug) subtypes = product.get_subtypes() if 'ProductVariation' in subtypes: # got a variation, we want to work with its parent product = product.productvariation.parent.product if 'ConfigurableProduct' in product.get_subtypes(): url = urlresolvers.reverse("satchmo_admin_variation_manager", kwargs = {'product_slug' : product.slug}) return HttpResponseRedirect(url) if 'ConfigurableProduct' not in subtypes: return bad_or_missing(request, _('The product you have requested is not a Configurable Product.')) except Product.DoesNotExist: return bad_or_missing(request, _('The product you have requested does not exist.')) if request.method == 'POST': new_data = request.POST.copy() form = VariationManagerForm(new_data, product=product) if form.is_valid(): log.debug("Saving form") form.save(request) # rebuild the form form = VariationManagerForm(product=product) else: log.debug('errors on form') else: form = VariationManagerForm(product=product) ctx = RequestContext(request, { 'product' : product, 'form' : form, }) return render_to_response('admin/product/configurableproduct/variation_manager.html', ctx)
def add(request, id=0): """Add an item to the cart.""" #TODO: Error checking for invalid combos try: product = Product.objects.get(slug=request.POST['productname']) p_types = product.get_subtypes() details = [] if 'ConfigurableProduct' in p_types: # This happens when productname cannot be updated by javascript. cp = product.configurableproduct chosenOptions = optionset_from_post(cp, request.POST) product = cp.get_product_from_options(chosenOptions) if 'CustomProduct' in p_types: for customfield in product.customproduct.custom_text_fields.all(): details.append((customfield, request.POST["custom_%s" % customfield.slug])) template = find_product_template(product) except (Product.DoesNotExist, MultiValueDictKeyError): return bad_or_missing(request, _('The product you have requested does not exist.')) try: quantity = int(request.POST['quantity']) except ValueError: context = RequestContext(request, { 'product': product, 'error_message': _("Please enter a whole number.")}) return HttpResponse(template.render(context)) if quantity < 1: context = RequestContext(request, { 'product': product, 'error_message': _("Please enter a positive number.")}) return HttpResponse(template.render(context)) if request.session.get('cart'): cart = Cart.objects.get(id=request.session['cart']) else: cart = Cart() cart.save() # Give the cart an id cart.add_item(product, number_added=quantity, details=details) request.session['cart'] = cart.id url = urlresolvers.reverse('satchmo_cart') return HttpResponseRedirect(url)
def variation_manager(request, product_slug=""): try: product = Product.objects.get(slug=product_slug) subtypes = product.get_subtypes() if 'ProductVariation' in subtypes: # got a variation, we want to work with its parent product = product.productvariation.parent.product if 'ConfigurableProduct' in product.get_subtypes(): url = urlresolvers.reverse("satchmo_admin_variation_manager", kwargs={'product_slug': product.slug}) return HttpResponseRedirect(url) if 'ConfigurableProduct' not in subtypes: return bad_or_missing(request, _('The product you have requested is not a Configurable Product.')) except Product.DoesNotExist: return bad_or_missing(request, _('The product you have requested does not exist.')) if request.method == 'POST': new_data = request.POST.copy() form = VariationManagerForm(new_data, product=product) if form.is_valid(): log.debug("Saving form") form.save(request) # rebuild the form form = VariationManagerForm(product=product) else: log.debug('errors on form') else: form = VariationManagerForm(product=product) context = RequestContext(request, { 'product': product, 'form': form, }) return render_to_response('admin/product/configurableproduct/variation_manager.html', context)
def charge_remaining(request, orderitem_id): """Given an orderitem_id, this returns a confirmation form.""" try: orderitem = OrderItem.objects.get(pk = orderitem_id) except OrderItem.DoesNotExist: return bad_or_missing(request, _("The orderitem you have requested doesn't exist, or you don't have access to it.")) amount = orderitem.product.customproduct.full_price data = { 'orderitem' : orderitem_id, 'amount' : amount, } form = CustomChargeForm(data) ctx = RequestContext(request, {'form' : form}) return render_to_response('admin/charge_remaining_confirm.html', ctx)
def order_tracking(request, order_id): order = None contact = Contact.from_request(request, create=False) if contact is not None: try: order = Order.objects.get(id__exact=order_id, contact=contact) except Order.DoesNotExist: pass if order is None: return bad_or_missing(request, _("The order you have requested doesn't exist, or you don't have access to it.")) ctx = RequestContext(request, { 'contact' : contact, 'order' : order}) return render_to_response('contact/order_tracking.html', ctx)
def add(request, id=0, redirect_to='satchmo_cart'): """Add an item to the cart.""" log.debug('FORM: %s', request.POST) formdata = request.POST.copy() productslug = None if 'productname' in formdata: productslug = formdata['productname'] try: product, details = product_from_post(productslug, formdata) if not (product and product.active): return _product_error( request, product, _("That product is not available at the moment.")) except (Product.DoesNotExist, MultiValueDictKeyError): log.debug("Could not find product: %s", productslug) return bad_or_missing( request, _('The product you have requested does not exist.')) try: quantity = int(formdata['quantity']) except ValueError: return _product_error(request, product, _("Please enter a whole number.")) if quantity < 1: return _product_error(request, product, _("Please enter a positive number.")) cart = Cart.objects.from_request(request, create=True) # send a signal so that listeners can update product details before we add it to the cart. satchmo_cart_details_query.send(cart, product=product, quantity=quantity, details=details, request=request, form=formdata) try: added_item = cart.add_item(product, number_added=quantity, details=details) except CartAddProhibited, cap: return _product_error(request, product, cap.message)
def charge_remaining(request, orderitem_id): """Given an orderitem_id, this returns a confirmation form.""" try: orderitem = OrderItem.objects.get(pk=orderitem_id) except OrderItem.DoesNotExist: return bad_or_missing( request, _("The orderitem you have requested doesn't exist, or you don't have access to it." ), ) amount = orderitem.product.customproduct.full_price data = {"orderitem": orderitem_id, "amount": amount} form = CustomChargeForm(data) ctx = {"form": form} return render(request, "admin/charge_remaining_confirm.html", ctx)
def charge_remaining(request, orderitem_id): """Given an orderitem_id, this returns a confirmation form.""" try: orderitem = OrderItem.objects.get(pk=orderitem_id) except OrderItem.DoesNotExist: return bad_or_missing( request, _( "The orderitem you have requested doesn't exist, or you don't have access to it." ), ) amount = orderitem.product.customproduct.full_price data = {"orderitem": orderitem_id, "amount": amount} form = CustomChargeForm(data) ctx = {"form": form} return render(request, "admin/charge_remaining_confirm.html", ctx)
def success(request): """ The order has been succesfully processed. This can be used to generate a receipt or some other confirmation """ try: order = Order.objects.from_request(request) except Order.DoesNotExist: return bad_or_missing(request, _('Your order has already been processed.')) # Added to track total sold for each product for item in order.orderitem_set.all(): product = item.product product.total_sold += item.quantity product.items_in_stock -= item.quantity product.save() del request.session['orderID'] context = RequestContext(request, {'order': order}) return render_to_response('checkout/success.html', context)
def add(request, id=0, redirect_to='satchmo_cart'): """Add an item to the cart.""" log.debug('FORM: %s', request.POST) formdata = request.POST.copy() productslug = None if formdata.has_key('productname'): productslug = formdata['productname'] try: product, details = product_from_post(productslug, formdata) if not (product and product.active): return _product_error(request, product, _("That product is not available at the moment.")) except (Product.DoesNotExist, MultiValueDictKeyError): log.debug("Could not find product: %s", productslug) return bad_or_missing(request, _('The product you have requested does not exist.')) try: quantity = int(formdata['quantity']) except ValueError: return _product_error(request, product, _("Please enter a whole number.")) if quantity < 1: return _product_error(request, product, _("Please enter a positive number.")) cart = Cart.objects.from_request(request, create=True) # send a signal so that listeners can update product details before we add it to the cart. satchmo_cart_details_query.send( cart, product=product, quantity=quantity, details=details, request=request, form=formdata ) try: added_item = cart.add_item(product, number_added=quantity, details=details) except CartAddProhibited, cap: return _product_error(request, product, cap.message)
def charge_remaining(request, orderitem_id): """Given an orderitem_id, this returns a confirmation form.""" try: orderitem = OrderItem.objects.get(pk=orderitem_id) except OrderItem.DoesNotExist: return bad_or_missing( request, _("The orderitem you have requested doesn't exist, or you don't have access to it." )) amount = orderitem.product.customproduct.full_price data = { 'orderitem': orderitem_id, 'amount': amount, } form = CustomChargeForm(data) ctx = RequestContext(request, {'form': form}) return render_to_response('admin/charge_remaining_confirm.html', ctx)
def order_tracking(request, order_id): order = None try: contact = Contact.objects.from_request(request, create=False) try: order = Order.objects.get(id__exact=order_id, contact=contact) except Order.DoesNotExist: pass except Contact.DoesNotExist: contact = None if order is None: return bad_or_missing(request, _("The order you have requested doesn't exist, or you don't have access to it.")) ctx = RequestContext(request, { 'default_view_tax': config_value('TAX', 'DEFAULT_VIEW_TAX'), 'contact' : contact, 'order' : order}) return render_to_response('shop/order_tracking.html', ctx)
def wishlist_add(request): """Add an item to the wishlist.""" try: contact = Contact.objects.from_request(request) except Contact.DoesNotExist: return _wishlist_requires_login(request) log.debug('FORM: %s', request.POST) formdata = request.POST.copy() productslug = None if 'productname' in formdata: productslug = formdata['productname'] try: product, details = product_from_post(productslug, formdata) except (Product.DoesNotExist, MultiValueDictKeyError): log.debug("Could not find product: %s", productslug) return bad_or_missing(request, _('The product you have requested does not exist.')) ProductWish.objects.create_if_new(product, contact, details) url = urlresolvers.reverse('satchmo_wishlist_view') return HttpResponseRedirect(url)
def get_product(request, product_slug, selected_options=Set()): try: product = Product.objects.get(active=True, slug=product_slug) except Product.DoesNotExist: return bad_or_missing(request, _("The product you have requested does not exist.")) p_types = product.get_subtypes() options = [] if "ProductVariation" in p_types: selected_options = product.productvariation.option_values # Display the ConfigurableProduct that this ProductVariation belongs to. product = product.productvariation.parent.product p_types = product.get_subtypes() if "ConfigurableProduct" in p_types: options = serialize_options(product.configurableproduct, selected_options) template = find_product_template(product, producttypes=p_types) ctx = RequestContext(request, {"product": product, "options": options}) return http.HttpResponse(template.render(ctx))
def wishlist_add(request): """Add an item to the wishlist.""" try: contact = Contact.objects.from_request(request) except Contact.DoesNotExist: return _wishlist_requires_login(request) log.debug('FORM: %s', request.POST) formdata = request.POST.copy() productslug = None if 'productname' in formdata: productslug = formdata['productname'] try: product, details = product_from_post(productslug, formdata) except (Product.DoesNotExist, MultiValueDictKeyError): log.debug("Could not find product: %s", productslug) return bad_or_missing( request, _('The product you have requested does not exist.')) ProductWish.objects.create_if_new(product, contact, details) url = urlresolvers.reverse('satchmo_wishlist_view') return HttpResponseRedirect(url)
def get_product(request, product_slug, selected_options=Set()): try: product = Product.objects.get(active=True, slug=product_slug) except Product.DoesNotExist: return bad_or_missing( request, _('The product you have requested does not exist.')) p_types = product.get_subtypes() options = [] if 'ProductVariation' in p_types: selected_options = product.productvariation.option_values #Display the ConfigurableProduct that this ProductVariation belongs to. product = product.productvariation.parent.product p_types = product.get_subtypes() if 'ConfigurableProduct' in p_types: options = serialize_options(product.configurableproduct, selected_options) template = find_product_template(product, producttypes=p_types) ctx = RequestContext(request, {'product': product, 'options': options}) return http.HttpResponse(template.render(ctx))
def get_product( request, category_slug, brand_slug, product_slug, selected_options=(), include_tax=NOTSET, default_view_tax=NOTSET, ): """Basic product view""" try: product = Product.objects.active().get(slug=product_slug) except Product.DoesNotExist: return bad_or_missing( request, _("The product you have requested does not exist.")) try: category = Category.objects.get(slug=category_slug) except Category.DoesNotExist: category = None brand = Brand.objects.get(slug=brand_slug) if default_view_tax == NOTSET: default_view_tax = config_value("TAX", "DEFAULT_VIEW_TAX") if default_view_tax: include_tax = True elif include_tax == NOTSET: include_tax = default_view_tax if default_view_tax: include_tax = True subtype_names = product.get_subtypes() if "ProductVariation" in subtype_names: selected_options = product.productvariation.unique_option_ids # Display the ConfigurableProduct that this ProductVariation belongs to. product = product.productvariation.parent.product subtype_names = product.get_subtypes() best_discount = find_best_auto_discount(product) context = { "product": product, "category": category, "brand": brand, "default_view_tax": default_view_tax, "sale": best_discount, } # Get the template context from the Product. context = product.add_template_context( context=context, request=request, selected_options=selected_options, include_tax=include_tax, default_view_tax=default_view_tax, ) if include_tax: tax_amt = get_tax(request.user, product, 1) context["product_tax"] = tax_amt context["price_with_tax"] = product.unit_price + tax_amt price = context["price_with_tax"] else: price = product.unit_price context["all_prices"] = [{ "currency": currency.iso_4217_code, "price": convert_to_currency(price, currency.iso_4217_code), } for currency in Currency.objects.filter(accepted=True)] template = find_product_template(product, producttypes=subtype_names) return TemplateResponse(request, template, context)
def cron_rebill(request=None): """Rebill customers with expiring recurring subscription products This can either be run via a url with GET key authentication or directly from a shell script. """ #TODO: support re-try billing for failed transactions if request is not None: if not config_value('PAYMENT', 'ALLOW_URL_REBILL'): return bad_or_missing(request, _("Feature is not enabled.")) if 'key' not in request.GET or request.GET['key'] != config_value('PAYMENT','CRON_KEY'): return HttpResponse("Authentication Key Required") expiring_subscriptions = OrderItem.objects.filter(expire_date__gte=datetime.now()).order_by('order', 'id', 'expire_date') for item in expiring_subscriptions: if item.product.is_subscription:#TODO - need to add support for products with trial but non-recurring if item.product.subscriptionproduct.recurring_times and item.product.subscriptionproduct.recurring_times + item.product.subscriptionproduct.get_trial_terms().count() == OrderItem.objects.filter(order=item.order, product=item.product).count(): continue if item.expire_date == datetime.date(datetime.now()) and item.completed: if item.id == OrderItem.objects.filter(product=item.product, order=item.order).order_by('-id')[0].id: #bill => add orderitem, recalculate total, porocess card new_order_item = OrderItem(order=item.order, product=item.product, quantity=item.quantity, unit_price=item.unit_price, line_item_price=item.line_item_price) #if product is recurring, set subscription end if item.product.subscriptionproduct.recurring: new_order_item.expire_date = item.product.subscriptionproduct.calc_expire_date() #check if product has 2 or more trial periods and if the last one paid was a trial or a regular payment. ordercount = item.order.orderitem_set.all().count() if item.product.subscriptionproduct.get_trial_terms().count() > 1 and item.unit_price == item.product.subscriptionproduct.get_trial_terms(ordercount - 1).price: new_order_item.unit_price = item.product.subscriptionproduct.get_trial.terms(ordercount).price new_order_item.line_item_price = new_order_item.quantity * new_order_item.unit_price new_order_item.expire_date = item.product.subscriptionproduct.get_trial_terms(ordercount).calc_expire_date() new_order_item.save() item.order.recalculate_total() # if new_order_item.product.subscriptionproduct.is_shippable == 3: # item.order.total = item.order.total - item.order.shipping_cost # item.order.save() payments = item.order.payments.all()[0] #list of ipn based payment modules. Include processors that use 3rd party recurring billing. ipn_based = ['PAYPAL'] if not payments.payment in ipn_based and item.order.balance > 0: #run card #Do the credit card processing here & if successful, execute the success_handler from satchmo.configuration import config_get_group payment_module = config_get_group('PAYMENT_%s' % payments.payment) credit_processor = payment_module.MODULE.load_module('processor') processor = credit_processor.PaymentProcessor(payment_module) processor.prepareData(item.order) results, reason_code, msg = processor.process() log.info("""Processing %s recurring transaction with %s Order #%i Results=%s Response=%s Reason=%s""", payment_module.LABEL.value, payment_module.KEY.value, item.order.id, results, reason_code, msg) if results: #success handler item.order.add_status(status='Pending', notes = "Subscription Renewal Order successfully submitted") new_order_item.completed = True new_order_item.save() orderpayment = OrderPayment(order=item.order, amount=item.order.balance, payment=unicode(payment_module.KEY.value)) orderpayment.save() return HttpResponse()
notes = order.notes + '\n' else: notes = '' notes += '%s\n' % datetime.now() notes += outcome.summary order.notes = notes order.save() # Make sure that we were successful and perform sanity checks key = unicode(checkout.payment_module.KEY.value) pending_payments = order.payments.filter( transaction_id__exact="PENDING", payment__exact=key) try: pending_amount = pending_payments[0].amount except IndexError: return bad_or_missing(request, u'The payment was not pending') try: assert isinstance(outcome.outcome, Success), \ _('The transaction was not successful') assert outcome.order_id == checkout.processor.id_prefix(order), \ _('The order ID does not match what we sent') assert outcome.amount.as_decimal == pending_amount, _( 'The amount that was paid does not ' 'match what we ordered. (Asked for %s, got %s)' ) % ( pending_amount, outcome.amount.as_decimal) assert outcome.auth_id, _('The authorization ID for this ' 'transaction is missing') assert outcome.trans_id, _('The transaction ID is missing') except AssertionError, a: return bad_or_missing(request, unicode(a))
def get_product( request, category_slug, brand_slug, product_slug, selected_options=(), include_tax=NOTSET, default_view_tax=NOTSET, ): """Basic product view""" try: product = Product.objects.get_by_site(active=True, slug=product_slug) except Product.DoesNotExist: return bad_or_missing( request, _("The product you have requested does not exist.") ) try: category = Category.objects.get(slug=category_slug) except Category.DoesNotExist: category = None brand = Brand.objects.get(slug=brand_slug) if default_view_tax == NOTSET: default_view_tax = config_value("TAX", "DEFAULT_VIEW_TAX") if default_view_tax: include_tax = True elif include_tax == NOTSET: include_tax = default_view_tax if default_view_tax: include_tax = True subtype_names = product.get_subtypes() if "ProductVariation" in subtype_names: selected_options = product.productvariation.unique_option_ids # Display the ConfigurableProduct that this ProductVariation belongs to. product = product.productvariation.parent.product subtype_names = product.get_subtypes() best_discount = find_best_auto_discount(product) context = { "product": product, "category": category, "brand": brand, "default_view_tax": default_view_tax, "sale": best_discount, } # Get the template context from the Product. context = product.add_template_context( context=context, request=request, selected_options=selected_options, include_tax=include_tax, default_view_tax=default_view_tax, ) if include_tax: tax_amt = get_tax(request.user, product, 1) context["product_tax"] = tax_amt context["price_with_tax"] = product.unit_price + tax_amt price = context["price_with_tax"] else: price = product.unit_price context["all_prices"] = [ { "currency": currency.iso_4217_code, "price": convert_to_currency(price, currency.iso_4217_code), } for currency in Currency.objects.filter(accepted=True) ] template = find_product_template(product, producttypes=subtype_names) return TemplateResponse(request, template, context)
def get_product(request, category_slug, brand_slug, product_slug, selected_options=(), include_tax=NOTSET, default_view_tax=NOTSET): """Basic product view""" try: product = Product.objects.get_by_site(active=True, slug=product_slug) except Product.DoesNotExist: return bad_or_missing( request, _('The product you have requested does not exist.')) try: category = Category.objects.get(slug=category_slug) except Category.DoesNotExist: category = None brand = Brand.objects.get(slug=brand_slug) if default_view_tax == NOTSET: default_view_tax = config_value('TAX', 'DEFAULT_VIEW_TAX') if default_view_tax: include_tax = True elif include_tax == NOTSET: include_tax = default_view_tax if default_view_tax: include_tax = True subtype_names = product.get_subtypes() if 'ProductVariation' in subtype_names: selected_options = product.productvariation.unique_option_ids # Display the ConfigurableProduct that this ProductVariation belongs to. product = product.productvariation.parent.product subtype_names = product.get_subtypes() best_discount = find_best_auto_discount(product) extra_context = { 'product': product, 'category': category, 'brand': brand, 'default_view_tax': default_view_tax, 'sale': best_discount, } # Get the template context from the Product. extra_context = product.add_template_context( context=extra_context, request=request, selected_options=selected_options, include_tax=include_tax, default_view_tax=default_view_tax) if include_tax: tax_amt = get_tax(request.user, product, 1) extra_context['product_tax'] = tax_amt extra_context['price_with_tax'] = product.unit_price + tax_amt template = find_product_template(product, producttypes=subtype_names) context = RequestContext(request, extra_context) return http.HttpResponse(template.render(context))
def cron_rebill(request=None): """Rebill customers with expiring recurring subscription products This can either be run via a url with GET key authentication or directly from a shell script. """ #TODO: support re-try billing for failed transactions if request is not None: if not config_value('PAYMENT', 'ALLOW_URL_REBILL'): return bad_or_missing(request, _("Feature is not enabled.")) if 'key' not in request.GET or request.GET['key'] != config_value( 'PAYMENT', 'CRON_KEY'): return HttpResponse("Authentication Key Required") expiring_subscriptions = OrderItem.objects.filter( expire_date__gte=datetime.now()).order_by('order', 'id', 'expire_date') for item in expiring_subscriptions: if item.product.is_subscription: #TODO - need to add support for products with trial but non-recurring if item.product.subscriptionproduct.recurring_times and item.product.subscriptionproduct.recurring_times + item.product.subscriptionproduct.get_trial_terms( ).count() == OrderItem.objects.filter( order=item.order, product=item.product).count(): continue if item.expire_date == datetime.date( datetime.now()) and item.completed: if item.id == OrderItem.objects.filter( product=item.product, order=item.order).order_by('-id')[0].id: #bill => add orderitem, recalculate total, porocess card new_order_item = OrderItem( order=item.order, product=item.product, quantity=item.quantity, unit_price=item.unit_price, line_item_price=item.line_item_price) #if product is recurring, set subscription end if item.product.subscriptionproduct.recurring: new_order_item.expire_date = item.product.subscriptionproduct.calc_expire_date( ) #check if product has 2 or more trial periods and if the last one paid was a trial or a regular payment. ordercount = item.order.orderitem_set.all().count() if item.product.subscriptionproduct.get_trial_terms( ).count( ) > 1 and item.unit_price == item.product.subscriptionproduct.get_trial_terms( ordercount - 1).price: new_order_item.unit_price = item.product.subscriptionproduct.get_trial.terms( ordercount).price new_order_item.line_item_price = new_order_item.quantity * new_order_item.unit_price new_order_item.expire_date = item.product.subscriptionproduct.get_trial_terms( ordercount).calc_expire_date() new_order_item.save() item.order.recalculate_total() # if new_order_item.product.subscriptionproduct.is_shippable == 3: # item.order.total = item.order.total - item.order.shipping_cost # item.order.save() payments = item.order.payments.all()[0] #list of ipn based payment modules. Include processors that use 3rd party recurring billing. ipn_based = ['PAYPAL'] if not payments.payment in ipn_based and item.order.balance > 0: #run card #Do the credit card processing here & if successful, execute the success_handler from satchmo.configuration import config_get_group payment_module = config_get_group('PAYMENT_%s' % payments.payment) credit_processor = payment_module.MODULE.load_module( 'processor') processor = credit_processor.PaymentProcessor( payment_module) processor.prepareData(item.order) results, reason_code, msg = processor.process() log.info( """Processing %s recurring transaction with %s Order #%i Results=%s Response=%s Reason=%s""", payment_module.LABEL.value, payment_module.KEY.value, item.order.id, results, reason_code, msg) if results: #success handler item.order.add_status( status='Pending', notes= "Subscription Renewal Order successfully submitted" ) new_order_item.completed = True new_order_item.save() orderpayment = OrderPayment( order=item.order, amount=item.order.balance, payment=unicode(payment_module.KEY.value)) orderpayment.save() return HttpResponse()
notes = order.notes + '\n' else: notes = '' notes += '%s\n' % datetime.now() notes += outcome.summary order.notes = notes order.save() # Make sure that we were successful and perform sanity checks key = unicode(checkout.payment_module.KEY.value) pending_payments = order.payments.filter(transaction_id__exact="PENDING", payment__exact=key) try: pending_amount = pending_payments[0].amount except IndexError: return bad_or_missing(request, u'The payment was not pending') try: assert isinstance(outcome.outcome, Success), \ _('The transaction was not successful') assert outcome.order_id == checkout.processor.id_prefix(order), \ _('The order ID does not match what we sent') assert outcome.amount.as_decimal == pending_amount, _( 'The amount that was paid does not ' 'match what we ordered. (Asked for %s, got %s)') % ( pending_amount, outcome.amount.as_decimal) assert outcome.auth_id, _('The authorization ID for this ' 'transaction is missing') assert outcome.trans_id, _('The transaction ID is missing') except AssertionError, a: return bad_or_missing(request, unicode(a))