ob-dj-store 0.0.11.3__py3-none-any.whl → 0.0.11.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ob_dj_store/apis/stores/filters.py +33 -18
- ob_dj_store/apis/stores/rest/serializers/serializers.py +129 -53
- ob_dj_store/apis/stores/urls.py +3 -3
- ob_dj_store/apis/stores/views.py +182 -42
- ob_dj_store/core/stores/admin.py +8 -3
- ob_dj_store/core/stores/admin_inlines.py +4 -4
- ob_dj_store/core/stores/gateway/tap/models.py +1 -1
- ob_dj_store/core/stores/gateway/tap/utils.py +4 -4
- ob_dj_store/core/stores/managers.py +8 -6
- ob_dj_store/core/stores/migrations/0056_auto_20230213_2224.py +33 -0
- ob_dj_store/core/stores/migrations/0057_auto_20230214_1724.py +37 -0
- ob_dj_store/core/stores/migrations/0058_attributechoice_is_default.py +18 -0
- ob_dj_store/core/stores/migrations/0059_auto_20230217_2006.py +41 -0
- ob_dj_store/core/stores/migrations/0060_alter_orderitem_product_variant.py +24 -0
- ob_dj_store/core/stores/migrations/0061_auto_20230223_1435.py +28 -0
- ob_dj_store/core/stores/migrations/0062_auto_20230226_2005.py +43 -0
- ob_dj_store/core/stores/migrations/0063_alter_store_payment_methods.py +23 -0
- ob_dj_store/core/stores/migrations/0064_auto_20230228_1814.py +24 -0
- ob_dj_store/core/stores/migrations/0065_auto_20230228_1932.py +34 -0
- ob_dj_store/core/stores/models/_favorite.py +4 -1
- ob_dj_store/core/stores/models/_order.py +4 -2
- ob_dj_store/core/stores/models/_payment.py +31 -11
- ob_dj_store/core/stores/models/_product.py +22 -13
- ob_dj_store/core/stores/models/_store.py +15 -6
- ob_dj_store/core/stores/models/_wallet.py +41 -8
- ob_dj_store/core/stores/receivers.py +79 -4
- ob_dj_store/core/stores/utils.py +12 -6
- ob_dj_store/utils/helpers.py +8 -2
- ob_dj_store/utils/utils.py +43 -3
- {ob_dj_store-0.0.11.3.dist-info → ob_dj_store-0.0.11.10.dist-info}/METADATA +1 -1
- {ob_dj_store-0.0.11.3.dist-info → ob_dj_store-0.0.11.10.dist-info}/RECORD +33 -23
- {ob_dj_store-0.0.11.3.dist-info → ob_dj_store-0.0.11.10.dist-info}/WHEEL +0 -0
- {ob_dj_store-0.0.11.3.dist-info → ob_dj_store-0.0.11.10.dist-info}/top_level.txt +0 -0
ob_dj_store/apis/stores/views.py
CHANGED
@@ -4,6 +4,8 @@ import typing
|
|
4
4
|
from django.contrib.contenttypes.models import ContentType
|
5
5
|
from django.core.exceptions import ObjectDoesNotExist
|
6
6
|
from django.db.models import Prefetch
|
7
|
+
from django.http import Http404
|
8
|
+
from django.shortcuts import get_object_or_404
|
7
9
|
from django.utils.decorators import method_decorator
|
8
10
|
from django.utils.translation import ugettext_lazy as _
|
9
11
|
from django_auto_prefetching import AutoPrefetchViewSetMixin, prefetch
|
@@ -24,6 +26,7 @@ from ob_dj_store.apis.stores.filters import (
|
|
24
26
|
FavoriteFilter,
|
25
27
|
InventoryFilter,
|
26
28
|
OrderFilter,
|
29
|
+
PaymentMethodFilter,
|
27
30
|
ProductFilter,
|
28
31
|
StoreFilter,
|
29
32
|
VariantFilter,
|
@@ -45,6 +48,8 @@ from ob_dj_store.apis.stores.rest.serializers.serializers import (
|
|
45
48
|
ShippingMethodSerializer,
|
46
49
|
StoreSerializer,
|
47
50
|
TaxSerializer,
|
51
|
+
WalletSerializer,
|
52
|
+
WalletTopUpSerializer,
|
48
53
|
)
|
49
54
|
from ob_dj_store.core.stores.models import (
|
50
55
|
Cart,
|
@@ -60,6 +65,7 @@ from ob_dj_store.core.stores.models import (
|
|
60
65
|
ShippingMethod,
|
61
66
|
Store,
|
62
67
|
Tax,
|
68
|
+
Wallet,
|
63
69
|
)
|
64
70
|
from ob_dj_store.core.stores.models._inventory import Inventory
|
65
71
|
|
@@ -80,9 +86,10 @@ class StoreView(
|
|
80
86
|
queryset = Store.objects.active()
|
81
87
|
distance_ordering_filter_field = "location"
|
82
88
|
filter_backends = [DistanceToPointOrderingFilter, DjangoFilterBackend]
|
89
|
+
lookup_value_regex = "[0-9]+"
|
83
90
|
|
84
91
|
def get_permissions(self):
|
85
|
-
if self.action in ["favorites", "favorite", "recently_ordered_from"]:
|
92
|
+
if self.action in ["favorites", "favorite", "recently_ordered_from", "count"]:
|
86
93
|
return [
|
87
94
|
permissions.IsAuthenticated(),
|
88
95
|
]
|
@@ -90,7 +97,7 @@ class StoreView(
|
|
90
97
|
|
91
98
|
def get_queryset(self):
|
92
99
|
queryset = super().get_queryset()
|
93
|
-
queryset.
|
100
|
+
queryset = queryset.prefetch_related("opening_hours")
|
94
101
|
if self.action == "favorites":
|
95
102
|
favorite_store_ids = Favorite.objects.favorites_for_model(
|
96
103
|
Store, self.request.user
|
@@ -185,29 +192,6 @@ class StoreView(
|
|
185
192
|
serializer = self.get_serializer(page, many=True)
|
186
193
|
return self.get_paginated_response(serializer.data)
|
187
194
|
|
188
|
-
@swagger_auto_schema(
|
189
|
-
operation_summary="Add or Remove Store from Favorites",
|
190
|
-
operation_description="""
|
191
|
-
Add or Remove Store from Favorites
|
192
|
-
""",
|
193
|
-
tags=[
|
194
|
-
"Store",
|
195
|
-
],
|
196
|
-
)
|
197
|
-
@action(
|
198
|
-
detail=True,
|
199
|
-
methods=["GET"],
|
200
|
-
url_path="favorite",
|
201
|
-
)
|
202
|
-
def favorite(self, request, *args, **kwargs):
|
203
|
-
instance = self.get_object()
|
204
|
-
try:
|
205
|
-
Favorite.objects.favorite_for_user(instance, request.user).delete()
|
206
|
-
except Favorite.DoesNotExist:
|
207
|
-
Favorite.add_favorite(instance, request.user)
|
208
|
-
serializer = StoreSerializer(instance=instance, context={"request": request})
|
209
|
-
return Response(serializer.data)
|
210
|
-
|
211
195
|
@swagger_auto_schema(
|
212
196
|
operation_summary="Retrieve count of store's products",
|
213
197
|
operation_description="""
|
@@ -228,10 +212,13 @@ class StoreView(
|
|
228
212
|
product_variants__inventories__store=store
|
229
213
|
).values_list("id", flat=True)
|
230
214
|
content_type = ContentType.objects.get_for_model(Product)
|
231
|
-
favorites_count =
|
232
|
-
|
233
|
-
|
234
|
-
|
215
|
+
favorites_count = (
|
216
|
+
Favorite.objects.filter(
|
217
|
+
content_type=content_type, object_id__in=products_ids, user=request.user
|
218
|
+
).count()
|
219
|
+
if request.user.id
|
220
|
+
else 0
|
221
|
+
)
|
235
222
|
menu = Product.objects.filter(
|
236
223
|
product_variants__inventories__store=store,
|
237
224
|
category__isnull=False,
|
@@ -244,6 +231,45 @@ class StoreView(
|
|
244
231
|
}
|
245
232
|
return Response(data, status=status.HTTP_200_OK)
|
246
233
|
|
234
|
+
@swagger_auto_schema(
|
235
|
+
operation_summary="Retrieve count of stores",
|
236
|
+
operation_description="""
|
237
|
+
Retrieve count of stores (Nearby,previous,favorites)
|
238
|
+
""",
|
239
|
+
tags=[
|
240
|
+
"Store",
|
241
|
+
],
|
242
|
+
)
|
243
|
+
@action(
|
244
|
+
detail=False,
|
245
|
+
methods=["GET"],
|
246
|
+
url_path="count",
|
247
|
+
)
|
248
|
+
def count(self, request, *args, **kwargs):
|
249
|
+
previous_count = (
|
250
|
+
super()
|
251
|
+
.get_queryset()
|
252
|
+
.filter(
|
253
|
+
orders__customer=self.request.user,
|
254
|
+
orders__status__in=[
|
255
|
+
"PAID",
|
256
|
+
"DELIVERED",
|
257
|
+
],
|
258
|
+
)
|
259
|
+
.count()
|
260
|
+
)
|
261
|
+
nearby_count = super().get_queryset().count()
|
262
|
+
favorite_store_ids = Favorite.objects.favorites_for_model(
|
263
|
+
Store, self.request.user
|
264
|
+
).values_list("object_id", flat=True)
|
265
|
+
favorites_count = self.queryset.filter(pk__in=favorite_store_ids).count()
|
266
|
+
data = {
|
267
|
+
"previous_count": previous_count,
|
268
|
+
"nearby_count": nearby_count,
|
269
|
+
"favorites_count": favorites_count,
|
270
|
+
}
|
271
|
+
return Response(data, status=status.HTTP_200_OK)
|
272
|
+
|
247
273
|
|
248
274
|
class CartView(
|
249
275
|
mixins.RetrieveModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet
|
@@ -293,6 +319,7 @@ class CartItemView(
|
|
293
319
|
permissions.IsAuthenticated,
|
294
320
|
]
|
295
321
|
queryset = CartItem.objects.all()
|
322
|
+
lookup_value_regex = "[0-9]+"
|
296
323
|
|
297
324
|
@swagger_auto_schema(
|
298
325
|
operation_summary="Retrieve Cart Item",
|
@@ -522,10 +549,12 @@ class ProductView(
|
|
522
549
|
queryset = self.queryset.filter(pk__in=favorite_product_ids)
|
523
550
|
return queryset
|
524
551
|
|
525
|
-
def
|
526
|
-
|
527
|
-
|
528
|
-
|
552
|
+
def get_object(self):
|
553
|
+
|
554
|
+
instance = self.get_queryset().filter(pk=self.kwargs["pk"]).distinct().first()
|
555
|
+
if not instance:
|
556
|
+
raise Http404("No Product matches the given query.")
|
557
|
+
return instance
|
529
558
|
|
530
559
|
@swagger_auto_schema(
|
531
560
|
operation_summary="Retrieve A Product",
|
@@ -624,6 +653,41 @@ class CategoryViewSet(
|
|
624
653
|
permission_classes = (permissions.AllowAny,)
|
625
654
|
queryset = Category.objects.active()
|
626
655
|
filterset_class = CategoryFilter
|
656
|
+
lookup_value_regex = "[0-9]+"
|
657
|
+
|
658
|
+
def get_queryset(self):
|
659
|
+
return super().get_queryset().prefetch_related("products__images")
|
660
|
+
|
661
|
+
def get_object(self):
|
662
|
+
store_id = self.request.query_params.get("store", None)
|
663
|
+
instance_pk = self.kwargs["pk"]
|
664
|
+
if not store_id:
|
665
|
+
return get_object_or_404(Category, pk=instance_pk, is_active=True)
|
666
|
+
try:
|
667
|
+
product_queryset = Product.objects.filter(
|
668
|
+
product_variants__inventories__store=store_id,
|
669
|
+
is_active=True,
|
670
|
+
)
|
671
|
+
instance = self.queryset.prefetch_related(
|
672
|
+
Prefetch(
|
673
|
+
"subcategories",
|
674
|
+
queryset=Category.objects.filter(
|
675
|
+
products__product_variants__inventories__store=store_id
|
676
|
+
).distinct(),
|
677
|
+
),
|
678
|
+
Prefetch(
|
679
|
+
"subcategories__products",
|
680
|
+
queryset=product_queryset.distinct(),
|
681
|
+
),
|
682
|
+
Prefetch(
|
683
|
+
"products",
|
684
|
+
queryset=product_queryset.distinct(),
|
685
|
+
),
|
686
|
+
"subcategories__products__images",
|
687
|
+
).get(pk=instance_pk)
|
688
|
+
except Category.DoesNotExist:
|
689
|
+
raise Http404("No Category matches the given query.")
|
690
|
+
return instance
|
627
691
|
|
628
692
|
@method_decorator(
|
629
693
|
name="retrieve",
|
@@ -698,7 +762,7 @@ class TransactionsViewSet(
|
|
698
762
|
def get_queryset(self):
|
699
763
|
return Payment.objects.filter(
|
700
764
|
user=self.request.user, status=Payment.PaymentStatus.SUCCESS.value
|
701
|
-
).order_by("payment_post_at")
|
765
|
+
).order_by("-payment_post_at")
|
702
766
|
|
703
767
|
@swagger_auto_schema(
|
704
768
|
operation_summary="List Users's Captured Transactions",
|
@@ -721,14 +785,9 @@ class PaymentMethodViewSet(
|
|
721
785
|
permission_classes = [
|
722
786
|
permissions.IsAuthenticated,
|
723
787
|
]
|
724
|
-
queryset = PaymentMethod.objects.
|
725
|
-
|
726
|
-
|
727
|
-
try:
|
728
|
-
store = Store.objects.get(pk=self.kwargs["store_pk"])
|
729
|
-
except ObjectDoesNotExist:
|
730
|
-
raise ValidationError(_(f"Store does not Exist"))
|
731
|
-
return store.payment_methods.filter(is_active=True)
|
788
|
+
queryset = PaymentMethod.objects.filter(is_active=True)
|
789
|
+
filterset_class = PaymentMethodFilter
|
790
|
+
lookup_value_regex = "[0-9]+"
|
732
791
|
|
733
792
|
@swagger_auto_schema(
|
734
793
|
operation_summary="List Payment Methods",
|
@@ -870,3 +929,84 @@ class FavoriteViewSet(
|
|
870
929
|
)
|
871
930
|
def destroy(self, request, *args, **kwargs):
|
872
931
|
return super().destroy(request, *args, **kwargs)
|
932
|
+
|
933
|
+
|
934
|
+
class WalletViewSet(
|
935
|
+
mixins.ListModelMixin,
|
936
|
+
mixins.RetrieveModelMixin,
|
937
|
+
mixins.UpdateModelMixin,
|
938
|
+
viewsets.GenericViewSet,
|
939
|
+
):
|
940
|
+
queryset = Wallet.objects.all()
|
941
|
+
serializer_class = WalletSerializer
|
942
|
+
permission_classes = [
|
943
|
+
permissions.IsAuthenticated,
|
944
|
+
]
|
945
|
+
|
946
|
+
def get_queryset(self):
|
947
|
+
return Wallet.objects.filter(user=self.request.user)
|
948
|
+
|
949
|
+
@swagger_auto_schema(
|
950
|
+
operation_summary="Get User Wallet",
|
951
|
+
operation_description="""
|
952
|
+
Get User Wallet
|
953
|
+
""",
|
954
|
+
tags=[
|
955
|
+
"Wallet",
|
956
|
+
],
|
957
|
+
)
|
958
|
+
def retrieve(
|
959
|
+
self, request: Request, *args: typing.Any, **kwargs: typing.Any
|
960
|
+
) -> Response:
|
961
|
+
return super().retrieve(request=request, *args, **kwargs)
|
962
|
+
|
963
|
+
@swagger_auto_schema(
|
964
|
+
operation_summary="Update user wallet",
|
965
|
+
operation_description="""
|
966
|
+
Update a wallet
|
967
|
+
""",
|
968
|
+
tags=[
|
969
|
+
"Wallet",
|
970
|
+
],
|
971
|
+
)
|
972
|
+
def partial_update(self, request: Request, *args: typing.Any, **kwargs: typing.Any):
|
973
|
+
return super().partial_update(request, *args, **kwargs)
|
974
|
+
|
975
|
+
@swagger_auto_schema(
|
976
|
+
operation_summary="List User Wallets",
|
977
|
+
operation_description="""
|
978
|
+
List User Wallets
|
979
|
+
""",
|
980
|
+
tags=[
|
981
|
+
"Wallet",
|
982
|
+
],
|
983
|
+
)
|
984
|
+
def list(
|
985
|
+
self, request: Request, *args: typing.Any, **kwargs: typing.Any
|
986
|
+
) -> Response:
|
987
|
+
return super().list(request=request, *args, **kwargs)
|
988
|
+
|
989
|
+
@swagger_auto_schema(
|
990
|
+
operation_summary="top up a wallet",
|
991
|
+
operation_description="""
|
992
|
+
top up a user wallet with tap payment
|
993
|
+
""",
|
994
|
+
tags=[
|
995
|
+
"Wallet",
|
996
|
+
],
|
997
|
+
)
|
998
|
+
@action(
|
999
|
+
methods=["POST"],
|
1000
|
+
detail=True,
|
1001
|
+
url_path="top-up",
|
1002
|
+
url_name="top-up",
|
1003
|
+
serializer_class=WalletTopUpSerializer,
|
1004
|
+
)
|
1005
|
+
def top_up_wallet(
|
1006
|
+
self, request: Request, *args: typing.Any, **kwargs: typing.Any
|
1007
|
+
) -> Response:
|
1008
|
+
serializer = self.get_serializer(data=request.data)
|
1009
|
+
serializer.is_valid(raise_exception=True)
|
1010
|
+
instance = self.get_object()
|
1011
|
+
payment_url = serializer.top_up_wallet(instance)
|
1012
|
+
return Response({"payment_url": payment_url}, status=status.HTTP_200_OK)
|
ob_dj_store/core/stores/admin.py
CHANGED
@@ -99,7 +99,6 @@ class CategoryAdmin(admin.ModelAdmin):
|
|
99
99
|
list_display = ["name", "is_active", "parent", "image"]
|
100
100
|
search_fields = [
|
101
101
|
"name",
|
102
|
-
"parent__name",
|
103
102
|
]
|
104
103
|
list_filter = [
|
105
104
|
"is_active",
|
@@ -117,6 +116,9 @@ class ProductVariantAdmin(admin.ModelAdmin):
|
|
117
116
|
]
|
118
117
|
search_fields = ["name", "product__name", "sku"]
|
119
118
|
|
119
|
+
def get_queryset(self, request):
|
120
|
+
return super().get_queryset(request).prefetch_related("inventories")
|
121
|
+
|
120
122
|
|
121
123
|
class ProductAdmin(admin.ModelAdmin):
|
122
124
|
list_display = ["id", "name", "category", "type", "is_active"]
|
@@ -221,7 +223,7 @@ class PaymentAdmin(admin.ModelAdmin):
|
|
221
223
|
"method__payment_provider",
|
222
224
|
"status",
|
223
225
|
]
|
224
|
-
search_fields = ["
|
226
|
+
search_fields = ["orders__store__name", "user__email"]
|
225
227
|
|
226
228
|
|
227
229
|
class InventoryAdmin(admin.ModelAdmin):
|
@@ -244,6 +246,9 @@ class InventoryAdmin(admin.ModelAdmin):
|
|
244
246
|
"is_uncountable",
|
245
247
|
]
|
246
248
|
|
249
|
+
def get_queryset(self, request):
|
250
|
+
return super().get_queryset(request).prefetch_related("store")
|
251
|
+
|
247
252
|
|
248
253
|
class TaxAdmin(admin.ModelAdmin):
|
249
254
|
list_display = [
|
@@ -272,7 +277,7 @@ class WalletTransactionAdmin(admin.ModelAdmin):
|
|
272
277
|
"type",
|
273
278
|
]
|
274
279
|
search_fields = [
|
275
|
-
"
|
280
|
+
"wallet__user__email",
|
276
281
|
]
|
277
282
|
|
278
283
|
|
@@ -22,10 +22,10 @@ class InventoryInlineAdmin(admin.TabularInline):
|
|
22
22
|
extra = 1
|
23
23
|
|
24
24
|
def get_queryset(self, request):
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
"variant",
|
25
|
+
return (
|
26
|
+
super()
|
27
|
+
.get_queryset(request)
|
28
|
+
.select_related("variant", "store", "variant__product")
|
29
29
|
)
|
30
30
|
|
31
31
|
|
@@ -32,7 +32,7 @@ def initiate_payment(
|
|
32
32
|
callback_url = f"{settings.WEBSITE_URI}{callback_path}"
|
33
33
|
|
34
34
|
payload = {
|
35
|
-
"amount": "%.3f" % payment.
|
35
|
+
"amount": "%.3f" % payment.total_payment,
|
36
36
|
"currency": currency_code,
|
37
37
|
"source": {"id": source},
|
38
38
|
"customer": {
|
@@ -59,15 +59,15 @@ def initiate_payment(
|
|
59
59
|
url=f"{settings.TAP_API_URL}{url}", method=method, data=payload, headers=headers
|
60
60
|
)
|
61
61
|
tap_response = response.json()
|
62
|
-
|
62
|
+
payment_transaction = tap_response.get("transaction", None)
|
63
63
|
charge_id = tap_response.get("id")
|
64
|
-
if not
|
64
|
+
if not payment_transaction or not charge_id:
|
65
65
|
# TODO: How does this issue occur and is this the best way to handle it?
|
66
66
|
logger.error(
|
67
67
|
f"Failed to create charge request no payment_url or charge_id returned."
|
68
68
|
)
|
69
69
|
raise TapException(payload)
|
70
|
-
|
70
|
+
payment_url = payment_transaction.get("url")
|
71
71
|
status = tap_response.get("status")
|
72
72
|
source = tap_response.get("source").get("id") if source else ""
|
73
73
|
|
@@ -6,7 +6,6 @@ from django.db import models
|
|
6
6
|
from django.utils.translation import gettext_lazy as _
|
7
7
|
|
8
8
|
from config import settings
|
9
|
-
from ob_dj_store.core.stores.utils import get_country_by_currency
|
10
9
|
|
11
10
|
|
12
11
|
class ActiveMixin:
|
@@ -48,11 +47,15 @@ class PaymentMethodManager(ActiveMixin, models.Manager):
|
|
48
47
|
|
49
48
|
|
50
49
|
class PaymentManager(models.Manager):
|
51
|
-
def create(self, *args: typing.Any, **kwargs: typing.Any):
|
50
|
+
def create(self, currency: str, *args: typing.Any, **kwargs: typing.Any):
|
52
51
|
from ob_dj_store.core.stores.gateway.tap.models import TapPayment
|
53
52
|
from ob_dj_store.core.stores.models import Tax, WalletTransaction
|
54
53
|
|
55
|
-
orders = kwargs.pop("orders",
|
54
|
+
orders = kwargs.pop("orders", None)
|
55
|
+
if not orders:
|
56
|
+
raise ValidationError(
|
57
|
+
{"order", _("You cannot perform payment without items")}
|
58
|
+
)
|
56
59
|
try:
|
57
60
|
kwargs["payment_tax"] = Tax.objects.get(is_active=True)
|
58
61
|
except ObjectDoesNotExist:
|
@@ -61,7 +64,7 @@ class PaymentManager(models.Manager):
|
|
61
64
|
method = kwargs.get("method", None)
|
62
65
|
if method:
|
63
66
|
gateway = method.payment_provider
|
64
|
-
instance: "models.Payment" = super().create(*args, **kwargs)
|
67
|
+
instance: "models.Payment" = super().create(currency=currency, *args, **kwargs)
|
65
68
|
instance.orders.set(orders)
|
66
69
|
if gateway in [settings.TAP_CREDIT_CARD, settings.TAP_KNET, settings.TAP_ALL]:
|
67
70
|
source = gateway
|
@@ -73,8 +76,7 @@ class PaymentManager(models.Manager):
|
|
73
76
|
return instance
|
74
77
|
elif gateway == settings.WALLET:
|
75
78
|
try:
|
76
|
-
|
77
|
-
wallet = kwargs["user"].wallets.get(country=country)
|
79
|
+
wallet = kwargs["user"].wallets.get(currency=currency)
|
78
80
|
except ObjectDoesNotExist:
|
79
81
|
raise ValidationError({"wallet": _("Wallet Not Found")})
|
80
82
|
WalletTransaction.objects.create(
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Generated by Django 3.1.14 on 2023-02-13 19:24
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
|
5
|
+
import ob_dj_store.utils.helpers
|
6
|
+
|
7
|
+
|
8
|
+
class Migration(migrations.Migration):
|
9
|
+
|
10
|
+
dependencies = [
|
11
|
+
("stores", "0055_store_image"),
|
12
|
+
]
|
13
|
+
|
14
|
+
operations = [
|
15
|
+
migrations.AddField(
|
16
|
+
model_name="category",
|
17
|
+
name="image_thumbnail",
|
18
|
+
field=models.ImageField(
|
19
|
+
blank=True,
|
20
|
+
null=True,
|
21
|
+
upload_to=ob_dj_store.utils.helpers.category_media_upload_to,
|
22
|
+
),
|
23
|
+
),
|
24
|
+
migrations.AddField(
|
25
|
+
model_name="productmedia",
|
26
|
+
name="image_thumbnail",
|
27
|
+
field=models.ImageField(
|
28
|
+
blank=True,
|
29
|
+
null=True,
|
30
|
+
upload_to=ob_dj_store.utils.helpers.product_media_upload_to,
|
31
|
+
),
|
32
|
+
),
|
33
|
+
]
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Generated by Django 3.1.14 on 2023-02-14 14:24
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
|
5
|
+
|
6
|
+
class Migration(migrations.Migration):
|
7
|
+
|
8
|
+
dependencies = [
|
9
|
+
("stores", "0056_auto_20230213_2224"),
|
10
|
+
]
|
11
|
+
|
12
|
+
operations = [
|
13
|
+
migrations.AddField(
|
14
|
+
model_name="productattribute",
|
15
|
+
name="max",
|
16
|
+
field=models.PositiveSmallIntegerField(default=1),
|
17
|
+
),
|
18
|
+
migrations.AddField(
|
19
|
+
model_name="productattribute",
|
20
|
+
name="min",
|
21
|
+
field=models.PositiveSmallIntegerField(default=1),
|
22
|
+
),
|
23
|
+
migrations.AlterField(
|
24
|
+
model_name="productattribute",
|
25
|
+
name="type",
|
26
|
+
field=models.CharField(
|
27
|
+
choices=[
|
28
|
+
("ONE_CHOICE", "one choice"),
|
29
|
+
("MULTIPLE_CHOICES", "multiple choices"),
|
30
|
+
("LIST_CHOICES", "list choices"),
|
31
|
+
("INCREMENT_CHOICE", "increment choice"),
|
32
|
+
],
|
33
|
+
default="ONE_CHOICE",
|
34
|
+
max_length=32,
|
35
|
+
),
|
36
|
+
),
|
37
|
+
]
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Generated by Django 3.2.8 on 2023-02-17 12:43
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
|
5
|
+
|
6
|
+
class Migration(migrations.Migration):
|
7
|
+
|
8
|
+
dependencies = [
|
9
|
+
("stores", "0057_auto_20230214_1724"),
|
10
|
+
]
|
11
|
+
|
12
|
+
operations = [
|
13
|
+
migrations.AddField(
|
14
|
+
model_name="attributechoice",
|
15
|
+
name="is_default",
|
16
|
+
field=models.BooleanField(default=False),
|
17
|
+
),
|
18
|
+
]
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Generated by Django 3.2.8 on 2023-02-17 17:06
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
|
5
|
+
|
6
|
+
class Migration(migrations.Migration):
|
7
|
+
|
8
|
+
dependencies = [
|
9
|
+
("stores", "0058_attributechoice_is_default"),
|
10
|
+
]
|
11
|
+
|
12
|
+
operations = [
|
13
|
+
migrations.RemoveField(
|
14
|
+
model_name="category",
|
15
|
+
name="image_thumbnail",
|
16
|
+
),
|
17
|
+
migrations.RemoveField(
|
18
|
+
model_name="productmedia",
|
19
|
+
name="image_thumbnail",
|
20
|
+
),
|
21
|
+
migrations.AddField(
|
22
|
+
model_name="category",
|
23
|
+
name="image_thumbnail_medium",
|
24
|
+
field=models.ImageField(blank=True, null=True, upload_to="category_media/"),
|
25
|
+
),
|
26
|
+
migrations.AddField(
|
27
|
+
model_name="category",
|
28
|
+
name="image_thumbnail_small",
|
29
|
+
field=models.ImageField(blank=True, null=True, upload_to="category_media/"),
|
30
|
+
),
|
31
|
+
migrations.AddField(
|
32
|
+
model_name="productmedia",
|
33
|
+
name="image_thumbnail_medium",
|
34
|
+
field=models.ImageField(blank=True, null=True, upload_to="product_media/"),
|
35
|
+
),
|
36
|
+
migrations.AddField(
|
37
|
+
model_name="productmedia",
|
38
|
+
name="image_thumbnail_small",
|
39
|
+
field=models.ImageField(blank=True, null=True, upload_to="product_media/"),
|
40
|
+
),
|
41
|
+
]
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Generated by Django 3.2.8 on 2023-02-22 16:56
|
2
|
+
|
3
|
+
import django.db.models.deletion
|
4
|
+
from django.db import migrations, models
|
5
|
+
|
6
|
+
|
7
|
+
class Migration(migrations.Migration):
|
8
|
+
|
9
|
+
dependencies = [
|
10
|
+
("stores", "0059_auto_20230217_2006"),
|
11
|
+
]
|
12
|
+
|
13
|
+
operations = [
|
14
|
+
migrations.AlterField(
|
15
|
+
model_name="orderitem",
|
16
|
+
name="product_variant",
|
17
|
+
field=models.ForeignKey(
|
18
|
+
null=True,
|
19
|
+
on_delete=django.db.models.deletion.PROTECT,
|
20
|
+
related_name="order_items",
|
21
|
+
to="stores.productvariant",
|
22
|
+
),
|
23
|
+
),
|
24
|
+
]
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Generated by Django 3.2.8 on 2023-02-23 11:35
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
|
5
|
+
|
6
|
+
class Migration(migrations.Migration):
|
7
|
+
|
8
|
+
dependencies = [
|
9
|
+
("stores", "0060_alter_orderitem_product_variant"),
|
10
|
+
]
|
11
|
+
|
12
|
+
operations = [
|
13
|
+
migrations.AddField(
|
14
|
+
model_name="attributechoice",
|
15
|
+
name="label",
|
16
|
+
field=models.CharField(blank=True, max_length=200, null=True),
|
17
|
+
),
|
18
|
+
migrations.AddField(
|
19
|
+
model_name="productattribute",
|
20
|
+
name="label",
|
21
|
+
field=models.CharField(blank=True, max_length=200, null=True),
|
22
|
+
),
|
23
|
+
migrations.AlterField(
|
24
|
+
model_name="product",
|
25
|
+
name="name",
|
26
|
+
field=models.CharField(help_text="Name", max_length=200, unique=True),
|
27
|
+
),
|
28
|
+
]
|