ob-dj-store 0.0.22.2__py3-none-any.whl → 0.0.22.4__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 +19 -6
- ob_dj_store/apis/stores/views.py +1 -1
- ob_dj_store/core/stores/admin.py +1 -0
- ob_dj_store/core/stores/migrations/0110_auto_20250923_1714.py +26 -0
- ob_dj_store/core/stores/migrations/0111_auto_20251023_1700.py +35 -0
- ob_dj_store/core/stores/models/_payment.py +2 -2
- ob_dj_store/core/stores/models/_product.py +4 -0
- ob_dj_store/core/stores/models/_store.py +3 -0
- ob_dj_store/core/stores/models/_wallet.py +16 -9
- {ob_dj_store-0.0.22.2.dist-info → ob_dj_store-0.0.22.4.dist-info}/METADATA +1 -1
- {ob_dj_store-0.0.22.2.dist-info → ob_dj_store-0.0.22.4.dist-info}/RECORD +13 -11
- {ob_dj_store-0.0.22.2.dist-info → ob_dj_store-0.0.22.4.dist-info}/WHEEL +0 -0
- {ob_dj_store-0.0.22.2.dist-info → ob_dj_store-0.0.22.4.dist-info}/top_level.txt +0 -0
|
@@ -401,8 +401,7 @@ class OrderSerializer(serializers.ModelSerializer):
|
|
|
401
401
|
|
|
402
402
|
def _validate_pickup_time(self, store, pickup_time):
|
|
403
403
|
# validate that the pickup_time is always in the future
|
|
404
|
-
|
|
405
|
-
if pickup_time < localtime(now()):
|
|
404
|
+
if pickup_time < localtime(now(), self._get_store().timezone):
|
|
406
405
|
raise serializers.ValidationError(_("Pickup time must be in the future"))
|
|
407
406
|
pickup_time_time = pickup_time.time()
|
|
408
407
|
# validate that the pickup_time is between store's opening hours and closing hours
|
|
@@ -1059,11 +1058,13 @@ class SubCategorySerializer(ArabicFieldsMixin, serializers.ModelSerializer):
|
|
|
1059
1058
|
def get_is_available(self, obj) -> bool:
|
|
1060
1059
|
store_id = self.context["request"].query_params.get("store", None)
|
|
1061
1060
|
if store_id:
|
|
1061
|
+
local_tz = Store.objects.get(id=store_id).timezone
|
|
1062
|
+
current_time = localtime(now(), local_tz) if local_tz else localtime(now())
|
|
1062
1063
|
for availability_hours in obj.parent.availability_hours.all():
|
|
1063
1064
|
if availability_hours.category == obj.parent:
|
|
1064
1065
|
return (
|
|
1065
1066
|
availability_hours.from_hour
|
|
1066
|
-
<=
|
|
1067
|
+
<= current_time.time()
|
|
1067
1068
|
<= availability_hours.to_hour
|
|
1068
1069
|
)
|
|
1069
1070
|
return False
|
|
@@ -1095,11 +1096,13 @@ class CategorySerializer(ArabicFieldsMixin, serializers.ModelSerializer):
|
|
|
1095
1096
|
def get_is_available(self, obj) -> bool:
|
|
1096
1097
|
store_id = self.context["request"].query_params.get("store", None)
|
|
1097
1098
|
if store_id:
|
|
1099
|
+
local_tz = Store.objects.get(id=store_id).timezone
|
|
1100
|
+
current_time = localtime(now(), local_tz) if local_tz else localtime(now())
|
|
1098
1101
|
for availability_hours in obj.availability_hours.all():
|
|
1099
1102
|
if availability_hours.category == obj:
|
|
1100
1103
|
return (
|
|
1101
1104
|
availability_hours.from_hour
|
|
1102
|
-
<=
|
|
1105
|
+
<= current_time.time()
|
|
1103
1106
|
<= availability_hours.to_hour
|
|
1104
1107
|
)
|
|
1105
1108
|
return False
|
|
@@ -1210,6 +1213,7 @@ class StoreSerializer(ArabicFieldsMixin, FavoriteMixin, serializers.ModelSeriali
|
|
|
1210
1213
|
shipping_methods = ShippingMethodSerializer(many=True, read_only=True)
|
|
1211
1214
|
distance = serializers.SerializerMethodField()
|
|
1212
1215
|
current_day_opening_hours = serializers.SerializerMethodField()
|
|
1216
|
+
timezone = serializers.SerializerMethodField()
|
|
1213
1217
|
|
|
1214
1218
|
class Meta:
|
|
1215
1219
|
model = Store
|
|
@@ -1238,6 +1242,7 @@ class StoreSerializer(ArabicFieldsMixin, FavoriteMixin, serializers.ModelSeriali
|
|
|
1238
1242
|
"image",
|
|
1239
1243
|
"busy_mode",
|
|
1240
1244
|
"name_arabic",
|
|
1245
|
+
"timezone",
|
|
1241
1246
|
)
|
|
1242
1247
|
extra_kwargs = {
|
|
1243
1248
|
"image": {"read_only": True, "required": False},
|
|
@@ -1246,12 +1251,12 @@ class StoreSerializer(ArabicFieldsMixin, FavoriteMixin, serializers.ModelSeriali
|
|
|
1246
1251
|
def get_is_closed(self, obj):
|
|
1247
1252
|
if obj.busy_mode:
|
|
1248
1253
|
return True
|
|
1249
|
-
current_time = localtime(now())
|
|
1254
|
+
current_time = localtime(now(), obj.timezone)
|
|
1250
1255
|
current_op_hour = obj.current_opening_hours
|
|
1251
1256
|
if current_op_hour:
|
|
1252
1257
|
from_hour = current_op_hour.from_hour
|
|
1253
1258
|
to_hour = current_op_hour.to_hour
|
|
1254
|
-
if current_time.tzinfo
|
|
1259
|
+
if current_time.tzinfo != "Asia/Dubai":
|
|
1255
1260
|
if obj.currency == "AED":
|
|
1256
1261
|
try:
|
|
1257
1262
|
current_time += timedelta(hours=1)
|
|
@@ -1365,6 +1370,9 @@ class StoreSerializer(ArabicFieldsMixin, FavoriteMixin, serializers.ModelSeriali
|
|
|
1365
1370
|
op_hour = f"{settings.DEFAULT_OPENING_HOURS[0]['from_hour']} - {settings.DEFAULT_OPENING_HOURS[0]['to_hour']}"
|
|
1366
1371
|
return op_hour
|
|
1367
1372
|
|
|
1373
|
+
def get_timezone(self, obj):
|
|
1374
|
+
return str(obj.timezone)
|
|
1375
|
+
|
|
1368
1376
|
def to_representation(self, instance):
|
|
1369
1377
|
return super().to_representation(instance)
|
|
1370
1378
|
|
|
@@ -1403,10 +1411,15 @@ class TaxSerializer(serializers.ModelSerializer):
|
|
|
1403
1411
|
|
|
1404
1412
|
|
|
1405
1413
|
class StoreListSerializer(ArabicFieldsMixin, serializers.ModelSerializer):
|
|
1414
|
+
timezone = serializers.SerializerMethodField()
|
|
1415
|
+
|
|
1406
1416
|
class Meta:
|
|
1407
1417
|
model = Store
|
|
1408
1418
|
fields = "__all__"
|
|
1409
1419
|
|
|
1420
|
+
def get_timezone(self, obj):
|
|
1421
|
+
return str(obj.timezone)
|
|
1422
|
+
|
|
1410
1423
|
|
|
1411
1424
|
class GenericSerializer(serializers.Serializer):
|
|
1412
1425
|
"""
|
ob_dj_store/apis/stores/views.py
CHANGED
|
@@ -1268,7 +1268,7 @@ class PartnerAuthInfoViewSet(
|
|
|
1268
1268
|
class PartnerViewSet(
|
|
1269
1269
|
mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet,
|
|
1270
1270
|
):
|
|
1271
|
-
queryset = Partner.objects.all()
|
|
1271
|
+
queryset = Partner.objects.all().order_by("name")
|
|
1272
1272
|
permission_classes = [
|
|
1273
1273
|
permissions.IsAuthenticated,
|
|
1274
1274
|
]
|
ob_dj_store/core/stores/admin.py
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Generated by Django 3.2.8 on 2025-09-23 14:14
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("stores", "0109_wallettransaction_cashback_type"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterModelOptions(
|
|
14
|
+
name="productvariant",
|
|
15
|
+
options={
|
|
16
|
+
"ordering": ("order_value",),
|
|
17
|
+
"verbose_name": "Product Variation",
|
|
18
|
+
"verbose_name_plural": "Product Variations",
|
|
19
|
+
},
|
|
20
|
+
),
|
|
21
|
+
migrations.AddField(
|
|
22
|
+
model_name="productvariant",
|
|
23
|
+
name="order_value",
|
|
24
|
+
field=models.PositiveSmallIntegerField(default=1, verbose_name="ordering"),
|
|
25
|
+
),
|
|
26
|
+
]
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Generated by Django 3.2.8 on 2025-10-23 14:00
|
|
2
|
+
|
|
3
|
+
import timezone_field.fields
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
("stores", "0110_auto_20250923_1714"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AddField(
|
|
15
|
+
model_name="store",
|
|
16
|
+
name="has_daylight_saving_time",
|
|
17
|
+
field=models.BooleanField(default=False),
|
|
18
|
+
),
|
|
19
|
+
migrations.AddField(
|
|
20
|
+
model_name="store",
|
|
21
|
+
name="timezone",
|
|
22
|
+
field=timezone_field.fields.TimeZoneField(default="Asia/Kuwait"),
|
|
23
|
+
),
|
|
24
|
+
migrations.AlterField(
|
|
25
|
+
model_name="tax",
|
|
26
|
+
name="value",
|
|
27
|
+
field=models.DecimalField(
|
|
28
|
+
blank=True,
|
|
29
|
+
decimal_places=5,
|
|
30
|
+
help_text="Value for the given Payment -> 0.0625",
|
|
31
|
+
max_digits=7,
|
|
32
|
+
null=True,
|
|
33
|
+
),
|
|
34
|
+
),
|
|
35
|
+
]
|
|
@@ -35,8 +35,8 @@ class Tax(models.Model):
|
|
|
35
35
|
country = CountryField(help_text=_("The address country."), default="KW")
|
|
36
36
|
value = models.DecimalField(
|
|
37
37
|
blank=True,
|
|
38
|
-
max_digits=
|
|
39
|
-
decimal_places=
|
|
38
|
+
max_digits=7,
|
|
39
|
+
decimal_places=5,
|
|
40
40
|
null=True,
|
|
41
41
|
help_text="Value for the given Payment -> 0.0625",
|
|
42
42
|
)
|
|
@@ -447,6 +447,9 @@ class ProductVariant(DjangoModelCleanMixin, models.Model):
|
|
|
447
447
|
image_thumbnail_medium = models.ImageField(
|
|
448
448
|
upload_to="product_variant_media/", null=True, blank=True
|
|
449
449
|
)
|
|
450
|
+
order_value = models.PositiveSmallIntegerField(
|
|
451
|
+
verbose_name=_("ordering"), default=1
|
|
452
|
+
)
|
|
450
453
|
# Audit fields
|
|
451
454
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
452
455
|
updated_at = models.DateTimeField(auto_now=True)
|
|
@@ -456,6 +459,7 @@ class ProductVariant(DjangoModelCleanMixin, models.Model):
|
|
|
456
459
|
class Meta:
|
|
457
460
|
verbose_name = _("Product Variation")
|
|
458
461
|
verbose_name_plural = _("Product Variations")
|
|
462
|
+
ordering = ("order_value",)
|
|
459
463
|
|
|
460
464
|
def __str__(self):
|
|
461
465
|
return f"Variation {self.product.name} {self.name} (PK={self.pk})"
|
|
@@ -8,6 +8,7 @@ from django.utils.timezone import now
|
|
|
8
8
|
from django.utils.translation import gettext_lazy as _
|
|
9
9
|
from django_countries.fields import CountryField
|
|
10
10
|
from phonenumber_field.modelfields import PhoneNumberField
|
|
11
|
+
from timezone_field import TimeZoneField
|
|
11
12
|
|
|
12
13
|
from ob_dj_store.core.stores.managers import (
|
|
13
14
|
CountryPaymentMethodManager,
|
|
@@ -179,6 +180,8 @@ class Store(DjangoModelCleanMixin, models.Model):
|
|
|
179
180
|
)
|
|
180
181
|
busy_mode = models.BooleanField(default=False)
|
|
181
182
|
is_digital = models.BooleanField(default=False)
|
|
183
|
+
timezone = TimeZoneField(default="Asia/Kuwait")
|
|
184
|
+
has_daylight_saving_time = models.BooleanField(default=False)
|
|
182
185
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
183
186
|
updated_at = models.DateTimeField(auto_now=True)
|
|
184
187
|
|
|
@@ -122,15 +122,22 @@ class Wallet(models.Model):
|
|
|
122
122
|
)
|
|
123
123
|
|
|
124
124
|
provider = payment_method.payment_provider
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
125
|
+
logger.info(f"Payment ID: {payment.id}")
|
|
126
|
+
logger.info(f"Payment provider: {provider}")
|
|
127
|
+
try:
|
|
128
|
+
if provider == settings.STRIPE:
|
|
129
|
+
logger.info(
|
|
130
|
+
f"Stripe payment info: {payment.stripe_payment.payment_intent_id}"
|
|
131
|
+
)
|
|
132
|
+
return (
|
|
133
|
+
payment.stripe_payment.payment_url,
|
|
134
|
+
payment.stripe_payment.payment_intent_id,
|
|
135
|
+
)
|
|
136
|
+
else:
|
|
137
|
+
logger.info(f"TAP payment info: {payment.tap_payment.charge_id}")
|
|
138
|
+
return (payment.tap_payment.payment_url, payment.tap_payment.charge_id)
|
|
139
|
+
except Exception as e:
|
|
140
|
+
logger.warning(f"Error returning payment details")
|
|
134
141
|
return (None, None)
|
|
135
142
|
|
|
136
143
|
|
|
@@ -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=JeUtcicJ3cFnZc71aUMEwn2jaVj1oNQsZOCZfdxGDu8,10338
|
|
4
4
|
ob_dj_store/apis/stores/urls.py,sha256=W9sNJ7ST9pGnfVCf7GmduDO-_zK9MGTI6ybV8n-lzSc,2111
|
|
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=E9msGnkPEFjMTqU9jn-6rnCof3pivoHLesZda6D1BBs,42761
|
|
6
|
+
ob_dj_store/apis/stores/rest/serializers/serializers.py,sha256=Rm-ay0ZwfkcChoy7lXZDbfyn5h2qPUVaEFATkVMeHvc,69783
|
|
7
7
|
ob_dj_store/apis/stripe/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
ob_dj_store/apis/stripe/serializers.py,sha256=SX3yKVNbDvE5LL35DF9XoC8sjwGkCSdKz_JUVWsJDLg,5949
|
|
9
9
|
ob_dj_store/apis/stripe/urls.py,sha256=IHH9sX3d74KDUlXkYnIAwYRC6zEvUaOTSFsJGJfiAjA,723
|
|
@@ -14,7 +14,7 @@ ob_dj_store/apis/tap/urls.py,sha256=bnOTv6an11kxpo_FdqlhsizlGPLVpNxBjCyKcf3_C9M,
|
|
|
14
14
|
ob_dj_store/apis/tap/views.py,sha256=sWqNT3nnEFXwRlVokoZREpCOwMQtyd_ZzrvUtQ6c5L0,2620
|
|
15
15
|
ob_dj_store/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
ob_dj_store/core/stores/__init__.py,sha256=-izNGrxNn_nn3IQXd5pkuES9lSF-AHYb14yhNPozYCI,65
|
|
17
|
-
ob_dj_store/core/stores/admin.py,sha256=
|
|
17
|
+
ob_dj_store/core/stores/admin.py,sha256=j7c_kDWY4BJrM0xWK1P8WRQSnu7kX6UBXFxfZ5oewj4,14394
|
|
18
18
|
ob_dj_store/core/stores/admin_inlines.py,sha256=9_35VwwRh5w8YU2CRTJ7sENUjF-D-J-o9jXhLEPpS3w,2900
|
|
19
19
|
ob_dj_store/core/stores/apps.py,sha256=ZadmEER_dNcQTH617b3fAsYZJSyRw0g46Kjp4eOAsOU,498
|
|
20
20
|
ob_dj_store/core/stores/managers.py,sha256=Q0PUB_LSz0bufJ0OfgHuvSC-5uAGSsDDlhitisFJqw4,10141
|
|
@@ -155,6 +155,8 @@ ob_dj_store/core/stores/migrations/0106_alter_paymentmethod_payment_provider.py,
|
|
|
155
155
|
ob_dj_store/core/stores/migrations/0107_auto_20250425_2059.py,sha256=XCj2Inlw8e-_6W9wvYeVVV-bGk6lX8_n2FNI5W80XVw,848
|
|
156
156
|
ob_dj_store/core/stores/migrations/0108_alter_paymentmethod_payment_provider.py,sha256=abuqKAhuha8tEdxJy-Tj1RNFOMV63_z5v_qK5LLSNVI,1078
|
|
157
157
|
ob_dj_store/core/stores/migrations/0109_wallettransaction_cashback_type.py,sha256=XA_RtxLjnpsz-i0uKlCyYK-UWL4RR10Q_XeqVd3KX6A,691
|
|
158
|
+
ob_dj_store/core/stores/migrations/0110_auto_20250923_1714.py,sha256=o8a6zt9iyZp7_Km4Wos8OSZ-vn-mVyAIdXvWdCytQaQ,727
|
|
159
|
+
ob_dj_store/core/stores/migrations/0111_auto_20251023_1700.py,sha256=CZcu32ZUREnZcpu0jmEYWKyus8G_TT_ULXm3o_jf8T8,949
|
|
158
160
|
ob_dj_store/core/stores/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
159
161
|
ob_dj_store/core/stores/models/__init__.py,sha256=VeWrDiIbw94ZDSFD-62rz9iTTW87iPdwDW5jcjxm7bs,2045
|
|
160
162
|
ob_dj_store/core/stores/models/_address.py,sha256=uf9W4dnlXkEFhhsK75ZsDwWq5R2JEngf7VhBiLEnIVs,2193
|
|
@@ -164,15 +166,15 @@ ob_dj_store/core/stores/models/_feedback.py,sha256=5kQ_AD9nkY57UOKo_qHg4_nEQAdFj
|
|
|
164
166
|
ob_dj_store/core/stores/models/_inventory.py,sha256=_rGlVL5HjOlHQVB8CI0776CPcE5r6szv1w3PjtkYnWM,4306
|
|
165
167
|
ob_dj_store/core/stores/models/_order.py,sha256=_08lqX5p4brCdUilqfbT--6Ao2TMsqnzXaWoV_7IYL8,9758
|
|
166
168
|
ob_dj_store/core/stores/models/_partner.py,sha256=OuYvevUWn1sYHs9PcFf51EUUC1uqytQss8Bx91aMOH8,4732
|
|
167
|
-
ob_dj_store/core/stores/models/_payment.py,sha256=
|
|
168
|
-
ob_dj_store/core/stores/models/_product.py,sha256=
|
|
169
|
-
ob_dj_store/core/stores/models/_store.py,sha256=
|
|
170
|
-
ob_dj_store/core/stores/models/_wallet.py,sha256=
|
|
169
|
+
ob_dj_store/core/stores/models/_payment.py,sha256=1Ssz2RbI_kI-n-bejApbH3EMm96Bg19dgiMUjQHj9R4,6650
|
|
170
|
+
ob_dj_store/core/stores/models/_product.py,sha256=rt30n_X9RRGcyqwB-hj1PMEZRQNvzJhc0M-mLkBoPWI,18675
|
|
171
|
+
ob_dj_store/core/stores/models/_store.py,sha256=vz-rVEwWCmz62pRtj3qAR7D3doBH1p2FkOUjKtI4-lo,9992
|
|
172
|
+
ob_dj_store/core/stores/models/_wallet.py,sha256=SjGizV1P3fhCYyxD-X0ts-PjhzdpGVHd5vIz54Rbj8A,6357
|
|
171
173
|
ob_dj_store/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
172
174
|
ob_dj_store/utils/helpers.py,sha256=o7wgypM7mI2vZqZKkhxnTcnHJC8GMQDOuYMnRwXr6tY,2058
|
|
173
175
|
ob_dj_store/utils/model.py,sha256=DV7hOhTaZL3gh9sptts2jTUFlTArKG3i7oPioq9HLFE,303
|
|
174
176
|
ob_dj_store/utils/utils.py,sha256=8UVAFB56qUSjJJ5f9vnermtw638gdFy4CFRCuMbns_M,1342
|
|
175
|
-
ob_dj_store-0.0.22.
|
|
176
|
-
ob_dj_store-0.0.22.
|
|
177
|
-
ob_dj_store-0.0.22.
|
|
178
|
-
ob_dj_store-0.0.22.
|
|
177
|
+
ob_dj_store-0.0.22.4.dist-info/METADATA,sha256=JEtu0JWXnO20S15Hxt2YF4Rt5NbMz_bGkTWzaigtPh4,2850
|
|
178
|
+
ob_dj_store-0.0.22.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
179
|
+
ob_dj_store-0.0.22.4.dist-info/top_level.txt,sha256=CZG3G0ptTkzGnc0dFYN-ZD7YKdJBmm47bsmGwofD_lk,12
|
|
180
|
+
ob_dj_store-0.0.22.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|