Exemplo n.º 1
0
class OrdersDashboardApplication(DashboardApplication):
    name = None
    default_permissions = ['is_staff', ]
    permissions_map = {
        'order-list': (['is_staff'], ['partner.dashboard_access']),
        'order-stats': (['is_staff'], ['partner.dashboard_access']),
        'order-detail': (['is_staff'], ['partner.dashboard_access']),
        'order-detail-note': (['is_staff'], ['partner.dashboard_access']),
        'order-line-detail': (['is_staff'], ['partner.dashboard_access']),
        'order-shipping-address': (['is_staff'], ['partner.dashboard_access']),
    }

    order_list_view = get_class('dashboard.orders.views', 'OrderListView')
    order_detail_view = get_class('dashboard.orders.views', 'OrderDetailView')
    shipping_address_view = get_class('dashboard.orders.views',
                                      'ShippingAddressUpdateView')
    line_detail_view = get_class('dashboard.orders.views', 'LineDetailView')
    order_stats_view = get_class('dashboard.orders.views', 'OrderStatsView')

    def get_urls(self):
        urls = [
            url(r'^$', self.order_list_view.as_view(), name='order-list'),
            url(r'^statistics/$', self.order_stats_view.as_view(),
                name='order-stats'),
            url(r'^(?P<number>[-\w]+)/$',
                self.order_detail_view.as_view(), name='order-detail'),
            url(r'^(?P<number>[-\w]+)/notes/(?P<note_id>\d+)/$',
                self.order_detail_view.as_view(), name='order-detail-note'),
            url(r'^(?P<number>[-\w]+)/lines/(?P<line_id>\d+)/$',
                self.line_detail_view.as_view(), name='order-line-detail'),
            url(r'^(?P<number>[-\w]+)/shipping-address/$',
                self.shipping_address_view.as_view(),
                name='order-shipping-address'),
        ]
        return self.post_process_urls(urls)
Exemplo n.º 2
0
class BaseCatalogueApplication(Application):
    name = 'catalogue'
    detail_view = get_class('catalogue.views', 'ProductDetailView')
    catalogue_view = get_class('catalogue.views', 'CatalogueView')
    category_view = get_class('catalogue.views', 'ProductCategoryView')
    range_view = get_class('offer.views', 'RangeDetailView')

    def get_urls(self):
        urlpatterns = super(BaseCatalogueApplication, self).get_urls()
        urlpatterns += [
            url(r'^$', self.catalogue_view.as_view(), name='index'),
            url(r'^(?P<product_slug>[\w-]*)_(?P<pk>\d+)/$',
                self.detail_view.as_view(),
                name='detail'),
            url(r'^category/(?P<category_slug>[\w-]+(/[\w-]+)*)_(?P<pk>\d+)/$',
                self.category_view.as_view(),
                name='category'),
            # Fallback URL if a user chops of the last part of the URL
            url(r'^category/(?P<category_slug>[\w-]+(/[\w-]+)*)/$',
                self.category_view.as_view()),
            url(r'^ranges/(?P<slug>[\w-]+)/$',
                self.range_view.as_view(),
                name='range')
        ]
        return self.post_process_urls(urlpatterns)
