import string import random from django.contrib.auth.forms import AuthenticationForm from django.utils.translation import ugettext_lazy as _ from django.core.exceptions import ObjectDoesNotExist from django import forms from django.db.models import get_model from django.contrib.auth import forms as auth_forms from django.conf import settings from django.core import validators from django.core.exceptions import ValidationError from django.contrib.sites.models import get_current_site from django.contrib.auth.tokens import default_token_generator from istore.core.loading import get_profile_class, get_class from istore.core.compat import get_user_model from istore.apps.customer.utils import get_password_reset_url Dispatcher = get_class('customer.utils', 'Dispatcher') CommunicationEventType = get_model('customer', 'communicationeventtype') ProductAlert = get_model('customer', 'ProductAlert') User = get_user_model() def generate_username(): uname = ''.join([random.choice(string.letters + string.digits + '_') for i in range(30)]) try: User.objects.get(username=uname) return generate_username() except User.DoesNotExist: return uname
import logging from optparse import make_option from django.core.management.base import BaseCommand, CommandError from istore.core.loading import get_class CatalogueImporter = get_class("partner.utils", "CatalogueImporter") CatalogueImportError = get_class("partner.exceptions", "CatalogueImportError") class Command(BaseCommand): args = "/path/to/file1.csv /path/to/file2.csv ..." help = "For creating product catalogues based on a CSV file" option_list = BaseCommand.option_list + ( make_option("--flush", action="store_true", dest="flush", default=False, help="Flush tables before importing"), make_option("--delimiter", dest="delimiter", default=",", help="Delimiter used within CSV file(s)"), ) def handle(self, *args, **options): logger = self._get_logger() if not args: raise CommandError("Please select a CSV file to import") logger.info("Starting catalogue import") importer = CatalogueImporter(logger, delimiter=options.get("delimiter"), flush=options.get("flush")) for file_path in args: logger.info(" - Importing records from '%s'" % file_path) try: importer.handle(file_path)
import datetime from django.contrib import messages from django.core.urlresolvers import reverse from django.db.models.loading import get_model from django.http import HttpResponseRedirect from django.utils.translation import ugettext_lazy as _ from django.views.generic import (ListView, FormView, DetailView, DeleteView) from istore.core.loading import get_class VoucherForm = get_class('dashboard.vouchers.forms', 'VoucherForm') VoucherSearchForm = get_class('dashboard.vouchers.forms', 'VoucherSearchForm') Voucher = get_model('voucher', 'Voucher') ConditionalOffer = get_model('offer', 'ConditionalOffer') Benefit = get_model('offer', 'Benefit') Condition = get_model('offer', 'Condition') OrderDiscount = get_model('order', 'OrderDiscount') class VoucherListView(ListView): model = Voucher context_object_name = 'vouchers' template_name = 'dashboard/vouchers/voucher_list.html' form_class = VoucherSearchForm description_template = _("%(main_filter)s %(name_filter)s %(code_filter)s") def get_queryset(self): qs = self.model.objects.all().order_by('-date_created') self.description_ctx = {'main_filter': _('All vouchers'), 'name_filter': '',
from urllib.parse import urlparse from django import template from django.db.models import get_model from django.utils.translation import ugettext_lazy as _ from django.core.urlresolvers import resolve, Resolver404 from istore.core.loading import get_class Product = get_model('catalogue', 'Product') Site = get_model('sites', 'Site') get_recently_viewed_product_ids = get_class( 'customer.history_helpers', 'get_recently_viewed_product_ids') register = template.Library() @register.inclusion_tag('customer/history/recently_viewed_products.html', takes_context=True) def recently_viewed_products(context): """ Inclusion tag listing the most recently viewed products """ request = context['request'] product_ids = get_recently_viewed_product_ids(request) current_product = context.get('product', None) if current_product and current_product.id in product_ids: product_ids.remove(current_product.id) # Reordering as the id order gets messed up in the query
from itertools import chain from datetime import datetime, date from django.conf import settings from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.core.validators import RegexValidator from django.db import models from django.db.models import Sum, Count, get_model from django.utils.translation import ugettext_lazy as _ from treebeard.mp_tree import MP_Node from istore.core.utils import slugify from istore.core.loading import get_class BrowsableProductManager = get_class( 'catalogue.managers', 'BrowsableProductManager') class AbstractProductClass(models.Model): """ Used for defining options and attributes for a subset of products. E.g. Books, DVDs and Toys. A product can only belong to one product class. At least one product class must be created when setting up a new Oscar deployment. Not necessarily equivalent to top-level categories but usually will be. """ name = models.CharField(_('Name'), max_length=128) slug = models.SlugField(_('Slug'), max_length=128, unique=True) #: Some product type don't require shipping (eg digital products) - we use
from django.dispatch import receiver from django.db import IntegrityError import logging from istore.core.loading import get_class, get_classes UserSearch, UserRecord, ProductRecord, UserProductView = get_classes( 'analytics.models', ['UserSearch', 'UserRecord', 'ProductRecord', 'UserProductView']) product_viewed, product_search = get_classes('catalogue.signals', ['product_viewed', 'product_search']) basket_addition = get_class('basket.signals', 'basket_addition') order_placed = get_class('order.signals', 'order_placed') # Helpers logger = logging.getLogger('istore.analytics') def _record_product_view(product): try: record, __ = ProductRecord.objects.get_or_create(product=product) record.num_views += 1 record.save() except IntegrityError: # get_or_create sometimes fails due to MySQL's weird transactions, fail # silently logger.error("IntegrityError on ProductRecord.objects." "get_or_create(product=product)")
from istore.apps.dashboard.reports.csv_utils import CsvUnicodeWriter # from istore.apps.payment.exceptions import PaymentError from istore.apps.order.exceptions import InvalidShippingEvent, InvalidStatus # add exception from not existing payment application class PaymentError(Exception): pass Order = get_model('order', 'Order') OrderNote = get_model('order', 'OrderNote') ShippingAddress = get_model('order', 'ShippingAddress') Line = get_model('order', 'Line') ShippingEventType = get_model('order', 'ShippingEventType') PaymentEventType = get_model('order', 'PaymentEventType') EventHandler = get_class('order.processing', 'EventHandler') class OrderStatsView(FormView): template_name = 'dashboard/orders/statistics.html' form_class = forms.OrderStatsForm def get(self, request, *args, **kwargs): return self.post(request, *args, **kwargs) def form_valid(self, form): ctx = self.get_context_data(form=form, filters=form.get_filters()) return self.render_to_response(ctx) def get_form_kwargs(self):
from django import forms from django.utils.translation import ugettext_lazy as _ from istore.core.loading import get_class GeneratorRepository = get_class("dashboard.reports.utils", "GeneratorRepository") class ReportForm(forms.Form): generators = GeneratorRepository().get_report_generators() type_choices = [] for generator in generators: type_choices.append((generator.code, generator.description)) report_type = forms.ChoiceField( widget=forms.Select(), choices=type_choices, label=_("Report Type"), help_text=_("Only the offer and order reports " "use the selected date range"), ) date_from = forms.DateField(label=_("Date from")) date_to = forms.DateField(label=_("Date to"), help_text=_("The report is inclusive of this date")) download = forms.BooleanField(label=_("Download"), required=False) def clean(self): if ( "date_from" in self.cleaned_data and "date_to" in self.cleaned_data and self.cleaned_data["date_from"] > self.cleaned_data["date_to"] ):
from istore.core.loading import get_class, get_classes OrderReportGenerator = get_class("order.reports", "OrderReportGenerator") ProductReportGenerator, UserReportGenerator = get_classes( "analytics.reports", ["ProductReportGenerator", "UserReportGenerator"] ) OpenBasketReportGenerator, SubmittedBasketReportGenerator = get_classes( "basket.reports", ["OpenBasketReportGenerator", "SubmittedBasketReportGenerator"] ) OfferReportGenerator = get_class("offer.reports", "OfferReportGenerator") VoucherReportGenerator = get_class("voucher.reports", "VoucherReportGenerator") class GeneratorRepository(object): generators = [ OrderReportGenerator, ProductReportGenerator, UserReportGenerator, OpenBasketReportGenerator, SubmittedBasketReportGenerator, VoucherReportGenerator, OfferReportGenerator, ] def get_report_generators(self): return self.generators def get_generator(self, code): for generator in self.generators: if generator.code == code:
from istore.core.loading import get_class Repository = get_class('shipping.repository', 'Repository') class CheckoutSessionData(object): """ Class responsible for marshalling all the checkout session data """ SESSION_KEY = 'checkout_data' def __init__(self, request): self.request = request if self.SESSION_KEY not in self.request.session: self.request.session[self.SESSION_KEY] = {} def _check_namespace(self, namespace): if namespace not in self.request.session[self.SESSION_KEY]: self.request.session[self.SESSION_KEY][namespace] = {} def _get(self, namespace, key, default=None): """ Return session value or None """ self._check_namespace(namespace) if key in self.request.session[self.SESSION_KEY][namespace]: return self.request.session[self.SESSION_KEY][namespace][key] return default def _set(self, namespace, key, value): """
import json from django.dispatch import receiver from django.conf import settings from istore.core.loading import get_class product_viewed = get_class('catalogue.signals', 'product_viewed') MAX_PRODUCTS = settings.ISTORE_RECENTLY_VIEWED_PRODUCTS # Helpers def get_recently_viewed_product_ids(request): """ Returns IDs of the last products browsed by the user Limited to the max number defined in settings.py under ISTORE_RECENTLY_VIEWED_PRODUCTS. """ product_ids = [] if (request.COOKIES.has_key('istore_recently_viewed_products')): try: product_ids = _get_list_from_json_string(request.COOKIES['istore_recently_viewed_products']) except ValueError: # This can occur if something messes up the cookie pass return product_ids def _update_recently_viewed_products(product, request, response): """
from django import template from django.db.models import get_model from istore.core.loading import get_class AddToBasketForm = get_class('basket.forms', 'AddToBasketForm') SimpleAddToBasketForm = get_class('basket.forms', 'SimpleAddToBasketForm') Product = get_model('catalogue', 'product') register = template.Library() QNT_SINGLE, QNT_MULTIPLE = 'single', 'multiple' @register.tag(name="basket_form") def do_basket_form(parse, token): """ Template tag for adding the add-to-basket form to the template context so it can be rendered. """ tokens = token.split_contents() if len(tokens) < 4 or tokens[3] != 'as': raise template.TemplateSyntaxError( "%r tag uses the following syntax: " "{%% basket_form request product_var as " "form_var %%}" % tokens[0]) request_var, product_var, form_var = tokens[1], tokens[2], tokens[4] quantity_type = tokens[5] if len(tokens) == 6 else QNT_MULTIPLE if quantity_type not in (QNT_SINGLE, QNT_MULTIPLE):
from django import template from istore.core.loading import get_class Order = get_class('order.models', 'Order') get_nodes = get_class('dashboard.nav', 'get_nodes') register = template.Library() def get_num_user_orders(parser, token): try: tag_name, user = token.split_contents() return NumUserOrdersNode(user) except IndexError: raise template.TemplateSyntaxError( "%r tag requires a user as it's first argument" % tag_name) class NumUserOrdersNode(template.Node): def __init__(self, user): self.user = template.Variable(user) def render(self, context): return Order.objects.filter(user=self.user.resolve(context)).count() register.tag('num_orders', get_num_user_orders) def dashboard_navigation(parser, token): return DashboardNavigationNode()
CreateView, UpdateView, DeleteView, FormView, RedirectView) from django.core.urlresolvers import reverse from django.core.exceptions import ObjectDoesNotExist from django.http import HttpResponseRedirect, Http404 from django.contrib import messages from django.utils.translation import ugettext as _ from django.contrib.auth import (authenticate, login as auth_login, logout as auth_logout) from django.contrib.auth.forms import PasswordChangeForm from django.contrib.sites.models import get_current_site from django.conf import settings from django.db.models import get_model from istore.views.generic import PostActionMixin from istore.apps.customer.utils import get_password_reset_url from istore.core.loading import get_class, get_profile_class, get_classes from istore.core.compat import get_user_model Dispatcher = get_class('customer.utils', 'Dispatcher') EmailAuthenticationForm, EmailUserCreationForm, SearchByDateRangeForm = get_classes( 'customer.forms', ['EmailAuthenticationForm', 'EmailUserCreationForm', 'SearchByDateRangeForm']) ProfileForm = get_class('customer.forms', 'ProfileForm') UserAddressForm = get_class('address.forms', 'UserAddressForm') user_registered = get_class('customer.signals', 'user_registered') Order = get_model('order', 'Order') Line = get_model('basket', 'Line') Basket = get_model('basket', 'Basket') UserAddress = get_model('address', 'UserAddress') Email = get_model('customer', 'Email') UserAddress = get_model('address', 'UserAddress')
import zlib from django.conf import settings from django.db.models import get_model from istore.core.loading import get_class Applicator = get_class('offer.utils', 'Applicator') Basket = get_model('basket', 'basket') class BasketMiddleware(object): def process_request(self, request): request.cookies_to_delete = [] basket = self.get_basket(request) self.apply_offers_to_basket(request, basket) request.basket = basket def get_basket(self, request): manager = Basket.open cookie_basket = self.get_cookie_basket( settings.ISTORE_BASKET_COOKIE_OPEN, request, manager) if hasattr(request, 'user') and request.user.is_authenticated(): # Signed-in user: if they have a cookie basket too, it means # that they have just signed in and we need to merge their cookie # basket into their user basket, then delete the cookie try: basket, _ = manager.get_or_create(owner=request.user) except Basket.MultipleObjectsReturned:
import logging from optparse import make_option from django.core.management.base import BaseCommand, CommandError from istore.core.loading import get_class StockImporter = get_class('partner.utils', 'StockImporter') ImportError = get_class('partner.exceptions', 'ImportError') class Command(BaseCommand): args = '<partner> /path/to/file1.csv' help = 'For updating stock for a partner based on a CSV file' option_list = BaseCommand.option_list + ( make_option('--delimiter', dest='delimiter', default=",", help='Delimiter used within CSV file(s)'), ) def handle(self, *args, **options): if len(args) != 2: raise CommandError( 'Command requires a partner and a path to a csv file') logger = self._get_logger() try: importer = StockImporter(logger, partner=args[0],
from django.http import HttpResponseRedirect from django.contrib import messages from django.core.urlresolvers import reverse from django.utils.translation import ugettext_lazy as _ from istore.core.loading import get_class ProgressChecker = get_class('checkout.utils', 'ProgressChecker') def prev_steps_must_be_complete(view_fn): """ Decorator for checking that previous steps of the checkout are complete. The completed steps (identified by URL-names) are stored in the session. If this fails, then we redirect to the next uncompleted step. """ def _view_wrapper(self, request, *args, **kwargs): checker = ProgressChecker() if not checker.are_previous_steps_complete(request): messages.error(request, _("You must complete this step of the checkout first")) url_name = checker.get_next_step(request) return HttpResponseRedirect(reverse(url_name)) return view_fn(self, request, *args, **kwargs) return _view_wrapper def basket_required(view_fn): """ Decorator for checking that the user has a non-empty basket or has a frozen one in the session
from django.contrib.sites.models import Site from django.conf import settings from django.db.models import get_model from django.utils.translation import ugettext_lazy as _ from istore.apps.shipping.methods import Free from istore.apps.order.exceptions import UnableToPlaceOrder from istore.core.loading import get_class ShippingAddress = get_model("order", "ShippingAddress") Order = get_model("order", "Order") Line = get_model("order", "Line") LinePrice = get_model("order", "LinePrice") LineAttribute = get_model("order", "LineAttribute") OrderDiscount = get_model("order", "OrderDiscount") order_placed = get_class("order.signals", "order_placed") class OrderNumberGenerator(object): """ Simple object for generating order numbers. We need this as the order number is often required for payment which takes place before the order model has been created. """ def order_number(self, basket): """ Return an order number for a given basket """ return 100000 + basket.id
from django.shortcuts import get_object_or_404 from django.utils.translation import ugettext_lazy as _ from istore.core.loading import get_classes, get_class ConditionalOffer = get_model('offer', 'ConditionalOffer') Condition = get_model('offer', 'Condition') Range = get_model('offer', 'Range') Product = get_model('catalogue', 'Product') OrderDiscount = get_model('order', 'OrderDiscount') Benefit = get_model('offer', 'Benefit') MetaDataForm, ConditionForm, BenefitForm, RestrictionsForm, OfferSearchForm = get_classes( 'dashboard.offers.forms', [ 'MetaDataForm', 'ConditionForm', 'BenefitForm', 'RestrictionsForm', 'OfferSearchForm']) OrderDiscountCSVFormatter = get_class( 'dashboard.offers.reports', 'OrderDiscountCSVFormatter') class OfferListView(ListView): model = ConditionalOffer context_object_name = 'offers' template_name = 'dashboard/offers/offer_list.html' form_class = OfferSearchForm def get_queryset(self): qs = self.model._default_manager.filter( offer_type=ConditionalOffer.SITE) qs = self.sort_queryset(qs) self.description = _("All offers")
import logging from django.core.management.base import BaseCommand from istore.core.loading import get_class Calculator = get_class('analytics.scores', 'Calculator') logger = logging.getLogger(__name__) class Command(BaseCommand): help = 'Calculate product scores based on analytics data' def handle(self, *args, **options): Calculator(logger).run()
from django.db.models import get_model from django.utils.translation import ugettext_lazy as _ from istore.core.loading import get_class ReportGenerator = get_class('dashboard.reports.reports', 'ReportGenerator') ReportCSVFormatter = get_class('dashboard.reports.reports', 'ReportCSVFormatter') ReportHTMLFormatter = get_class('dashboard.reports.reports', 'ReportHTMLFormatter') Basket = get_model('basket', 'Basket') class OpenBasketReportCSVFormatter(ReportCSVFormatter): filename_template = 'open-baskets-%s-%s.csv' def generate_csv(self, response, baskets): writer = self.get_csv_writer(response) header_row = [_('User ID'), _('Name'), _('Email'), _('Basket status'), _('Num lines'), _('Num items'), _('Value'), _('Date of creation'), _('Time since creation'), ] writer.writerow(header_row) for basket in baskets: if basket.owner:
import logging from optparse import make_option from django.core.management.base import BaseCommand, CommandError from istore.core.loading import get_class Importer = get_class('catalogue.utils', 'Importer') class Command(BaseCommand): args = '/path/to/folder' help = 'For importing product images from a folder' option_list = BaseCommand.option_list + ( make_option('--filename', dest='filename', default='upc', help='Product field to lookup from image filename'), ) def handle(self, *args, **options): if len(args) != 1: raise CommandError('Command requires a path to a single folder') logger = self._get_logger() logger.info("Starting image import...") dirname = args[0] importer = Importer(logger, field=options.get('filename')) importer.handle(dirname)
from django.db.models import get_model from django.utils.translation import ugettext_lazy as _ from istore.core.loading import get_class ReportGenerator = get_class("dashboard.reports.reports", "ReportGenerator") ReportCSVFormatter = get_class("dashboard.reports.reports", "ReportCSVFormatter") ReportHTMLFormatter = get_class("dashboard.reports.reports", "ReportHTMLFormatter") ProductRecord = get_model("analytics", "ProductRecord") UserRecord = get_model("analytics", "UserRecord") class ProductReportCSVFormatter(ReportCSVFormatter): filename_template = "conditional-offer-performance.csv" def generate_csv(self, response, products): writer = self.get_csv_writer(response) header_row = [_("Product"), _("Views"), _("Basket additions"), _("Purchases")] writer.writerow(header_row) for record in products: row = [record.product, record.num_views, record.num_basket_additions, record.num_purchases] writer.writerow(row) class ProductReportHTMLFormatter(ReportHTMLFormatter): filename_template = "dashboard/reports/partials/product_report.html" class ProductReportGenerator(ReportGenerator): code = "product_analytics"
import logging from django.db.models import get_model from istore.apps.shipping.methods import Free from istore.core.loading import get_class OrderTotalCalculator = get_class('checkout.calculators', 'OrderTotalCalculator') CheckoutSessionData = get_class('checkout.utils', 'CheckoutSessionData') ShippingAddress = get_model('order', 'ShippingAddress') UserAddress = get_model('address', 'UserAddress') # Standard logger for checkout events logger = logging.getLogger('istore.checkout') class CheckoutSessionMixin(object): """ Mixin to provide common functionality shared between checkout views. """ def dispatch(self, request, *args, **kwargs): self.checkout_session = CheckoutSessionData(request) return super(CheckoutSessionMixin, self).dispatch(request, *args, **kwargs) def get_shipping_address(self): """ Return the current shipping address for this checkout session. This could either be a ShippingAddress model which has been pre-populated (not saved), or a UserAddress model which will
from django.core.management.base import BaseCommand, CommandError from django.db.models import get_model from istore.core.loading import get_class Order = get_model('order', 'Order') CommunicationEventType = get_model('customer', 'CommunicationEventType') Dispatcher = get_class('customer.utils', 'Dispatcher') class Command(BaseCommand): args = '<communication_event_type> <order number>' help = 'For testing the content of order emails' def handle(self, *args, **options): if len(args) != 2: raise CommandError("Please select a event type and order number") try: order = Order.objects.get(number=args[1]) except Order.DoesNotExist: raise CommandError("No order found with number %s" % args[1]) messages = CommunicationEventType.objects.get_and_render( args[0], {'order': order}) print("Subject: %s\nBody:\n\n%s\nBody HTML:\n\n%s" % ( messages['subject'], messages['body'], messages['html']))
import logging from django.http import Http404, HttpResponseRedirect, HttpResponseBadRequest from django.core.urlresolvers import reverse from django.contrib import messages from django.contrib.auth import login from django.db.models import get_model from django.utils.translation import ugettext as _ from django.views.generic import DetailView, TemplateView, FormView, \ DeleteView, UpdateView, CreateView from istore.apps.shipping.methods import NoShippingRequired from istore.core.loading import get_class, get_classes ShippingAddressForm, GatewayForm = get_classes('checkout.forms', ['ShippingAddressForm', 'GatewayForm']) OrderTotalCalculator = get_class('checkout.calculators', 'OrderTotalCalculator') CheckoutSessionData = get_class('checkout.utils', 'CheckoutSessionData') pre_payment, post_payment = get_classes('checkout.signals', ['pre_payment', 'post_payment']) OrderNumberGenerator, OrderCreator = get_classes('order.utils', ['OrderNumberGenerator', 'OrderCreator']) UserAddressForm = get_class('address.forms', 'UserAddressForm') Repository = get_class('shipping.repository', 'Repository') AccountAuthView = get_class('customer.views', 'AccountAuthView') # RedirectRequired, UnableToTakePayment, PaymentError = get_classes( # 'payment.exceptions', ['RedirectRequired', 'UnableToTakePayment', 'PaymentError']) UnableToPlaceOrder = get_class('order.exceptions', 'UnableToPlaceOrder') OrderPlacementMixin = get_class('checkout.mixins', 'OrderPlacementMixin') CheckoutSessionMixin = get_class('checkout.session', 'CheckoutSessionMixin') Order = get_model('order', 'Order') ShippingAddress = get_model('order', 'ShippingAddress') CommunicationEvent = get_model('order', 'CommunicationEvent')
from django.template.loader import render_to_string from django.template import RequestContext from django.core.urlresolvers import reverse, resolve from django.utils import simplejson as json from django.db.models import get_model from django.http import HttpResponseRedirect, Http404, HttpResponse from django.views.generic import FormView, View from django.utils.translation import ugettext_lazy as _ from django.core.exceptions import ObjectDoesNotExist from extra_views import ModelFormSetView from istore.core import ajax from istore.apps.basket.signals import basket_addition, voucher_addition from istore.templatetags.currency_filters import currency from istore.core.loading import get_class, get_classes Applicator = get_class('offer.utils', 'Applicator') (BasketLineForm, AddToBasketForm, BasketVoucherForm, SavedLineFormSet, SavedLineForm, ProductSelectionForm) = get_classes( 'basket.forms', ('BasketLineForm', 'AddToBasketForm', 'BasketVoucherForm', 'SavedLineFormSet', 'SavedLineForm', 'ProductSelectionForm')) Repository = get_class('shipping.repository', ('Repository')) def get_messages(basket, offers_before, offers_after, include_buttons=True): """ Return the messages about offer changes """ # Look for changes in offers offers_lost = set(offers_before.keys()).difference(
from django.utils.translation import ugettext_lazy as _ from istore.core.loading import get_class ReportCSVFormatter = get_class("dashboard.reports.reports", "ReportCSVFormatter") class OrderDiscountCSVFormatter(ReportCSVFormatter): filename_template = "order-discounts-for-offer-%s.csv" def generate_csv(self, response, order_discounts): writer = self.get_csv_writer(response) header_row = [_("Order number"), _("Order date"), _("Order total"), _("Cost")] writer.writerow(header_row) for order_discount in order_discounts: order = order_discount.order row = [order.number, self.format_datetime(order.date_placed), order.total_incl_tax, order_discount.amount] writer.writerow(row) def filename(self, offer): return self.filename_template % offer.id
from django.conf import settings from django.http import HttpResponsePermanentRedirect, Http404 from django.views.generic import ListView, DetailView from django.db.models import get_model from django.utils.translation import ugettext_lazy as _ from istore.core.loading import get_class from istore.apps.catalogue.signals import product_viewed, product_search Product = get_model('catalogue', 'product') ProductReview = get_model('reviews', 'ProductReview') Category = get_model('catalogue', 'category') ProductAlert = get_model('customer', 'ProductAlert') ProductAlertForm = get_class('customer.forms', 'ProductAlertForm') class ProductDetailView(DetailView): context_object_name = 'product' model = Product view_signal = product_viewed template_folder = "catalogue" def get(self, request, **kwargs): # Ensure that the correct URL is used product = self.get_object() if product.is_variant: return HttpResponsePermanentRedirect(product.parent.get_absolute_url()) correct_path = product.get_absolute_url() if correct_path != request.path:
from django.http import HttpResponseForbidden, Http404 from django.template.response import TemplateResponse from django.views.generic import ListView from django.utils.translation import ugettext_lazy as _ from istore.core.loading import get_class ReportForm = get_class('dashboard.reports.forms', 'ReportForm') GeneratorRepository = get_class('dashboard.reports.utils', 'GeneratorRepository') class IndexView(ListView): template_name = 'dashboard/reports/index.html' paginate_by = 25 context_object_name = 'objects' report_form_class = ReportForm generator_repository = GeneratorRepository def _get_generator(self, form): code = form.cleaned_data['report_type'] repo = self.generator_repository() generator_cls = repo.get_generator(code) if not generator_cls: raise Http404() download = form.cleaned_data['download'] formatter = 'CSV' if download else 'HTML' return generator_cls(start_date=form.cleaned_data['date_from'], end_date=form.cleaned_data['date_to'], formatter=formatter)