ob-dj-store 0.0.21.1__py3-none-any.whl → 0.0.21.3__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.
@@ -1,3 +1,5 @@
1
+ from urllib.parse import unquote
2
+
1
3
  from django.contrib.contenttypes.models import ContentType
2
4
  from django.contrib.postgres.search import SearchVector
3
5
  from django.db.models import Prefetch, Q
@@ -101,10 +103,16 @@ class ProductFilter(filters.FilterSet):
101
103
  return queryset.filter(category__name__iexact=value)
102
104
 
103
105
  def filter_search(self, queryset, name, value):
104
- print("q filter :", value)
105
- return queryset.filter(
106
- Q(name__icontains=value) | Q(description__icontains=value)
107
- ).distinct()[:5]
106
+ language = self.request.META.get("HTTP_LANGUAGE", "").strip().upper()
107
+ if language == "AR":
108
+ value_ar = unquote(value)
109
+ query = Q(name_arabic__icontains=value_ar) | Q(
110
+ description_arabic__icontains=value_ar
111
+ )
112
+ else:
113
+ query = Q(name__icontains=value) | Q(description__icontains=value)
114
+ qs = queryset.filter(query).distinct()[:5]
115
+ return qs
108
116
 
109
117
 
110
118
  class VariantFilter(filters.FilterSet):