Exemplo n.º 3
0
class VoucherDashboardApplication(DashboardApplication):
    name = None
    default_permissions = [
        'is_staff',
    ]

    list_view = get_class('dashboard.vouchers.views', 'VoucherListView')
    create_view = get_class('dashboard.vouchers.views', 'VoucherCreateView')
    update_view = get_class('dashboard.vouchers.views', 'VoucherUpdateView')
    delete_view = get_class('dashboard.vouchers.views', 'VoucherDeleteView')
    stats_view = get_class('dashboard.vouchers.views', 'VoucherStatsView')

    set_list_view = get_class('dashboard.vouchers.views', 'VoucherSetListView')
    set_create_view = get_class('dashboard.vouchers.views',
                                'VoucherSetCreateView')
    set_update_view = get_class('dashboard.vouchers.views',
                                'VoucherSetUpdateView')
    set_detail_view = get_class('dashboard.vouchers.views',
                                'VoucherSetDetailView')
    set_download_view = get_class('dashboard.vouchers.views',
                                  'VoucherSetDownloadView')

    def get_urls(self):
        urls = [
            url(r'^$', self.list_view.as_view(), name='voucher-list'),
            url(r'^create/$',
                self.create_view.as_view(),
                name='voucher-create'),
            url(r'^update/(?P<pk>\d+)/$',
                self.update_view.as_view(),
                name='voucher-update'),
            url(r'^delete/(?P<pk>\d+)/$',
                self.delete_view.as_view(),
                name='voucher-delete'),
            url(r'^stats/(?P<pk>\d+)/$',
                self.stats_view.as_view(),
                name='voucher-stats'),
            url(r'^sets$',
                self.set_list_view.as_view(),
                name='voucher-set-list'),
            url(r'^sets/create/$',
                self.set_create_view.as_view(),
                name='voucher-set-create'),
            url(r'^sets/update/(?P<pk>\d+)/$',
                self.set_update_view.as_view(),
                name='voucher-set-update'),
            url(r'^sets/(?P<pk>\d+)/$',
                self.set_detail_view.as_view(),
                name='voucher-set'),
            url(r'^sets/(?P<pk>\d+)/download$',
                self.set_download_view.as_view(),
                name='voucher-set-download'),
        ]
        return self.post_process_urls(urls)
Exemplo n.º 4
0
 def test_raise_importerror_if_app_raises_importerror(self):
     """
     This tests that Wshop doesn't fall back to using the Wshop catalogue
     app if the overriding app throws an ImportError.
     """
     apps = list(settings.INSTALLED_APPS)
     apps[apps.index(
         'wshop.apps.catalogue')] = 'tests._site.import_error_app.catalogue'
     with override_settings(INSTALLED_APPS=apps):
         with self.assertRaises(ImportError):
             get_class('catalogue.app', 'CatalogueApplication')
Exemplo n.º 5
0
class OfferApplication(Application):
    name = 'offer'
    detail_view = get_class('offer.views', 'OfferDetailView')
    list_view = get_class('offer.views', 'OfferListView')

    def get_urls(self):
        urls = [
            url(r'^$', self.list_view.as_view(), name='list'),
            url(r'^(?P<slug>[\w-]+)/$', self.detail_view.as_view(),
                name='detail'),
        ]
        return self.post_process_urls(urls)
Exemplo n.º 6
0
class Shop(Application):
    name = None

    catalogue_app = get_class('catalogue.app', 'application')
    customer_app = get_class('customer.app', 'application')
    basket_app = get_class('basket.app', 'application')
    checkout_app = get_class('checkout.app', 'application')
    promotions_app = get_class('promotions.app', 'application')
    search_app = get_class('search.app', 'application')
    dashboard_app = get_class('dashboard.app', 'application')
    offer_app = get_class('offer.app', 'application')

    password_reset_form = get_class('customer.forms', 'PasswordResetForm')
    set_password_form = get_class('customer.forms', 'SetPasswordForm')

    def get_urls(self):
        urls = [
            url(r'^catalogue/', self.catalogue_app.urls),
            url(r'^basket/', self.basket_app.urls),
            url(r'^checkout/', self.checkout_app.urls),
            url(r'^accounts/', self.customer_app.urls),
            url(r'^search/', self.search_app.urls),
            url(r'^dashboard/', self.dashboard_app.urls),
            url(r'^offers/', self.offer_app.urls),

            # Password reset - as we're using Django's default view functions,
            # we can't namespace these urls as that prevents
            # the reverse function from working.
            url(r'^password-reset/$',
                login_forbidden(auth_views.password_reset), {
                    'password_reset_form': self.password_reset_form,
                    'post_reset_redirect': reverse_lazy('password-reset-done')
                },
                name='password-reset'),
            url(r'^password-reset/done/$',
                login_forbidden(auth_views.password_reset_done),
                name='password-reset-done'),
            url(r'^password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
                login_forbidden(auth_views.password_reset_confirm), {
                    'post_reset_redirect':
                    reverse_lazy('password-reset-complete'),
                    'set_password_form': self.set_password_form,
                },
                name='password-reset-confirm'),
            url(r'^password-reset/complete/$',
                login_forbidden(auth_views.password_reset_complete),
                name='password-reset-complete'),
        ]

        if settings.WSHOP_PROMOTIONS_ENABLED:
            urls.append(url(r'', self.promotions_app.urls))
        return urls
