ob-dj-store 0.0.12.2__py3-none-any.whl → 0.0.12.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.
- ob_dj_store/apis/stores/rest/serializers/serializers.py +66 -24
- ob_dj_store/apis/stores/views.py +23 -4
- ob_dj_store/core/stores/models/_favorite.py +15 -0
- {ob_dj_store-0.0.12.2.dist-info → ob_dj_store-0.0.12.3.dist-info}/METADATA +1 -1
- {ob_dj_store-0.0.12.2.dist-info → ob_dj_store-0.0.12.3.dist-info}/RECORD +7 -7
- {ob_dj_store-0.0.12.2.dist-info → ob_dj_store-0.0.12.3.dist-info}/WHEEL +1 -1
- {ob_dj_store-0.0.12.2.dist-info → ob_dj_store-0.0.12.3.dist-info}/top_level.txt +0 -0
@@ -464,12 +464,14 @@ class CartItemSerializer(InventoryValidationMixin, serializers.ModelSerializer):
|
|
464
464
|
image = serializers.SerializerMethodField()
|
465
465
|
inventory_quantity = serializers.SerializerMethodField()
|
466
466
|
is_uncountable = serializers.SerializerMethodField()
|
467
|
+
product_id = serializers.SerializerMethodField()
|
467
468
|
|
468
469
|
class Meta:
|
469
470
|
model = CartItem
|
470
471
|
fields = (
|
471
472
|
"id",
|
472
473
|
"product_variant",
|
474
|
+
"product_id",
|
473
475
|
"quantity",
|
474
476
|
"store",
|
475
477
|
"unit_price",
|
@@ -488,6 +490,9 @@ class CartItemSerializer(InventoryValidationMixin, serializers.ModelSerializer):
|
|
488
490
|
},
|
489
491
|
}
|
490
492
|
|
493
|
+
def get_product_id(self, obj):
|
494
|
+
return obj.product_variant.product.id
|
495
|
+
|
491
496
|
def get_inventory_quantity(self, obj):
|
492
497
|
if obj.inventory:
|
493
498
|
return obj.inventory.quantity
|
@@ -980,7 +985,7 @@ def get_favorite_extras_models():
|
|
980
985
|
|
981
986
|
class FavoriteExtraSerializer(serializers.ModelSerializer):
|
982
987
|
content_object = GenericSerializer(read_only=True)
|
983
|
-
object_id = serializers.IntegerField(min_value=1
|
988
|
+
object_id = serializers.IntegerField(min_value=1)
|
984
989
|
object_type = serializers.ChoiceField(
|
985
990
|
write_only=True, choices=get_favorite_extras_models()
|
986
991
|
)
|
@@ -1008,10 +1013,13 @@ class FavoriteExtraSerializer(serializers.ModelSerializer):
|
|
1008
1013
|
class FavoriteSerializer(serializers.ModelSerializer):
|
1009
1014
|
content_object = GenericSerializer(read_only=True)
|
1010
1015
|
extras = FavoriteExtraSerializer(many=True)
|
1011
|
-
object_id = serializers.IntegerField(min_value=1,
|
1016
|
+
object_id = serializers.IntegerField(min_value=1, required=False)
|
1012
1017
|
object_type = serializers.ChoiceField(
|
1013
|
-
write_only=True,
|
1018
|
+
write_only=True,
|
1019
|
+
choices=list(store_settings.FAVORITE_TYPES.keys()),
|
1020
|
+
required=False,
|
1014
1021
|
)
|
1022
|
+
is_available_in_store = serializers.SerializerMethodField()
|
1015
1023
|
|
1016
1024
|
class Meta:
|
1017
1025
|
model = Favorite
|
@@ -1022,11 +1030,27 @@ class FavoriteSerializer(serializers.ModelSerializer):
|
|
1022
1030
|
"object_id",
|
1023
1031
|
"object_type",
|
1024
1032
|
"name",
|
1033
|
+
"is_available_in_store",
|
1025
1034
|
)
|
1026
1035
|
extra_kwargs = {
|
1027
1036
|
"name": {"required": True},
|
1028
1037
|
}
|
1029
1038
|
|
1039
|
+
def get_is_available_in_store(self, obj):
|
1040
|
+
store_id = self.context["request"].query_params.get("store")
|
1041
|
+
type = self.context["request"].query_params.get("type")
|
1042
|
+
if type == "Product" and store_id:
|
1043
|
+
content_type = ContentType.objects.get_for_model(ProductVariant)
|
1044
|
+
try:
|
1045
|
+
extra = obj.extras.get(content_type=content_type)
|
1046
|
+
inventory = extra.content_object.inventories.get(store=store_id)
|
1047
|
+
if inventory.is_uncountable:
|
1048
|
+
return True
|
1049
|
+
return inventory.quantity > 0
|
1050
|
+
except ObjectDoesNotExist:
|
1051
|
+
return False
|
1052
|
+
return None
|
1053
|
+
|
1030
1054
|
def to_representation(self, instance):
|
1031
1055
|
data = super().to_representation(instance)
|
1032
1056
|
model_name = instance.content_type.model
|
@@ -1043,18 +1067,18 @@ class FavoriteSerializer(serializers.ModelSerializer):
|
|
1043
1067
|
object_id=data["content_object"].id,
|
1044
1068
|
user=self.context["request"].user,
|
1045
1069
|
).prefetch_related("extras")
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1070
|
+
if self.instance:
|
1071
|
+
queryset = queryset.exclude(pk=self.instance.pk)
|
1072
|
+
|
1073
|
+
if queryset.exists():
|
1074
|
+
for favorite in queryset:
|
1075
|
+
content_objects = [
|
1076
|
+
instance.content_object for instance in favorite.extras.all()
|
1077
|
+
]
|
1078
|
+
if set(data["extras"]) == set(content_objects):
|
1079
|
+
raise serializers.ValidationError(
|
1080
|
+
_(f"You cannot favorite the same item twice")
|
1081
|
+
)
|
1058
1082
|
|
1059
1083
|
def get_object(self, model: models.Model, id: int):
|
1060
1084
|
try:
|
@@ -1068,14 +1092,22 @@ class FavoriteSerializer(serializers.ModelSerializer):
|
|
1068
1092
|
def validate(self, attrs):
|
1069
1093
|
validated_data = super().validate(attrs)
|
1070
1094
|
extras_data = {}
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1095
|
+
if self.instance is None:
|
1096
|
+
object_type = validated_data["object_type"]
|
1097
|
+
object_type_model = import_string(
|
1098
|
+
store_settings.FAVORITE_TYPES[object_type]["path"]
|
1099
|
+
)
|
1100
|
+
object_instance = get_object_or_404(
|
1101
|
+
object_type_model, pk=validated_data["object_id"]
|
1102
|
+
)
|
1103
|
+
else:
|
1104
|
+
# when update
|
1105
|
+
model_name = self.instance.content_type.model
|
1106
|
+
for favorite in store_settings.FAVORITE_TYPES.keys():
|
1107
|
+
if model_name == favorite.lower():
|
1108
|
+
object_type = favorite
|
1109
|
+
object_instance = self.instance.content_object
|
1110
|
+
|
1079
1111
|
for extra in validated_data["extras"]:
|
1080
1112
|
if (
|
1081
1113
|
extra["object_type"]
|
@@ -1111,7 +1143,7 @@ class FavoriteSerializer(serializers.ModelSerializer):
|
|
1111
1143
|
validated_data = {
|
1112
1144
|
"content_object": object_instance,
|
1113
1145
|
"extras": extras,
|
1114
|
-
"name": name,
|
1146
|
+
"name": validated_data["name"],
|
1115
1147
|
}
|
1116
1148
|
self._lookup_validation(validated_data)
|
1117
1149
|
return validated_data
|
@@ -1128,6 +1160,16 @@ class FavoriteSerializer(serializers.ModelSerializer):
|
|
1128
1160
|
raise serializers.ValidationError(detail=e.message_dict)
|
1129
1161
|
return favorite
|
1130
1162
|
|
1163
|
+
def update(self, instance, validated_data):
|
1164
|
+
try:
|
1165
|
+
favorite = instance.update_favorite(
|
1166
|
+
validated_data["name"],
|
1167
|
+
validated_data["extras"],
|
1168
|
+
)
|
1169
|
+
except ValidationError as e:
|
1170
|
+
raise serializers.ValidationError(detail=e.message_dict)
|
1171
|
+
return favorite
|
1172
|
+
|
1131
1173
|
|
1132
1174
|
class WalletMediaSerializer(serializers.ModelSerializer):
|
1133
1175
|
class Meta:
|
ob_dj_store/apis/stores/views.py
CHANGED
@@ -23,7 +23,6 @@ from rest_framework_nested.viewsets import NestedViewSetMixin
|
|
23
23
|
from config import settings as store_settings
|
24
24
|
from ob_dj_store.apis.stores.filters import (
|
25
25
|
CategoryFilter,
|
26
|
-
FavoriteFilter,
|
27
26
|
InventoryFilter,
|
28
27
|
OrderFilter,
|
29
28
|
PaymentMethodFilter,
|
@@ -861,6 +860,7 @@ class FavoriteViewSet(
|
|
861
860
|
mixins.ListModelMixin,
|
862
861
|
mixins.CreateModelMixin,
|
863
862
|
mixins.DestroyModelMixin,
|
863
|
+
mixins.UpdateModelMixin,
|
864
864
|
viewsets.GenericViewSet,
|
865
865
|
):
|
866
866
|
serializer_class = FavoriteSerializer
|
@@ -868,11 +868,11 @@ class FavoriteViewSet(
|
|
868
868
|
permissions.IsAuthenticated,
|
869
869
|
]
|
870
870
|
queryset = Favorite.objects.all()
|
871
|
-
filterset_class = FavoriteFilter
|
871
|
+
# filterset_class = FavoriteFilter
|
872
872
|
|
873
873
|
def get_queryset(self):
|
874
874
|
model = self.request.query_params.get("type")
|
875
|
-
if self.action
|
875
|
+
if self.action in ["destroy", "update"]:
|
876
876
|
return self.queryset.filter(user=self.request.user)
|
877
877
|
if not model and model not in store_settings.FAVORITE_TYPES:
|
878
878
|
raise ValidationError(_("You must provide the favorite type"))
|
@@ -894,7 +894,14 @@ class FavoriteViewSet(
|
|
894
894
|
type=openapi.TYPE_STRING,
|
895
895
|
enum=list(store_settings.FAVORITE_TYPES),
|
896
896
|
required=True,
|
897
|
-
)
|
897
|
+
),
|
898
|
+
openapi.Parameter(
|
899
|
+
"store",
|
900
|
+
in_=openapi.IN_QUERY,
|
901
|
+
description="Store i of favorite products",
|
902
|
+
type=openapi.TYPE_INTEGER,
|
903
|
+
required=True,
|
904
|
+
),
|
898
905
|
],
|
899
906
|
tags=[
|
900
907
|
"Favorite",
|
@@ -915,6 +922,18 @@ class FavoriteViewSet(
|
|
915
922
|
def create(self, request, *args, **kwargs):
|
916
923
|
return super().create(request, *args, **kwargs)
|
917
924
|
|
925
|
+
@swagger_auto_schema(
|
926
|
+
operation_summary="Update Item From Favorites",
|
927
|
+
operation_description="""
|
928
|
+
Update Item From Favorites
|
929
|
+
""",
|
930
|
+
tags=[
|
931
|
+
"Favorite",
|
932
|
+
],
|
933
|
+
)
|
934
|
+
def update(self, request, *args, **kwargs):
|
935
|
+
return super().update(request, *args, **kwargs)
|
936
|
+
|
918
937
|
@swagger_auto_schema(
|
919
938
|
operation_summary="Remove Item From Favorites",
|
920
939
|
operation_description="""
|
@@ -52,6 +52,21 @@ class Favorite(DjangoModelCleanMixin, models.Model):
|
|
52
52
|
)
|
53
53
|
return favorite
|
54
54
|
|
55
|
+
def update_favorite(self, name, extras=[]):
|
56
|
+
from ob_dj_store.core.stores.models._favorite import FavoriteExtra
|
57
|
+
|
58
|
+
self.name = name
|
59
|
+
self.save()
|
60
|
+
FavoriteExtra.objects.filter(favorite=self).delete()
|
61
|
+
for extra in extras:
|
62
|
+
extra_content_type = ContentType.objects.get_for_model(type(extra))
|
63
|
+
self.extras.create(
|
64
|
+
content_type=extra_content_type,
|
65
|
+
object_id=extra.id,
|
66
|
+
content_object=extra,
|
67
|
+
)
|
68
|
+
return self
|
69
|
+
|
55
70
|
|
56
71
|
class FavoriteExtra(DjangoModelCleanMixin, models.Model):
|
57
72
|
favorite = models.ForeignKey(
|
@@ -2,8 +2,8 @@ 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=18Sb8Id1mgCC0zAzTOQRfBaS7bkyD_sgM8_jAbf1ulE,6349
|
4
4
|
ob_dj_store/apis/stores/urls.py,sha256=cPForgFpOgOGCUVAk6DZcZ7qOooMf1zpDIr1BA0L_8A,1593
|
5
|
-
ob_dj_store/apis/stores/views.py,sha256=
|
6
|
-
ob_dj_store/apis/stores/rest/serializers/serializers.py,sha256=
|
5
|
+
ob_dj_store/apis/stores/views.py,sha256=GryrtvVY3W9EiVMTnQgTL1uXtzspB75GX6_qnrjM5S0,32301
|
6
|
+
ob_dj_store/apis/stores/rest/serializers/serializers.py,sha256=ozazsEKATnmMD2Oc9lx9oIn-DxNOX3mjeLKrpvsFtD8,40720
|
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
|
@@ -101,7 +101,7 @@ ob_dj_store/core/stores/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQe
|
|
101
101
|
ob_dj_store/core/stores/models/__init__.py,sha256=fNB_sn6HM6EmTp_Z-Q7KXD8HDWVjG3qlayrWqvygvbw,1617
|
102
102
|
ob_dj_store/core/stores/models/_address.py,sha256=qS5TQ9Z12zx_4CrrHvG8PoYVkdiOq_MtbKR14WKh3Hw,1661
|
103
103
|
ob_dj_store/core/stores/models/_cart.py,sha256=qgjg5MXTMRIZRJJDx5BQ1pa9__ylfrnYMMRGbB2R53c,4555
|
104
|
-
ob_dj_store/core/stores/models/_favorite.py,sha256=
|
104
|
+
ob_dj_store/core/stores/models/_favorite.py,sha256=J29ECDsotIgduPpmUmieYTndymReWHkfdsZyQzz6A4g,3042
|
105
105
|
ob_dj_store/core/stores/models/_feedback.py,sha256=eCUVgprNK5hSRKOS4M_pdR7QH2-rqhoYevlpykhCOLg,1472
|
106
106
|
ob_dj_store/core/stores/models/_inventory.py,sha256=vAXSpCyUdYDIWgUEUUObQfhAcCcQO6j6zATrHf5dPuQ,3928
|
107
107
|
ob_dj_store/core/stores/models/_order.py,sha256=lizkG-HEsxsC7Xasi5nnAtUnBL4riXezR48LblX-Zsk,8246
|
@@ -113,7 +113,7 @@ ob_dj_store/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
|
|
113
113
|
ob_dj_store/utils/helpers.py,sha256=FtXXJOD2PILqZTyuf80bmf0KuWW64hxbJG6naJdxI5w,1607
|
114
114
|
ob_dj_store/utils/model.py,sha256=DV7hOhTaZL3gh9sptts2jTUFlTArKG3i7oPioq9HLFE,303
|
115
115
|
ob_dj_store/utils/utils.py,sha256=8UVAFB56qUSjJJ5f9vnermtw638gdFy4CFRCuMbns_M,1342
|
116
|
-
ob_dj_store-0.0.12.
|
117
|
-
ob_dj_store-0.0.12.
|
118
|
-
ob_dj_store-0.0.12.
|
119
|
-
ob_dj_store-0.0.12.
|
116
|
+
ob_dj_store-0.0.12.3.dist-info/METADATA,sha256=_2kjr1NOwjQZVvrFct_JH1heumK1WJOv-6uBl6f0Jzs,2827
|
117
|
+
ob_dj_store-0.0.12.3.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
118
|
+
ob_dj_store-0.0.12.3.dist-info/top_level.txt,sha256=CZG3G0ptTkzGnc0dFYN-ZD7YKdJBmm47bsmGwofD_lk,12
|
119
|
+
ob_dj_store-0.0.12.3.dist-info/RECORD,,
|
File without changes
|