ob-dj-store 0.0.11.11__py3-none-any.whl → 0.0.11.12__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.
@@ -40,6 +40,7 @@ from ob_dj_store.core.stores.models import (
40
40
  Store,
41
41
  Tax,
42
42
  Wallet,
43
+ WalletMedia,
43
44
  WalletTransaction,
44
45
  )
45
46
  from ob_dj_store.core.stores.models._inventory import Inventory
@@ -150,6 +151,7 @@ class OrderSerializer(serializers.ModelSerializer):
150
151
  items = OrderItemSerializer(many=True, read_only=True)
151
152
  history = OrderHistorySerializer(many=True, read_only=True)
152
153
  estimated_timeline = serializers.SerializerMethodField()
154
+ store_name = serializers.SerializerMethodField()
153
155
 
154
156
  class Meta:
155
157
  model = Order
@@ -172,6 +174,7 @@ class OrderSerializer(serializers.ModelSerializer):
172
174
  "extra_infos",
173
175
  "created_at",
174
176
  "updated_at",
177
+ "store_name",
175
178
  )
176
179
  extra_kwargs = {
177
180
  "customer": {"read_only": True},
@@ -202,9 +205,11 @@ class OrderSerializer(serializers.ModelSerializer):
202
205
  timeline["ready"] = timeline["delivering"] or timeline["order_ready"]
203
206
  return timeline
204
207
 
208
+ def get_store_name(self, obj):
209
+ return obj.store.name if obj.store else None
210
+
205
211
  def to_representation(self, instance):
206
212
  data = super().to_representation(instance)
207
- data["store_name"] = instance.store.name
208
213
  return data
209
214
 
210
215
  def _get_store(self):
@@ -1064,13 +1069,18 @@ class FavoriteSerializer(serializers.ModelSerializer):
1064
1069
  return favorite
1065
1070
 
1066
1071
 
1072
+ class WalletMediaSerializer(serializers.ModelSerializer):
1073
+ class Meta:
1074
+ model = WalletMedia
1075
+ fields = "__all__"
1076
+
1077
+
1067
1078
  class WalletSerializer(serializers.ModelSerializer):
1068
1079
  class Meta:
1069
1080
  model = Wallet
1070
- fields = ["id", "user", "balance", "name", "image", "image_thumbnail_medium"]
1081
+ fields = ["id", "user", "balance", "name", "media_image", "image_url"]
1071
1082
  extra_kwargs = {
1072
1083
  "user": {"read_only": True},
1073
- "image_thumbnail_medium": {"read_only": True},
1074
1084
  }
1075
1085
 
1076
1086
 
@@ -48,6 +48,7 @@ from ob_dj_store.apis.stores.rest.serializers.serializers import (
48
48
  ShippingMethodSerializer,
49
49
  StoreSerializer,
50
50
  TaxSerializer,
51
+ WalletMediaSerializer,
51
52
  WalletSerializer,
52
53
  WalletTopUpSerializer,
53
54
  WalletTransactionSerializer,
@@ -67,6 +68,7 @@ from ob_dj_store.core.stores.models import (
67
68
  Store,
68
69
  Tax,
69
70
  Wallet,
71
+ WalletMedia,
70
72
  )
71
73
  from ob_dj_store.core.stores.models._inventory import Inventory
72
74
 
@@ -945,7 +947,9 @@ class WalletViewSet(
945
947
  ]
946
948
 
947
949
  def get_queryset(self):
948
- return Wallet.objects.filter(user=self.request.user)
950
+ return Wallet.objects.filter(user=self.request.user).select_related(
951
+ "media_image"
952
+ )
949
953
 
950
954
  @swagger_auto_schema(
951
955
  operation_summary="Get User Wallet",
@@ -1040,3 +1044,32 @@ class WalletViewSet(
1040
1044
 
1041
1045
  serializer = self.get_serializer(queryset, many=True)
1042
1046
  return Response(serializer.data)
1047
+
1048
+ @swagger_auto_schema(
1049
+ operation_summary="List Wallet selection images",
1050
+ operation_description="""
1051
+ list wallet selection images
1052
+ """,
1053
+ tags=[
1054
+ "Wallet",
1055
+ ],
1056
+ )
1057
+ @action(
1058
+ methods=[
1059
+ "GET",
1060
+ ],
1061
+ detail=False,
1062
+ url_path="images",
1063
+ serializer_class=WalletMediaSerializer,
1064
+ )
1065
+ def images(
1066
+ self, request: Request, *args: typing.Any, **kwargs: typing.Any
1067
+ ) -> Response:
1068
+ queryset = WalletMedia.objects.filter(is_active=True)
1069
+ page = self.paginate_queryset(queryset)
1070
+ if page is not None:
1071
+ serializer = self.get_serializer(page, many=True)
1072
+ return self.get_paginated_response(serializer.data)
1073
+
1074
+ serializer = self.get_serializer(queryset, many=True)
1075
+ return Response(serializer.data)
@@ -288,6 +288,10 @@ class WalletAdmin(admin.ModelAdmin):
288
288
  ]
289
289
 
290
290
 
291
+ class WalletMediaAdmin(admin.ModelAdmin):
292
+ list_display = ("id", "image", "image_thumbnail_medium", "is_active")
293
+
294
+
291
295
  admin.site.register(models.Store, StoreAdmin)
292
296
  admin.site.register(models.ShippingMethod, ShippingMethodAdmin)
293
297
  admin.site.register(models.PaymentMethod, PaymentMethodAdmin)
@@ -305,3 +309,4 @@ admin.site.register(models.Inventory, InventoryAdmin)
305
309
  admin.site.register(models.Tax, TaxAdmin)
306
310
  admin.site.register(models.WalletTransaction, WalletTransactionAdmin)
307
311
  admin.site.register(models.Wallet, WalletAdmin)
312
+ admin.site.register(models.WalletMedia, WalletMediaAdmin)
@@ -0,0 +1,64 @@
1
+ # Generated by Django 3.2.8 on 2023-03-04 12:32
2
+
3
+ import django.db.models.deletion
4
+ from django.db import migrations, models
5
+
6
+ import ob_dj_store.utils.helpers
7
+ import ob_dj_store.utils.model
8
+
9
+
10
+ class Migration(migrations.Migration):
11
+
12
+ dependencies = [
13
+ ("stores", "0065_auto_20230228_1932"),
14
+ ]
15
+
16
+ operations = [
17
+ migrations.CreateModel(
18
+ name="WalletMedia",
19
+ fields=[
20
+ (
21
+ "id",
22
+ models.AutoField(
23
+ auto_created=True,
24
+ primary_key=True,
25
+ serialize=False,
26
+ verbose_name="ID",
27
+ ),
28
+ ),
29
+ (
30
+ "image",
31
+ models.ImageField(
32
+ upload_to=ob_dj_store.utils.helpers.wallet_media_upload_to
33
+ ),
34
+ ),
35
+ (
36
+ "image_thumbnail_medium",
37
+ models.ImageField(blank=True, null=True, upload_to="wallets/"),
38
+ ),
39
+ ("is_active", models.BooleanField(default=True)),
40
+ ("created_at", models.DateTimeField(auto_now_add=True)),
41
+ ("updated_at", models.DateTimeField(auto_now=True)),
42
+ ],
43
+ bases=(ob_dj_store.utils.model.DjangoModelCleanMixin, models.Model),
44
+ ),
45
+ migrations.RemoveField(
46
+ model_name="wallet",
47
+ name="image",
48
+ ),
49
+ migrations.RemoveField(
50
+ model_name="wallet",
51
+ name="image_thumbnail_medium",
52
+ ),
53
+ migrations.AddField(
54
+ model_name="wallet",
55
+ name="media_image",
56
+ field=models.ForeignKey(
57
+ blank=True,
58
+ null=True,
59
+ on_delete=django.db.models.deletion.SET_NULL,
60
+ related_name="wallets",
61
+ to="stores.walletmedia",
62
+ ),
63
+ ),
64
+ ]
@@ -26,7 +26,11 @@ from ob_dj_store.core.stores.models._store import (
26
26
  ShippingMethod,
27
27
  Store,
28
28
  )
29
- from ob_dj_store.core.stores.models._wallet import Wallet, WalletTransaction
29
+ from ob_dj_store.core.stores.models._wallet import (
30
+ Wallet,
31
+ WalletMedia,
32
+ WalletTransaction,
33
+ )
30
34
 
31
35
  __all__ = [
32
36
  "Store",
@@ -60,4 +64,5 @@ __all__ = [
60
64
  "WalletTransaction",
61
65
  "Wallet",
62
66
  "FavoriteExtra",
67
+ "WalletMedia",
63
68
  ]
@@ -11,10 +11,27 @@ from ob_dj_store.core.stores.managers import WalletTransactionManager
11
11
  from ob_dj_store.core.stores.models._store import PaymentMethod
12
12
  from ob_dj_store.core.stores.utils import validate_currency
13
13
  from ob_dj_store.utils.helpers import wallet_media_upload_to
14
+ from ob_dj_store.utils.model import DjangoModelCleanMixin
14
15
 
15
16
  logger = logging.getLogger(__name__)
16
17
 
17
18
 
19
+ class WalletMedia(DjangoModelCleanMixin, models.Model):
20
+ """
21
+ selection images for wallets.
22
+ """
23
+
24
+ image = models.ImageField(upload_to=wallet_media_upload_to)
25
+ image_thumbnail_medium = models.ImageField(
26
+ upload_to="wallets/", null=True, blank=True
27
+ )
28
+ is_active = models.BooleanField(default=True)
29
+
30
+ # Audit fields
31
+ created_at = models.DateTimeField(auto_now_add=True)
32
+ updated_at = models.DateTimeField(auto_now=True)
33
+
34
+
18
35
  class Wallet(models.Model):
19
36
  user = models.ForeignKey(
20
37
  settings.AUTH_USER_MODEL,
@@ -22,9 +39,12 @@ class Wallet(models.Model):
22
39
  related_name="wallets",
23
40
  )
24
41
  name = models.CharField(max_length=200, null=True, blank=True)
25
- image = models.ImageField(upload_to=wallet_media_upload_to, null=True, blank=True)
26
- image_thumbnail_medium = models.ImageField(
27
- upload_to="wallets/", null=True, blank=True
42
+ media_image = models.ForeignKey(
43
+ WalletMedia,
44
+ on_delete=models.SET_NULL,
45
+ null=True,
46
+ blank=True,
47
+ related_name="wallets",
28
48
  )
29
49
  currency = models.CharField(
30
50
  max_length=3,
@@ -63,6 +83,12 @@ class Wallet(models.Model):
63
83
  )
64
84
  return query["balance"]
65
85
 
86
+ @property
87
+ def image_url(self):
88
+ if self.media_image:
89
+ image = self.media_image.image_thumbnail_medium
90
+ return image.url if image else None
91
+
66
92
  def top_up_wallet(self, amount: Decimal, payment_method: PaymentMethod):
67
93
  from ob_dj_store.core.stores.models import Order, Payment
68
94
 
@@ -9,7 +9,7 @@ from ob_dj_store.core.stores.models import (
9
9
  Order,
10
10
  OrderHistory,
11
11
  ProductMedia,
12
- Wallet,
12
+ WalletMedia,
13
13
  )
14
14
  from ob_dj_store.utils.utils import resize_image
15
15
 
@@ -95,7 +95,7 @@ def create_product_media_thumbnails(sender, instance, **kwargs):
95
95
 
96
96
  @receiver(
97
97
  pre_save,
98
- sender=Wallet,
98
+ sender=WalletMedia,
99
99
  dispatch_uid="create_wallet_thumbnails",
100
100
  )
101
101
  def create_wallet_thumbnails(sender, instance, **kwargs):
@@ -105,5 +105,4 @@ def create_wallet_thumbnails(sender, instance, **kwargs):
105
105
  instance.image,
106
106
  dim=medium_dim,
107
107
  size_name="medium",
108
- image_name=f"{instance.currency}_{instance.user.username}",
109
108
  )
@@ -35,6 +35,6 @@ def store_media_upload_to(instance, filename):
35
35
 
36
36
 
37
37
  def wallet_media_upload_to(instance, filename):
38
- ext = filename.split(".")[-1]
38
+ image_name, ext = filename.split(".")
39
39
  if instance:
40
- return f"wallets/{instance.currency}_{instance.user.username}_{int(now().timestamp())}.{ext}"
40
+ return f"wallets/{image_name}_{int(now().timestamp())}.{ext}"
@@ -10,7 +10,7 @@ from pilkit.processors import ResizeToFill
10
10
  logger = logging.getLogger(__name__)
11
11
 
12
12
 
13
- def resize_image(image, dim: dict, size_name: str, image_name: str):
13
+ def resize_image(image, dim: dict, size_name: str, image_name: str = None):
14
14
  try:
15
15
  img = Image.open(image)
16
16
  except UnidentifiedImageError as e:
@@ -32,6 +32,8 @@ def resize_image(image, dim: dict, size_name: str, image_name: str):
32
32
  new_img = new_img.convert("RGB")
33
33
  new_img.save(output, format=img_format, quality=70)
34
34
  output.seek(0)
35
+ if not image_name:
36
+ image_name = filename
35
37
  new_image = InMemoryUploadedFile(
36
38
  output,
37
39
  "ImageField",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ob-dj-store
3
- Version: 0.0.11.11
3
+ Version: 0.0.11.12
4
4
  Summary: OBytes django application for managing ecommerce stores.
5
5
  Home-page: https://www.obytes.com/
6
6
  Author: OBytes
@@ -2,19 +2,19 @@ ob_dj_store/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
2
2
  ob_dj_store/apis/stores/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  ob_dj_store/apis/stores/filters.py,sha256=s4US_TysnIgdT8pue_1jlG3V33WhYmCymXK3DuC0rqY,5746
4
4
  ob_dj_store/apis/stores/urls.py,sha256=cPForgFpOgOGCUVAk6DZcZ7qOooMf1zpDIr1BA0L_8A,1593
5
- ob_dj_store/apis/stores/views.py,sha256=1rmtT1tHYwvo3U43gSWfjV-E4_qs6P3hqxMnPlYd-xA,30767
6
- ob_dj_store/apis/stores/rest/serializers/serializers.py,sha256=RyGNV8w1xFtD8WCqfhVzFr56d-pbyXiJpyUaEWp2SeQ,36720
5
+ ob_dj_store/apis/stores/views.py,sha256=RjibvMPfEKsKQtuuieU4UplNL2z-54ZkwDyC5J5Mbwo,31738
6
+ ob_dj_store/apis/stores/rest/serializers/serializers.py,sha256=9hPfSHj5ODbrPuePX5sT5zPXc_jNk_FTZMOsu-rEWLY,36921
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
10
10
  ob_dj_store/apis/tap/views.py,sha256=VnVquybTHlJquxsC0RNTy20dtLXalchO0SlGjSDaBng,2666
11
11
  ob_dj_store/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  ob_dj_store/core/stores/__init__.py,sha256=-izNGrxNn_nn3IQXd5pkuES9lSF-AHYb14yhNPozYCI,65
13
- ob_dj_store/core/stores/admin.py,sha256=4um-O_30xpnfcZHe_sNOyvSTnqLSbeExA2E1QppLEZQ,7354
13
+ ob_dj_store/core/stores/admin.py,sha256=xRmi6LCda27w3f4c2rIaodbTSvLLBuhOLVgmEJcUU4g,7530
14
14
  ob_dj_store/core/stores/admin_inlines.py,sha256=SLj8mMa-Sc3oP693R0W9c3Ocyk7eb34IyXbC4E6LL8M,1557
15
15
  ob_dj_store/core/stores/apps.py,sha256=i6D2lcqlluP6FwJSBpekf7BQVzQURwSy_Y97SgqWTkM,434
16
16
  ob_dj_store/core/stores/managers.py,sha256=cDr8TtPxayLwTFNgFs9I87ZXh7ssqM-yAmvEcN9a5LU,6359
17
- ob_dj_store/core/stores/receivers.py,sha256=5AYMW8ul5htJPp4gBwRAH1VyT5ugZvDMJmed2sostBM,3194
17
+ ob_dj_store/core/stores/receivers.py,sha256=gfpshRC_OjLW8dx9Y61dpakPGZkW_hV9KV9cEYH7K1w,3132
18
18
  ob_dj_store/core/stores/settings_validation.py,sha256=s9BPEdyCL2aslZwZGLAWEvJBzXlUo0p2TbC1_0E_SDo,327
19
19
  ob_dj_store/core/stores/utils.py,sha256=_FwZEIwKdfj3CuYHCz3wKqq5TBb8xak7UiiCB1oggKc,1850
20
20
  ob_dj_store/core/stores/gateway/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -94,8 +94,9 @@ ob_dj_store/core/stores/migrations/0062_auto_20230226_2005.py,sha256=ApzGG5teYcL
94
94
  ob_dj_store/core/stores/migrations/0063_alter_store_payment_methods.py,sha256=QKIrNVtjttvYn4IO1GpGkA2gX4cyqjHNbFQ7q7cQqno,571
95
95
  ob_dj_store/core/stores/migrations/0064_auto_20230228_1814.py,sha256=6fgusQrMykN_tlNBxiJqLNvrHBA0yI32JK0kQ4VfNpQ,644
96
96
  ob_dj_store/core/stores/migrations/0065_auto_20230228_1932.py,sha256=r3-ThPhh_Lf4J3tYbCLiRbLSui5VSqwaVCtzvEZes_8,919
97
+ ob_dj_store/core/stores/migrations/0066_auto_20230304_1532.py,sha256=IVOFLoaaFyRM50EBdfw9W4ixUP_F1n6LRm4zQJ9Yfaw,1977
97
98
  ob_dj_store/core/stores/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
- ob_dj_store/core/stores/models/__init__.py,sha256=1lEOqmvQlQJZj9nnObTAQqgnPP1yVGvM8H9yjglZ0VI,1568
99
+ ob_dj_store/core/stores/models/__init__.py,sha256=fNB_sn6HM6EmTp_Z-Q7KXD8HDWVjG3qlayrWqvygvbw,1617
99
100
  ob_dj_store/core/stores/models/_address.py,sha256=qS5TQ9Z12zx_4CrrHvG8PoYVkdiOq_MtbKR14WKh3Hw,1661
100
101
  ob_dj_store/core/stores/models/_cart.py,sha256=qgjg5MXTMRIZRJJDx5BQ1pa9__ylfrnYMMRGbB2R53c,4555
101
102
  ob_dj_store/core/stores/models/_favorite.py,sha256=bpXlFBNK8jsQkZG1RiDAbNTNSoVP0NOUUxZI8c46QzI,2561
@@ -105,12 +106,12 @@ ob_dj_store/core/stores/models/_order.py,sha256=qtdUpG30dZeDGeh0Z8JhzyyqQIuxTdLf
105
106
  ob_dj_store/core/stores/models/_payment.py,sha256=dCOXOYkgxOGJqp0nxEvzHmdZxR_srFUIZAhrB--SP1U,6143
106
107
  ob_dj_store/core/stores/models/_product.py,sha256=yGVp3vl5rCReG4c8ogWy2NUcsTJeqCxP0tm6lQyYx7Y,10928
107
108
  ob_dj_store/core/stores/models/_store.py,sha256=g7QXKbZI886Pdw6smuheVep7Vh1ke42PEhJhnxW4byA,7334
108
- ob_dj_store/core/stores/models/_wallet.py,sha256=4LUyWPlgRedthWij-Nkn4diYvWHU755IOBLgpjZOyQ8,3679
109
+ ob_dj_store/core/stores/models/_wallet.py,sha256=iPeS2BVbDhZcqw0Wi7tEiUgw7ihFKQvd0RK8ZaF6ZYY,4350
109
110
  ob_dj_store/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
110
- ob_dj_store/utils/helpers.py,sha256=02igVH2DSDTZYa6kFSTmBnJeXfTdgjRCRSXQ7mvmCGo,1224
111
+ ob_dj_store/utils/helpers.py,sha256=3LsbPik74hkn4T2R6cwa0x6IE9gBNK7gMQsjQsJz1uk,1200
111
112
  ob_dj_store/utils/model.py,sha256=DV7hOhTaZL3gh9sptts2jTUFlTArKG3i7oPioq9HLFE,303
112
- ob_dj_store/utils/utils.py,sha256=euWeNI39P48jGNwKoBCC5AmwQUmgDeb92t0fQtPm-5g,1282
113
- ob_dj_store-0.0.11.11.dist-info/METADATA,sha256=uObApo60WAdwyIg3mZ4_onVE7gwMSaofdhj5MIT6Cfo,2828
114
- ob_dj_store-0.0.11.11.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
115
- ob_dj_store-0.0.11.11.dist-info/top_level.txt,sha256=CZG3G0ptTkzGnc0dFYN-ZD7YKdJBmm47bsmGwofD_lk,12
116
- ob_dj_store-0.0.11.11.dist-info/RECORD,,
113
+ ob_dj_store/utils/utils.py,sha256=8UVAFB56qUSjJJ5f9vnermtw638gdFy4CFRCuMbns_M,1342
114
+ ob_dj_store-0.0.11.12.dist-info/METADATA,sha256=OVSVTQIgRyF-cfWmlfDeklAKAx3PUL-MZE8pi-CkT44,2828
115
+ ob_dj_store-0.0.11.12.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
116
+ ob_dj_store-0.0.11.12.dist-info/top_level.txt,sha256=CZG3G0ptTkzGnc0dFYN-ZD7YKdJBmm47bsmGwofD_lk,12
117
+ ob_dj_store-0.0.11.12.dist-info/RECORD,,