Exemplo n.º 7
0
class CheckoutApplication(Application):
    name = 'checkout'

    index_view = get_class('checkout.views', 'IndexView')
    shipping_address_view = get_class('checkout.views', 'ShippingAddressView')
    user_address_update_view = get_class('checkout.views',
                                         'UserAddressUpdateView')
    user_address_delete_view = get_class('checkout.views',
                                         'UserAddressDeleteView')
    shipping_method_view = get_class('checkout.views', 'ShippingMethodView')
    payment_method_view = get_class('checkout.views', 'PaymentMethodView')
    payment_details_view = get_class('checkout.views', 'PaymentDetailsView')
    thankyou_view = get_class('checkout.views', 'ThankYouView')

    def get_urls(self):
        urls = [
            url(r'^$', self.index_view.as_view(), name='index'),

            # Shipping/user address views
            url(r'shipping-address/$',
                self.shipping_address_view.as_view(),
                name='shipping-address'),
            url(r'user-address/edit/(?P<pk>\d+)/$',
                self.user_address_update_view.as_view(),
                name='user-address-update'),
            url(r'user-address/delete/(?P<pk>\d+)/$',
                self.user_address_delete_view.as_view(),
                name='user-address-delete'),

            # Shipping method views
            url(r'shipping-method/$',
                self.shipping_method_view.as_view(),
                name='shipping-method'),

            # Payment views
            url(r'payment-method/$',
                self.payment_method_view.as_view(),
                name='payment-method'),
            url(r'payment-details/$',
                self.payment_details_view.as_view(),
                name='payment-details'),

            # Preview and thankyou
            url(r'preview/$',
                self.payment_details_view.as_view(preview=True),
                name='preview'),
            url(r'thank-you/$', self.thankyou_view.as_view(),
                name='thank-you'),
        ]
        return self.post_process_urls(urls)

    def get_url_decorator(self, pattern):
        if not settings.WSHOP_ALLOW_ANON_CHECKOUT:
            return login_required
        if pattern.name.startswith('user-address'):
            return login_required
        return None
Exemplo n.º 8
0
class CommsDashboardApplication(DashboardApplication):
    name = None
    default_permissions = [
        'is_staff',
    ]

    list_view = get_class('dashboard.communications.views', 'ListView')
    update_view = get_class('dashboard.communications.views', 'UpdateView')

    def get_urls(self):
        urls = [
            url(r'^$', self.list_view.as_view(), name='comms-list'),
            url(r'^(?P<slug>\w+)/$',
                self.update_view.as_view(),
                name='comms-update'),
        ]
        return self.post_process_urls(urls)
Exemplo n.º 9
0
class PromotionsApplication(Application):
    name = 'promotions'

    home_view = get_class('promotions.views', 'HomeView')
    record_click_view = get_class('promotions.views', 'RecordClickView')

    def get_urls(self):
        urls = [
            url(r'page-redirect/(?P<page_promotion_id>\d+)/$',
                self.record_click_view.as_view(model=PagePromotion),
                name='page-click'),
            url(r'keyword-redirect/(?P<keyword_promotion_id>\d+)/$',
                self.record_click_view.as_view(model=KeywordPromotion),
                name='keyword-click'),
            url(r'^$', self.home_view.as_view(), name='home'),
        ]
        return self.post_process_urls(urls)
Exemplo n.º 10
0
    def test_override_class_loader(self):
        # Clear lru cache for the class loader
        get_class_loader.cache_clear()

        View = get_class('catalogue.views', 'ProductDetailView')
        self.assertEqual(View, DummyClass)

        # Clear lru cache for the class loader again
        get_class_loader.cache_clear()
