ob-dj-store 0.0.12.1__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 +92 -31
- 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.1.dist-info → ob_dj_store-0.0.12.3.dist-info}/METADATA +1 -1
- {ob_dj_store-0.0.12.1.dist-info → ob_dj_store-0.0.12.3.dist-info}/RECORD +7 -7
- {ob_dj_store-0.0.12.1.dist-info → ob_dj_store-0.0.12.3.dist-info}/WHEEL +1 -1
- {ob_dj_store-0.0.12.1.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
|
@@ -970,17 +975,17 @@ class GenericSerializer(serializers.Serializer):
|
|
970
975
|
)
|
971
976
|
|
972
977
|
|
973
|
-
|
974
|
-
|
975
|
-
|
978
|
+
def get_favorite_extras_models():
|
979
|
+
extras_list = []
|
980
|
+
for key, value in settings.FAVORITE_TYPES.items():
|
981
|
+
if "extras" in value:
|
982
|
+
extras_list.extend(value["extras"].keys())
|
983
|
+
return extras_list
|
976
984
|
|
977
|
-
for key, value in settings.FAVORITE_TYPES.items():
|
978
|
-
if "extras" in value:
|
979
|
-
extras_list.extend(value["extras"].keys())
|
980
|
-
return extras_list
|
981
985
|
|
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
|
)
|
@@ -994,14 +999,27 @@ class FavoriteExtraSerializer(serializers.ModelSerializer):
|
|
994
999
|
"object_type",
|
995
1000
|
)
|
996
1001
|
|
1002
|
+
def to_representation(self, instance):
|
1003
|
+
data = super().to_representation(instance)
|
1004
|
+
extras = get_favorite_extras_models()
|
1005
|
+
model_name = instance.content_type.model
|
1006
|
+
for extra in extras:
|
1007
|
+
if model_name == extra.lower():
|
1008
|
+
data["object_type"] = extra
|
1009
|
+
break
|
1010
|
+
return data
|
1011
|
+
|
997
1012
|
|
998
1013
|
class FavoriteSerializer(serializers.ModelSerializer):
|
999
1014
|
content_object = GenericSerializer(read_only=True)
|
1000
1015
|
extras = FavoriteExtraSerializer(many=True)
|
1001
|
-
object_id = serializers.IntegerField(min_value=1,
|
1016
|
+
object_id = serializers.IntegerField(min_value=1, required=False)
|
1002
1017
|
object_type = serializers.ChoiceField(
|
1003
|
-
write_only=True,
|
1018
|
+
write_only=True,
|
1019
|
+
choices=list(store_settings.FAVORITE_TYPES.keys()),
|
1020
|
+
required=False,
|
1004
1021
|
)
|
1022
|
+
is_available_in_store = serializers.SerializerMethodField()
|
1005
1023
|
|
1006
1024
|
class Meta:
|
1007
1025
|
model = Favorite
|
@@ -1012,11 +1030,36 @@ class FavoriteSerializer(serializers.ModelSerializer):
|
|
1012
1030
|
"object_id",
|
1013
1031
|
"object_type",
|
1014
1032
|
"name",
|
1033
|
+
"is_available_in_store",
|
1015
1034
|
)
|
1016
1035
|
extra_kwargs = {
|
1017
1036
|
"name": {"required": True},
|
1018
1037
|
}
|
1019
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
|
+
|
1054
|
+
def to_representation(self, instance):
|
1055
|
+
data = super().to_representation(instance)
|
1056
|
+
model_name = instance.content_type.model
|
1057
|
+
for favorite in store_settings.FAVORITE_TYPES.keys():
|
1058
|
+
if model_name == favorite.lower():
|
1059
|
+
data["object_type"] = favorite
|
1060
|
+
break
|
1061
|
+
return data
|
1062
|
+
|
1020
1063
|
def _lookup_validation(self, data):
|
1021
1064
|
content_type = ContentType.objects.get_for_model(data["content_object"])
|
1022
1065
|
queryset = Favorite.objects.filter(
|
@@ -1024,18 +1067,18 @@ class FavoriteSerializer(serializers.ModelSerializer):
|
|
1024
1067
|
object_id=data["content_object"].id,
|
1025
1068
|
user=self.context["request"].user,
|
1026
1069
|
).prefetch_related("extras")
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
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
|
+
)
|
1039
1082
|
|
1040
1083
|
def get_object(self, model: models.Model, id: int):
|
1041
1084
|
try:
|
@@ -1049,14 +1092,22 @@ class FavoriteSerializer(serializers.ModelSerializer):
|
|
1049
1092
|
def validate(self, attrs):
|
1050
1093
|
validated_data = super().validate(attrs)
|
1051
1094
|
extras_data = {}
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
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
|
+
|
1060
1111
|
for extra in validated_data["extras"]:
|
1061
1112
|
if (
|
1062
1113
|
extra["object_type"]
|
@@ -1092,7 +1143,7 @@ class FavoriteSerializer(serializers.ModelSerializer):
|
|
1092
1143
|
validated_data = {
|
1093
1144
|
"content_object": object_instance,
|
1094
1145
|
"extras": extras,
|
1095
|
-
"name": name,
|
1146
|
+
"name": validated_data["name"],
|
1096
1147
|
}
|
1097
1148
|
self._lookup_validation(validated_data)
|
1098
1149
|
return validated_data
|
@@ -1109,6 +1160,16 @@ class FavoriteSerializer(serializers.ModelSerializer):
|
|
1109
1160
|
raise serializers.ValidationError(detail=e.message_dict)
|
1110
1161
|
return favorite
|
1111
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
|
+
|
1112
1173
|
|
1113
1174
|
class WalletMediaSerializer(serializers.ModelSerializer):
|
1114
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
|