Просмотр исходного кода

Adapt dashboard views to multiple stockrecords

We allow access to a product as long as one stockrecord's partner has
the user in it's list. That more permissive default was chosen as it
reduces UI complexity and we don't want to complicate already complex
behaviour further.
master
Maik Hoepfel 12 лет назад
Родитель
Сommit
df3db982c3

+ 12
- 7
oscar/apps/catalogue/abstract_models.py Просмотреть файл

@@ -6,7 +6,7 @@ import warnings
6 6
 
7 7
 from django.conf import settings
8 8
 from django.contrib.staticfiles.finders import find
9
-from django.core.exceptions import ObjectDoesNotExist, ValidationError, ImproperlyConfigured
9
+from django.core.exceptions import ValidationError, ImproperlyConfigured
10 10
 from django.core.validators import RegexValidator
11 11
 from django.db import models
12 12
 from django.db.models import Sum, Count, get_model
@@ -490,14 +490,19 @@ class AbstractProduct(models.Model):
490 490
             return False, _("No stock available")
491 491
         return self.stockrecord.is_purchase_permitted(user, quantity, self)
492 492
 
493
-    def user_in_partner_users(self, user):
493
+    def is_user_in_partners_users(self, user, match_all=False):
494 494
         """
495
-        Test whether the user is in this product partner's users
495
+        The stockrecords of this product are linked to a fulfilment partner,
496
+        which have a M2M field for a list of users.
497
+
498
+        This function tests whether a given user is in any (match_all=False) or
499
+        all (match_all=True) of those user lists.
496 500
         """
497
-        try:
498
-            return self.stockrecord.partner.users.filter(pk=user.pk).exists()
499
-        except (AttributeError, ObjectDoesNotExist):
500
-            return False
501
+        queryset = user.partners.filter(stockrecords__product=self)
502
+        if match_all:
503
+            return queryset.count() == self.stockrecords.count()
504
+        else:
505
+            return queryset.exists()
501 506
 
502 507
     @property
503 508
     def min_variant_price_incl_tax(self):

+ 19
- 14
oscar/apps/dashboard/catalogue/views.py Просмотреть файл

@@ -1,4 +1,4 @@
1
-from django.core.exceptions import ObjectDoesNotExist, PermissionDenied, ImproperlyConfigured
1
+from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
2 2
 from django.views import generic
3 3
 from django.db.models import get_model
4 4
 from django.http import HttpResponseRedirect, Http404
@@ -35,6 +35,15 @@ StockAlert = get_model('partner', 'StockAlert')
35 35
 Partner = get_model('partner', 'Partner')
36 36
 
37 37
 
38
+def get_queryset_for_user(user):
39
+    queryset = Product.objects.base_queryset().order_by('-date_created')
40
+    if user.is_staff:
41
+        return queryset.all()
42
+    else:
43
+        return queryset.filter(
44
+            stockrecords__partner__users__pk=user.pk).distinct()
45
+
46
+
38 47
 class ProductListView(generic.ListView):
39 48
     template_name = 'dashboard/catalogue/product_list.html'
40 49
     model = Product
@@ -50,14 +59,6 @@ class ProductListView(generic.ListView):
50 59
         ctx['queryset_description'] = self.description
51 60
         return ctx
52 61
 
53
-    def get_queryset_for_user(self, user):
54
-        queryset = self.model.objects.base_queryset().select_related(
55
-            'stockrecord__partner').order_by('-date_created')
56
-        if user.is_staff:
57
-            return queryset.all()
58
-        else:
59
-            return queryset.filter(stockrecord__partner__users__pk=user.pk)
60
-
61 62
     def get_queryset(self):
62 63
         """
63 64
         Build the queryset for this list and also update the title that
@@ -65,7 +66,7 @@ class ProductListView(generic.ListView):
65 66
         """
66 67
         description_ctx = {'upc_filter': '',
67 68
                            'title_filter': ''}
68
-        queryset = self.get_queryset_for_user(self.request.user)
69
+        queryset = get_queryset_for_user(self.request.user)
69 70
         self.form = self.form_class(self.request.GET)
70 71
         if not self.form.is_valid():
71 72
             self.description = self.description_template % description_ctx
@@ -137,9 +138,13 @@ class ProductCreateUpdateView(generic.UpdateView):
137 138
             else:
138 139
                 return None  # success
139 140
         else:
140
-            obj = super(ProductCreateUpdateView, self).get_object(queryset)
141
-            self.product_class = obj.product_class
142
-            return obj
141
+            product = super(ProductCreateUpdateView, self).get_object(queryset)
142
+            user = self.request.user
143
+            self.product_class = product.product_class
144
+            if user.is_staff or product.is_user_in_partners_users(user):
145
+                return product
146
+            else:
147
+                raise PermissionDenied
143 148
 
144 149
     def get_context_data(self, **kwargs):
145 150
         ctx = super(ProductCreateUpdateView, self).get_context_data(**kwargs)
@@ -270,7 +275,7 @@ class ProductDeleteView(generic.DeleteView):
270 275
         """
271 276
         product = super(ProductDeleteView, self).get_object(queryset)
272 277
         user = self.request.user
273
-        if user.is_staff or product.user_in_partner_users(user):
278
+        if user.is_staff or product.is_user_in_partners_users(user):
274 279
             return product
275 280
         else:
276 281
             raise PermissionDenied

+ 7
- 5
oscar/test/factories.py Просмотреть файл

@@ -25,14 +25,15 @@ ProductAttributeValue = get_model('catalogue', 'ProductAttributeValue')
25 25
 
26 26
 
27 27
 def create_stockrecord(product=None, price_excl_tax=None, partner_sku=None,
28
-                       num_in_stock=None, partner_name="Dummy partner",
28
+                       num_in_stock=None, partner_name=u"Dummy partner",
29 29
                        currency=settings.OSCAR_DEFAULT_CURRENCY,
30
-                       partner_users=[]):
30
+                       partner_users=None):
31 31
     if product is None:
32 32
         product = create_product()
33 33
     partner, __ = Partner.objects.get_or_create(
34 34
         name=partner_name)
35
-    for user in partner_users:
35
+    if partner_users:
36
+        for user in partner_users:
36 37
             partner.users.add(user)
37 38
     if not price_excl_tax:
38 39
         price_excl_tax = D('9.99')
@@ -79,10 +80,11 @@ def create_product(upc=None, title=u"Dummy title",
79 80
 
80 81
     # Shortcut for creating stockrecord
81 82
     stockrecord_fields = [price, partner_sku, num_in_stock, partner_users]
82
-    if any([field is not None for field in stockrecord_fields):
83
+    if any([field is not None for field in stockrecord_fields]):
83 84
         create_stockrecord(
84 85
             product, price_excl_tax=price, num_in_stock=num_in_stock,
85
-            partner_users=partner_users, partner_sku=partner_sku)
86
+            partner_users=partner_users, partner_sku=partner_sku,
87
+            partner_name=partner)
86 88
     return product
87 89
 
88 90
 

Загрузка…
Отмена
Сохранить