Exemplo n.º 11
0
def get_product_search_handler_class():
    """
    Determine the search handler to use.

    Currently only Solr is supported as a search backend, so it falls
    back to rudimentary category browsing if that isn't enabled.
    """
    # Use get_class to ensure overridability
    if settings.WSHOP_PRODUCT_SEARCH_HANDLER is not None:
        return import_string(settings.WSHOP_PRODUCT_SEARCH_HANDLER)
    if is_solr_supported():
        return get_class('catalogue.search_handlers', 'SolrProductSearchHandler')
    elif is_elasticsearch_supported():
        return get_class(
            'catalogue.search_handlers', 'ESProductSearchHandler',
        )
    else:
        return get_class(
            'catalogue.search_handlers', 'SimpleProductSearchHandler')
Exemplo n.º 12
0
def default_access_fn(user, url_name, url_args=None, url_kwargs=None):
    """
    Given a url_name and a user, this function tries to assess whether the
    user has the right to access the URL.
    The application instance of the view is fetched via dynamic imports,
    and those assumptions will only hold true if the standard Wshop layout
    is followed.
    Once the permissions for the view are known, the access logic used
    by the dashboard decorator is evaluated

    This function might seem costly, but a simple comparison with DTT
    did not show any change in response time
    """
    exception = ImproperlyConfigured(
        "Please follow Wshop's default dashboard app layout or set a "
        "custom access_fn")
    if url_name is None:  # it's a heading
        return True

    # get view module string.
    try:
        url = reverse(url_name, args=url_args, kwargs=url_kwargs)
    except NoReverseMatch:
        # In Wshop 1.5 this exception was silently ignored which made debugging
        # very difficult. Now it is being logged and in future the exception will
        # be propagated.
        logger.exception('Invalid URL name {}'.format(url_name))
        return False

    view_module = resolve(url).func.__module__

    # We can't assume that the view has the same parent module as the app,
    # as either the app or view can be customised. So we turn the module
    # string (e.g. 'wshop.apps.dashboard.catalogue.views') into an app
    # label that can be loaded by get_class (e.g.
    # 'dashboard.catalogue.app), which then essentially checks
    # INSTALLED_APPS for the right module to load
    match = re.search('(dashboard[\w\.]*)\.views$', view_module)
    if not match:
        raise exception
    app_label_str = match.groups()[0] + '.app'

    try:
        app_instance = get_class(app_label_str, 'application')
    except AppNotFoundError:
        raise exception

    # handle name-spaced view names
    if ':' in url_name:
        view_name = url_name.split(':')[1]
    else:
        view_name = url_name
    permissions = app_instance.get_permissions(view_name)
    return check_permissions(user, permissions)
Exemplo n.º 13
0
class ReviewsApplication(Application):
    name = None
    reviews_app = get_class('catalogue.reviews.app', 'application')

    def get_urls(self):
        urlpatterns = super(ReviewsApplication, self).get_urls()
        urlpatterns += [
            url(r'^(?P<product_slug>[\w-]*)_(?P<product_pk>\d+)/reviews/',
                self.reviews_app.urls)
        ]
        return self.post_process_urls(urlpatterns)
Exemplo n.º 14
0
class ReviewsApplication(DashboardApplication):
    name = None
    default_permissions = [
        'is_staff',
    ]

    list_view = get_class('dashboard.reviews.views', 'ReviewListView')
    update_view = get_class('dashboard.reviews.views', 'ReviewUpdateView')
    delete_view = get_class('dashboard.reviews.views', 'ReviewDeleteView')

    def get_urls(self):
        urls = [
            url(r'^$', self.list_view.as_view(), name='reviews-list'),
            url(r'^(?P<pk>\d+)/$',
                self.update_view.as_view(),
                name='reviews-update'),
            url(r'^(?P<pk>\d+)/delete/$',
                self.delete_view.as_view(),
                name='reviews-delete'),
        ]
        return self.post_process_urls(urls)