@@ -947,6 +947,44 @@ class ProductSerializer(ArabicFieldsMixin, FavoriteMixin, serializers.ModelSeria
947
947
  return data
948
948
 
949
949
 
950
+ class ProductSearchSerializer(
951
+ ArabicFieldsMixin, FavoriteMixin, serializers.ModelSerializer
952
+ ):
953
+ is_snoozed = serializers.SerializerMethodField()
954
+ is_available = serializers.SerializerMethodField()
955
+
956
+ class Meta:
957
+ model = Product
958
+ fields = (
959
+ "id",
960
+ "name",
961
+ "name_arabic",
962
+ "slug",
963
+ "description",
964
+ "description_arabic",
965
+ "is_snoozed",
966
+ "is_available",
967
+ )
968
+
969
+ def get_store_id(self):
970
+ return self.context["request"].query_params.get("store")
971
+
972
+ def get_inventory_for_store(self, store_id):
973
+ if hasattr(self, "get_inventory"):
974
+ return self.get_inventory(store_id)
975
+ return None
976
+
977
+ def get_is_snoozed(self, obj):
978
+ store_id = self.get_store_id()
979
+ inventory = self.get_inventory_for_store(store_id)
980
+ return obj.is_snoozed(store_id=store_id) if inventory else False
981
+
982
+ def get_is_available(self, obj):
983
+ store_id = self.get_store_id()
984
+ inventory = self.get_inventory_for_store(store_id)
985
+ return bool(inventory and inventory.quantity)
986
+
987
+
950
988
  class ProductListSerializer(ArabicFieldsMixin, serializers.ModelSerializer):
951
989
  product_images = ProductMediaSerializer(many=True, source="images")
952
990
 
@@ -20,6 +20,7 @@ from ob_dj_store.apis.stores.views import (
20
20
  TaxViewSet,
21
21
  TransactionsViewSet,
22
22
  VariantView,
23
+ WalletV2ViewSet,
23
24
  WalletViewSet,
24
25
  )
25
26
 
@@ -43,6 +44,7 @@ router.register(r"cart", CartView, basename="cart")
43
44
  router.register(r"cart-item", CartItemView, basename="cart-item")
44
45
  router.register(r"favorite", FavoriteViewSet, basename="favorite")
45
46
  router.register(r"wallet", WalletViewSet, basename="wallet")
47
+ router.register(r"wallet_v2", WalletV2ViewSet, basename="wallet_v2")
46
48
  router.register(r"payment-method", PaymentMethodViewSet, basename="payment-method")
47
49
  router.register(r"order", ReorderViewSet, basename="re-order")
48
50
  router.register(r"partner/auth", PartnerAuthInfoViewSet, basename="auth")
@@ -51,6 +51,7 @@ from ob_dj_store.apis.stores.rest.serializers.serializers import (
51
51
  PaymentMethodSerializer,
52
52
  PaymentSerializer,
53
53
  ProductListSerializer,
54
+ ProductSearchSerializer,
54
55
  ProductSerializer,
55
56
  ProductVariantSerializer,
56
57
  ReorderSerializer,
@@ -61,6 +62,7 @@ from ob_dj_store.apis.stores.rest.serializers.serializers import (
61
62
  WalletSerializer,
62
63
  WalletTopUpSerializer,
63
64
  WalletTransactionListSerializer,
65
+ WalletTransactionSerializer,
64
66
  )
65
67
  from ob_dj_store.core.stores.gateway.tap.utils import TapException
66
68
  from ob_dj_store.core.stores.models import (
@@ -575,6 +577,11 @@ class ProductView(
575
577
  filterset_class = ProductFilter
576
578
  queryset = Product.objects.active()
577
579
 
580
+ def get_serializer_class(self):
581
+ if self.request.query_params.get("q"):
582
+ return ProductSearchSerializer
583
+ return ProductSerializer
584
+
578
585
  def apply_prefetch(self, queryset):
579
586
 
580
587
  qs = queryset.prefetch_related(
@@ -1103,13 +1110,19 @@ class WalletViewSet(
1103
1110
  methods=["GET"],
1104
1111
  detail=True,
1105
1112
  url_path="transactions",
1106
- serializer_class=WalletTransactionListSerializer,
1113
+ serializer_class=WalletTransactionSerializer,
1107
1114
  )
1108
- def transactions(self, request, *args, **kwargs):
1109
- wallet = self.get_object()
1110
- queryset = wallet.transactions.all().order_by("-created_at")
1111
- serializer = WalletTransactionListSerializer(queryset, many=True)
1112
- return Response({"results": serializer.data})
1115
+ def transactions(
1116
+ self, request: Request, *args: typing.Any, **kwargs: typing.Any
1117
+ ) -> Response:
1118
+ queryset = self.get_object().transactions.all().order_by("-created_at")
1119
+ page = self.paginate_queryset(queryset)
1120
+ if page is not None:
1121
+ serializer = self.get_serializer(page, many=True)
1122
+ return self.get_paginated_response(serializer.data)
1123
+
1124
+ serializer = self.get_serializer(queryset, many=True)
1125
+ return Response(serializer.data)
1113
1126
 
1114
1127
  @swagger_auto_schema(
1115
1128
  operation_summary="List Wallet selection images",
@@ -1137,6 +1150,34 @@ class WalletViewSet(
1137
1150
  return Response(serializer.data)
1138
1151
 
1139
1152
 
1153
+ class WalletV2ViewSet(
1154
+ mixins.ListModelMixin, viewsets.GenericViewSet,
1155
+ ):
1156
+ def get_queryset(self):
1157
+ return Wallet.objects.filter(
1158
+ user=self.request.user, is_active=True
1159
+ ).select_related("media_image")
1160
+
1161
+ @swagger_auto_schema(
1162
+ operation_summary="List Wallet's transactions",
1163
+ operation_description="""
1164
+ list user's wallet transactions(debit,credit)
1165
+ """,
1166
+ tags=["Wallet",],
1167
+ )
1168
+ @action(
1169
+ methods=["GET"],
1170
+ detail=True,
1171
+ url_path="transactions",
1172
+ serializer_class=WalletTransactionListSerializer,
1173
+ )
1174
+ def transactions(self, request, *args, **kwargs):
1175
+ wallet = self.get_object()
1176
+ queryset = wallet.transactions.all().order_by("-created_at")
1177
+ serializer = WalletTransactionListSerializer(queryset, many=True)
1178
+ return Response({"results": serializer.data})
1179
+
1180
+
1140
1181
  class PartnerAuthInfoViewSet(
1141
1182
  mixins.CreateModelMixin,
1142
1183
  mixins.RetrieveModelMixin,
@@ -248,6 +248,19 @@ class Product(DjangoModelCleanMixin, models.Model):
248
248
  def __str__(self):
249
249
  return f"Product {self.name} (PK={self.pk})"
250
250
 
251
+ def get_inventory(self, store_id):
252
+ try:
253
+ inventory = self.product_variants.inventories.get(store=store_id)
254
+ except ObjectDoesNotExist:
255
+ return None
256
+
257
+ def is_snoozed(self, store_id):
258
+ try:
259
+ inventory = self.product_variants.inventories.get(store=store_id)
260
+ except ObjectDoesNotExist:
261
+ return False
262
+ return inventory.is_snoozed
263
+
251
264
 
252
265
  # TODO: must remove, redundunt
253
266
  class Attribute(DjangoModelCleanMixin, models.Model):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ob-dj-store
3
- Version: 0.0.21.1
3
+ Version: 0.0.21.3
4
4
  Summary: OBytes django application for managing ecommerce stores.
5
5
  Home-page: https://www.obytes.com/
6
6
  Author: OBytes
@@ -1,9 +1,9 @@
1
1
  ob_dj_store/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  ob_dj_store/apis/stores/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- ob_dj_store/apis/stores/filters.py,sha256=SzGLbiRhR3XEgAYcSI-_75xcq5GIA-yqLyBifY1yeBA,10031
4
- ob_dj_store/apis/stores/urls.py,sha256=7vwogfIGcKS0hHYK3iBXKQwi1kCA_vuHY1eZt8rAspg,2021
5
- ob_dj_store/apis/stores/views.py,sha256=YCYZ3XlJLFOwhpqMU-Lvx_emJwW-0fdyEF2SXROEmNU,41405
6
- ob_dj_store/apis/stores/rest/serializers/serializers.py,sha256=mhUS1LmnZpFY5OAnGbiMBwD6zywC7tZ8vKK1bVniJTE,67087
3
+ ob_dj_store/apis/stores/filters.py,sha256=JeUtcicJ3cFnZc71aUMEwn2jaVj1oNQsZOCZfdxGDu8,10338
4
+ ob_dj_store/apis/stores/urls.py,sha256=W9sNJ7ST9pGnfVCf7GmduDO-_zK9MGTI6ybV8n-lzSc,2111
5
+ ob_dj_store/apis/stores/views.py,sha256=cwDFNY2rtTfjl_F9PpR5zOJy2DPmGidOjIlJ9fsgSYI,42744
6
+ ob_dj_store/apis/stores/rest/serializers/serializers.py,sha256=GUsUTN4MTXq92Uriv6Ql9MzjZJsSbmFDC3lZhSmB7vE,68219
7
7
  ob_dj_store/apis/tap/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  ob_dj_store/apis/tap/serializers.py,sha256=KPrBK4h2-fWvEVf6vOj2ww5-USV9WqpyYicIqoHIiXI,1065
9
9
  ob_dj_store/apis/tap/urls.py,sha256=bnOTv6an11kxpo_FdqlhsizlGPLVpNxBjCyKcf3_C9M,367
@@ -153,14 +153,14 @@ ob_dj_store/core/stores/models/_inventory.py,sha256=_rGlVL5HjOlHQVB8CI0776CPcE5r
153
153
  ob_dj_store/core/stores/models/_order.py,sha256=_08lqX5p4brCdUilqfbT--6Ao2TMsqnzXaWoV_7IYL8,9758
154
154
  ob_dj_store/core/stores/models/_partner.py,sha256=OuYvevUWn1sYHs9PcFf51EUUC1uqytQss8Bx91aMOH8,4732
155
155
  ob_dj_store/core/stores/models/_payment.py,sha256=FTV-NmvQjxwwR5C5X7qYWV-ZUIZfqMMEjkBNaS-drLs,6421
156
- ob_dj_store/core/stores/models/_product.py,sha256=E_P0BfJ5A7-aSb_8graCLOL_7PmL1JiBgqwx-mQpiM0,17825
156
+ ob_dj_store/core/stores/models/_product.py,sha256=iBSXZcZdtCXFINiOFqbnaZot9rWPkFdzySXwKJO5h6I,18239
157
157
  ob_dj_store/core/stores/models/_store.py,sha256=0K-CNJWuXNqeyULL1J0M9hiNcVla0UNNjdCdN_nzNEE,9833
158
158
  ob_dj_store/core/stores/models/_wallet.py,sha256=YvT-rvED-jrYjePLJpvdLXXoBudR6TGPu5cNE0m2fWo,5643
159
159
  ob_dj_store/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
160
160
  ob_dj_store/utils/helpers.py,sha256=o7wgypM7mI2vZqZKkhxnTcnHJC8GMQDOuYMnRwXr6tY,2058
161
161
  ob_dj_store/utils/model.py,sha256=DV7hOhTaZL3gh9sptts2jTUFlTArKG3i7oPioq9HLFE,303
162
162
  ob_dj_store/utils/utils.py,sha256=8UVAFB56qUSjJJ5f9vnermtw638gdFy4CFRCuMbns_M,1342
163
- ob_dj_store-0.0.21.1.dist-info/METADATA,sha256=tJ38YD5gc0-K0XNtvVbgpPre75gQc0wUWnG6tr-JjDs,2850
164
- ob_dj_store-0.0.21.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
165
- ob_dj_store-0.0.21.1.dist-info/top_level.txt,sha256=CZG3G0ptTkzGnc0dFYN-ZD7YKdJBmm47bsmGwofD_lk,12
166
- ob_dj_store-0.0.21.1.dist-info/RECORD,,
163
+ ob_dj_store-0.0.21.3.dist-info/METADATA,sha256=-i8CuO0fLzxvE5HZ-Vjd9gItuWICNyeg2QLrNZChBK4,2850
164
+ ob_dj_store-0.0.21.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
165
+ ob_dj_store-0.0.21.3.dist-info/top_level.txt,sha256=CZG3G0ptTkzGnc0dFYN-ZD7YKdJBmm47bsmGwofD_lk,12
166
+ ob_dj_store-0.0.21.3.dist-info/RECORD,,