Exemplo n.º 15
0
class RangeDashboardApplication(DashboardApplication):
    name = None
    default_permissions = [
        'is_staff',
    ]

    list_view = get_class('dashboard.ranges.views', 'RangeListView')
    create_view = get_class('dashboard.ranges.views', 'RangeCreateView')
    update_view = get_class('dashboard.ranges.views', 'RangeUpdateView')
    delete_view = get_class('dashboard.ranges.views', 'RangeDeleteView')
    products_view = get_class('dashboard.ranges.views', 'RangeProductListView')
    reorder_view = get_class('dashboard.ranges.views', 'RangeReorderView')

    def get_urls(self):
        urlpatterns = [
            url(r'^$', self.list_view.as_view(), name='range-list'),
            url(r'^create/$', self.create_view.as_view(), name='range-create'),
            url(r'^(?P<pk>\d+)/$',
                self.update_view.as_view(),
                name='range-update'),
            url(r'^(?P<pk>\d+)/delete/$',
                self.delete_view.as_view(),
                name='range-delete'),
            url(r'^(?P<pk>\d+)/products/$',
                self.products_view.as_view(),
                name='range-products'),
            url(r'^(?P<pk>\d+)/reorder/$',
                self.reorder_view.as_view(),
                name='range-reorder'),
        ]
        return self.post_process_urls(urlpatterns)
Exemplo n.º 16
0
class FlatPageManagementApplication(DashboardApplication):
    name = None
    default_permissions = ['is_staff', ]

    list_view = get_class('dashboard.pages.views', 'PageListView')
    create_view = get_class('dashboard.pages.views', 'PageCreateView')
    update_view = get_class('dashboard.pages.views', 'PageUpdateView')
    delete_view = get_class('dashboard.pages.views', 'PageDeleteView')

    def get_urls(self):
        """
        Get URL patterns defined for flatpage management application.
        """
        urls = [
            url(r'^$', self.list_view.as_view(), name='page-list'),
            url(r'^create/$', self.create_view.as_view(), name='page-create'),
            url(r'^update/(?P<pk>[-\w]+)/$',
                self.update_view.as_view(), name='page-update'),
            url(r'^delete/(?P<pk>\d+)/$',
                self.delete_view.as_view(), name='page-delete')
        ]
        return self.post_process_urls(urls)
Exemplo n.º 17
0
class ReportsApplication(DashboardApplication):
    name = None
    default_permissions = [
        'is_staff',
    ]

    index_view = get_class('dashboard.reports.views', 'IndexView')

    def get_urls(self):
        urls = [
            url(r'^$', self.index_view.as_view(), name='reports-index'),
        ]
        return self.post_process_urls(urls)
Exemplo n.º 18
0
class BasketApplication(Application):
    name = 'basket'
    summary_view = get_class('basket.views', 'BasketView')
    saved_view = get_class('basket.views', 'SavedView')
    add_view = get_class('basket.views', 'BasketAddView')
    add_voucher_view = get_class('basket.views', 'VoucherAddView')
    remove_voucher_view = get_class('basket.views', 'VoucherRemoveView')

    def get_urls(self):
        urls = [
            url(r'^$', self.summary_view.as_view(), name='summary'),
            url(r'^add/(?P<pk>\d+)/$', self.add_view.as_view(), name='add'),
            url(r'^vouchers/add/$',
                self.add_voucher_view.as_view(),
                name='vouchers-add'),
            url(r'^vouchers/(?P<pk>\d+)/remove/$',
                self.remove_voucher_view.as_view(),
                name='vouchers-remove'),
            url(r'^saved/$',
                login_required(self.saved_view.as_view()),
                name='saved'),
        ]
        return self.post_process_urls(urls)
Exemplo n.º 19
0
class SearchApplication(Application):
    name = 'search'
    search_view = get_class('search.views', 'FacetedSearchView')
    search_form = get_class('search.forms', 'SearchForm')

    def get_urls(self):

        # The form class has to be passed to the __init__ method as that is how
        # Haystack works.  It's slightly different to normal CBVs.
        urlpatterns = [
            url(r'^$',
                search_view_factory(view_class=self.search_view,
                                    form_class=self.search_form,
                                    searchqueryset=self.get_sqs()),
                name='search'),
        ]
        return self.post_process_urls(urlpatterns)

    def get_sqs(self):
        """
        Return the SQS required by a the Haystack search view
        """
        return facets.base_sqs()
Exemplo n.º 20
0
class RequestFactory(BaseRequestFactory):
    Basket = get_model('basket', 'basket')
    selector = get_class('partner.strategy', 'Selector')()

    def request(self, user=None, **request):
        request = super(RequestFactory, self).request(**request)
        request.user = user or AnonymousUser()
        request.session = SessionStore()
        request._messages = FallbackStorage(request)

        request.basket = self.Basket()
        request.basket_hash = None
        strategy = self.selector.strategy(request=request, user=request.user)
        request.strategy = request.basket.strategy = strategy

        return request
Exemplo n.º 21
0
 def proxy_map(self):
     return {
         self.PERCENTAGE:
         get_class('offer.benefits', 'PercentageDiscountBenefit'),
         self.FIXED:
         get_class('offer.benefits', 'AbsoluteDiscountBenefit'),
         self.MULTIBUY:
         get_class('offer.benefits', 'MultibuyDiscountBenefit'),
         self.FIXED_PRICE:
         get_class('offer.benefits', 'FixedPriceBenefit'),
         self.SHIPPING_ABSOLUTE:
         get_class('offer.benefits', 'ShippingAbsoluteDiscountBenefit'),
         self.SHIPPING_FIXED_PRICE:
         get_class('offer.benefits', 'ShippingFixedPriceBenefit'),
         self.SHIPPING_PERCENTAGE:
         get_class('offer.benefits', 'ShippingPercentageDiscountBenefit')
     }
Exemplo n.º 22
0
class OffersDashboardApplication(DashboardApplication):
    name = None
    default_permissions = ['is_staff', ]

    list_view = get_class('dashboard.offers.views', 'OfferListView')
    metadata_view = get_class('dashboard.offers.views', 'OfferMetaDataView')
    condition_view = get_class('dashboard.offers.views', 'OfferConditionView')
    benefit_view = get_class('dashboard.offers.views', 'OfferBenefitView')
    restrictions_view = get_class('dashboard.offers.views',
                                  'OfferRestrictionsView')
    delete_view = get_class('dashboard.offers.views', 'OfferDeleteView')
    detail_view = get_class('dashboard.offers.views', 'OfferDetailView')

    def get_urls(self):
        urls = [
            url(r'^$', self.list_view.as_view(), name='offer-list'),
            # Creation
            url(r'^new/name-and-description/$', self.metadata_view.as_view(),
                name='offer-metadata'),
            url(r'^new/condition/$', self.condition_view.as_view(),
                name='offer-condition'),
            url(r'^new/incentive/$', self.benefit_view.as_view(),
                name='offer-benefit'),
            url(r'^new/restrictions/$', self.restrictions_view.as_view(),
                name='offer-restrictions'),
            # Update
            url(r'^(?P<pk>\d+)/name-and-description/$',
                self.metadata_view.as_view(update=True),
                name='offer-metadata'),
            url(r'^(?P<pk>\d+)/condition/$',
                self.condition_view.as_view(update=True),
                name='offer-condition'),
            url(r'^(?P<pk>\d+)/incentive/$',
                self.benefit_view.as_view(update=True),
                name='offer-benefit'),
            url(r'^(?P<pk>\d+)/restrictions/$',
                self.restrictions_view.as_view(update=True),
                name='offer-restrictions'),
            # Delete
            url(r'^(?P<pk>\d+)/delete/$',
                self.delete_view.as_view(), name='offer-delete'),
            # Stats
            url(r'^(?P<pk>\d+)/$', self.detail_view.as_view(),
                name='offer-detail'),
        ]
        return self.post_process_urls(urls)
Exemplo n.º 23
0
class RequestFactory(BaseRequestFactory):
    Basket = get_model('basket', 'basket')
    selector = get_class('partner.strategy', 'Selector')()

    def request(self, user=None, basket=None, **request):
        request = super(RequestFactory, self).request(**request)
        request.user = user or AnonymousUser()
        request.session = SessionStore()
        request._messages = FallbackStorage(request)

        # Mimic basket middleware
        request.strategy = self.selector.strategy(request=request,
                                                  user=request.user)
        request.basket = basket or self.Basket()
        request.basket.strategy = request.strategy
        request.basket_hash = Signer().sign(basket.pk) if basket else None
        request.cookies_to_delete = []

        return request
Exemplo n.º 24
0
class ShippingDashboardApplication(DashboardApplication):
    name = None
    default_permissions = ['is_staff']

    weight_method_list_view = get_class(
        'dashboard.shipping.views', 'WeightBasedListView')
    weight_method_create_view = get_class(
        'dashboard.shipping.views', 'WeightBasedCreateView')
    weight_method_edit_view = get_class(
        'dashboard.shipping.views', 'WeightBasedUpdateView')
    weight_method_delete_view = get_class(
        'dashboard.shipping.views', 'WeightBasedDeleteView')
    # This doubles as the weight_band create view
    weight_method_detail_view = get_class(
        'dashboard.shipping.views', 'WeightBasedDetailView')
    weight_band_edit_view = get_class(
        'dashboard.shipping.views', 'WeightBandUpdateView')
    weight_band_delete_view = get_class(
        'dashboard.shipping.views', 'WeightBandDeleteView')

    def get_urls(self):
        urlpatterns = [
            url(r'^weight-based/$', self.weight_method_list_view.as_view(),
                name='shipping-method-list'),
            url(r'^weight-based/create/$',
                self.weight_method_create_view.as_view(),
                name='shipping-method-create'),
            url(r'^weight-based/(?P<pk>\d+)/$',
                self.weight_method_detail_view.as_view(),
                name='shipping-method-detail'),
            url(r'^weight-based/(?P<pk>\d+)/edit/$',
                self.weight_method_edit_view.as_view(),
                name='shipping-method-edit'),
            url(r'^weight-based/(?P<pk>\d+)/delete/$',
                self.weight_method_delete_view.as_view(),
                name='shipping-method-delete'),
            url(r'^weight-based/(?P<method_pk>\d+)/bands/(?P<pk>\d+)/$',
                self.weight_band_edit_view.as_view(),
                name='shipping-method-band-edit'),
            url(r'^weight-based/(?P<method_pk>\d+)/bands/(?P<pk>\d+)/delete/$',
                self.weight_band_delete_view.as_view(),
                name='shipping-method-band-delete'),
        ]
        return self.post_process_urls(urlpatterns)
Exemplo n.º 25
0
 def test_load_formset_new_destination(self):
     BaseBasketLineFormSet = get_class('basket.formsets',
                                       'BaseBasketLineFormSet')
     self.assertEqual('wshop.apps.basket.formsets',
                      BaseBasketLineFormSet.__module__)
     StockRecordFormSet = get_class('dashboard.catalogue.formsets',
                                    'StockRecordFormSet')
     self.assertEqual('wshop.apps.dashboard.catalogue.formsets',
                      StockRecordFormSet.__module__)
     OrderedProductFormSet = get_class('dashboard.promotions.formsets',
                                       'OrderedProductFormSet')
     OrderedProductForm = get_class('dashboard.promotions.forms',
                                    'OrderedProductForm')
     self.assertTrue(
         isinstance(OrderedProductFormSet().forms[0], OrderedProductForm))
     LineFormset = get_class('wishlists.formsets', 'LineFormset')
     WishListLineForm = get_class('wishlists.forms', 'WishListLineForm')
     self.assertTrue(
         isinstance(
             LineFormset(instance=self.wishlist).forms[0],
             WishListLineForm))
Exemplo n.º 26
0
class UserManagementApplication(DashboardApplication):
    name = None
    default_permissions = ['is_staff', ]

    index_view = get_class('dashboard.users.views', 'IndexView')
    user_detail_view = get_class('dashboard.users.views', 'UserDetailView')
    password_reset_view = get_class('dashboard.users.views',
                                    'PasswordResetView')
    alert_list_view = get_class('dashboard.users.views',
                                'ProductAlertListView')
    alert_update_view = get_class('dashboard.users.views',
                                  'ProductAlertUpdateView')
    alert_delete_view = get_class('dashboard.users.views',
                                  'ProductAlertDeleteView')

    def get_urls(self):
        urls = [
            url(r'^$', self.index_view.as_view(), name='users-index'),
            url(r'^(?P<pk>-?\d+)/$',
                self.user_detail_view.as_view(), name='user-detail'),
            url(r'^(?P<pk>-?\d+)/password-reset/$',
                self.password_reset_view.as_view(),
                name='user-password-reset'),

            # Alerts
            url(r'^alerts/$',
                self.alert_list_view.as_view(),
                name='user-alert-list'),
            url(r'^alerts/(?P<pk>-?\d+)/delete/$',
                self.alert_delete_view.as_view(),
                name='user-alert-delete'),
            url(r'^alerts/(?P<pk>-?\d+)/update/$',
                self.alert_update_view.as_view(),
                name='user-alert-update'),
        ]
        return self.post_process_urls(urls)
Exemplo n.º 27
0
 def test_load_formset_old_destination(self):
     BaseBasketLineFormSet = get_class('basket.forms',
                                       'BaseBasketLineFormSet')
     self.assertEqual('wshop.apps.basket.formsets',
                      BaseBasketLineFormSet.__module__)
     StockRecordFormSet = get_class('dashboard.catalogue.forms',
                                    'StockRecordFormSet')
     self.assertEqual('wshop.apps.dashboard.catalogue.formsets',
                      StockRecordFormSet.__module__)
     OrderedProductFormSet = get_class('dashboard.promotions.forms',
                                       'OrderedProductFormSet')
     OrderedProductForm = get_class('dashboard.promotions.forms',
                                    'OrderedProductForm')
     # Since OrderedProductFormSet created with metaclass, it has __module__
     # attribute pointing to the Django module. Thus, we test if formset was
     # loaded correctly by initiating class instance and checking its forms.
     self.assertTrue(
         isinstance(OrderedProductFormSet().forms[0], OrderedProductForm))
     LineFormset = get_class('wishlists.forms', 'LineFormset')
     WishListLineForm = get_class('wishlists.forms', 'WishListLineForm')
     self.assertTrue(
         isinstance(
             LineFormset(instance=self.wishlist).forms[0],
             WishListLineForm))
Exemplo n.º 28
0
from collections import defaultdict

from django import forms
from django.conf import settings
from django.forms.widgets import Input
from django.utils.translation import ugettext_lazy as _
from haystack.forms import FacetedSearchForm

from wshop.core.loading import get_class

is_solr_supported = get_class('search.features', 'is_solr_supported')


class SearchInput(Input):
    """
    Defining a search type widget

    This is an HTML5 thing and works nicely with Safari, other browsers default
    back to using the default "text" type
    """
    input_type = 'search'


# Build a dict of valid queries
VALID_FACET_QUERIES = defaultdict(list)
for facet in settings.WSHOP_SEARCH_FACETS['queries'].values():
    field_name = "%s_exact" % facet['field']
    queries = [t[1] for t in facet['queries']]
    VALID_FACET_QUERIES[field_name].extend(queries)

Exemplo n.º 29
0
from django.utils.functional import cached_property
from django.utils.html import strip_tags
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import get_language, pgettext_lazy
from treebeard.mp_tree import MP_Node

from wshop.core.loading import get_class, get_classes, get_model
from wshop.core.utils import slugify
from wshop.core.validators import non_python_keyword
from wshop.models.fields import AutoSlugField, NullCharField
from wshop.models.fields.slugfield import SlugField

ProductManager, BrowsableProductManager = get_classes(
    'catalogue.managers', ['ProductManager', 'BrowsableProductManager'])
ProductAttributesContainer = get_class('catalogue.product_attributes',
                                       'ProductAttributesContainer')
Selector = get_class('partner.strategy', 'Selector')


@python_2_unicode_compatible
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
    Wshop deployment.

    Not necessarily equivalent to top-level categories but usually will be.
    """
    name = models.CharField(_('Name'), max_length=128)
Exemplo n.º 30
0
from django.conf import settings
from django.http import Http404, HttpResponseForbidden
from django.template.response import TemplateResponse
from django.utils.translation import ugettext_lazy as _
from django.views.generic import ListView

from wshop.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 = settings.WSHOP_DASHBOARD_ITEMS_PER_PAGE
    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'