ob-dj-store 0.0.22.3__tar.gz → 0.0.22.5__tar.gz

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.
Files changed (218) hide show
  1. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/.isort.cfg +1 -1
  2. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/PKG-INFO +1 -1
  3. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/Pipfile +1 -0
  4. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/Pipfile.lock +16 -7
  5. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/stores/rest/serializers/serializers.py +25 -6
  6. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/stores/views.py +1 -1
  7. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/admin.py +20 -0
  8. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/admin_inlines.py +5 -0
  9. ob_dj_store-0.0.22.5/ob_dj_store/core/stores/migrations/0111_auto_20251023_1700.py +35 -0
  10. ob_dj_store-0.0.22.5/ob_dj_store/core/stores/migrations/0112_auto_20251027_1739.py +98 -0
  11. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/models/__init__.py +9 -1
  12. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/models/_order.py +58 -1
  13. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/models/_payment.py +2 -2
  14. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/models/_store.py +3 -0
  15. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store.egg-info/PKG-INFO +1 -1
  16. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store.egg-info/SOURCES.txt +2 -0
  17. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/.github/dependabot.yml +0 -0
  18. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/.github/workflows/docs.yml +0 -0
  19. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/.github/workflows/pre-release.yml +0 -0
  20. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/.github/workflows/release.yml +0 -0
  21. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/.github/workflows/test-build.yml +0 -0
  22. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/.gitignore +0 -0
  23. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/.pre-commit-config.yaml +0 -0
  24. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/Dockerfile +0 -0
  25. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/MANIFEST.in +0 -0
  26. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/Makefile +0 -0
  27. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/README.md +0 -0
  28. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/config/__init__.py +0 -0
  29. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/config/settings.py +0 -0
  30. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/config/urls.py +0 -0
  31. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/config/wsgi.py +0 -0
  32. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/docker-compose.env +0 -0
  33. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/docker-compose.yml +0 -0
  34. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/docs/Makefile +0 -0
  35. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/docs/make.bat +0 -0
  36. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/docs/source/admin.rst +0 -0
  37. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/docs/source/conf.py +0 -0
  38. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/docs/source/index.rst +0 -0
  39. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/docs/source/installation.rst +0 -0
  40. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/docs/source/models.rst +0 -0
  41. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/docs/source/rest_endpoints.rst +0 -0
  42. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/fixtures/initial_users.yaml +0 -0
  43. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/fixtures/stores.yaml +0 -0
  44. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/manage.py +0 -0
  45. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/__init__.py +0 -0
  46. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/__init__.py +0 -0
  47. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/stores/__init__.py +0 -0
  48. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/stores/filters.py +0 -0
  49. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/stores/urls.py +0 -0
  50. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/stripe/__init__.py +0 -0
  51. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/stripe/serializers.py +0 -0
  52. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/stripe/urls.py +0 -0
  53. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/stripe/views.py +0 -0
  54. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/tap/__init__.py +0 -0
  55. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/tap/serializers.py +0 -0
  56. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/tap/urls.py +0 -0
  57. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/apis/tap/views.py +0 -0
  58. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/__init__.py +0 -0
  59. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/__init__.py +0 -0
  60. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/apps.py +0 -0
  61. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/__init__.py +0 -0
  62. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/stripe/__init__.py +0 -0
  63. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/stripe/admin.py +0 -0
  64. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/stripe/apps.py +0 -0
  65. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/stripe/managers.py +0 -0
  66. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/stripe/migrations/0001_initial.py +0 -0
  67. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/stripe/migrations/__init__.py +0 -0
  68. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/stripe/models.py +0 -0
  69. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/stripe/utils.py +0 -0
  70. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/__init__.py +0 -0
  71. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/admin.py +0 -0
  72. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/apps.py +0 -0
  73. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/managers.py +0 -0
  74. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/migrations/0001_initial.py +0 -0
  75. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/migrations/0002_auto_20220815_1610.py +0 -0
  76. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/migrations/0003_auto_20220818_1938.py +0 -0
  77. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/migrations/0004_tapcustomer.py +0 -0
  78. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/migrations/0005_alter_tappayment_payment_url.py +0 -0
  79. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/migrations/0006_alter_tappayment_source.py +0 -0
  80. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/migrations/0007_alter_tappayment_source.py +0 -0
  81. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/migrations/0008_alter_tappayment_user.py +0 -0
  82. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/migrations/__init__.py +0 -0
  83. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/models.py +0 -0
  84. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/gateway/tap/utils.py +0 -0
  85. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/managers.py +0 -0
  86. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0001_initial.py +0 -0
  87. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0002_auto_20220422_0205.py +0 -0
  88. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0003_openinghours.py +0 -0
  89. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0004_auto_20220422_2326.py +0 -0
  90. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0005_auto_20220425_2119.py +0 -0
  91. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0005_auto_20220427_1729.py +0 -0
  92. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0006_auto_20220428_0100.py +0 -0
  93. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0007_cart_cartitem_order_orderitem.py +0 -0
  94. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0008_order_status.py +0 -0
  95. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0009_auto_20220508_2142.py +0 -0
  96. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0010_auto_20220509_1633.py +0 -0
  97. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0011_favorite.py +0 -0
  98. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0012_auto_20220514_0633.py +0 -0
  99. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0013_auto_20220518_1539.py +0 -0
  100. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0014_auto_20220519_0018.py +0 -0
  101. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0015_inventory_inventoryoperations.py +0 -0
  102. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0016_productvariant_preparation_time.py +0 -0
  103. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0017_auto_20220524_0912.py +0 -0
  104. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0018_auto_20220524_1613.py +0 -0
  105. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0019_product_is_featured.py +0 -0
  106. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0020_orderhistory.py +0 -0
  107. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0021_auto_20220531_1849.py +0 -0
  108. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0022_order_pickup_time.py +0 -0
  109. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0023_feedback_feedbackattribute_feedbackconfig.py +0 -0
  110. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0024_auto_20220609_1552.py +0 -0
  111. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0025_productvariant_is_primary.py +0 -0
  112. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0026_auto_20220630_1913.py +0 -0
  113. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0027_auto_20220713_1759.py +0 -0
  114. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0028_phonecontact.py +0 -0
  115. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0029_auto_20220726_1750.py +0 -0
  116. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0030_category_parent.py +0 -0
  117. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0031_auto_20220811_1733.py +0 -0
  118. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0032_auto_20220812_1951.py +0 -0
  119. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0033_auto_20220815_0133.py +0 -0
  120. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0034_auto_20220815_1528.py +0 -0
  121. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0035_auto_20220818_1938.py +0 -0
  122. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0036_productattribute_is_mandatory.py +0 -0
  123. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0037_auto_20220825_1736.py +0 -0
  124. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0038_cartitem_extra_infos.py +0 -0
  125. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0039_auto_20220831_1521.py +0 -0
  126. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0040_auto_20220902_1806.py +0 -0
  127. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0041_auto_20220912_1506.py +0 -0
  128. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0042_wallet_wallettransaction.py +0 -0
  129. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0043_auto_20220919_1854.py +0 -0
  130. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0044_remove_productvariant_has_inventory.py +0 -0
  131. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0045_shippingmethod_type.py +0 -0
  132. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0046_auto_20221014_1720.py +0 -0
  133. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0047_auto_20221018_1433.py +0 -0
  134. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0048_auto_20221026_1933.py +0 -0
  135. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0049_auto_20221029_1524.py +0 -0
  136. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0050_favoriteextra.py +0 -0
  137. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0051_order_car_id.py +0 -0
  138. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0052_auto_20221129_1732.py +0 -0
  139. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0053_inventory_plu.py +0 -0
  140. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0054_auto_20221230_1501.py +0 -0
  141. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0055_store_image.py +0 -0
  142. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0056_auto_20230213_2224.py +0 -0
  143. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0057_auto_20230214_1724.py +0 -0
  144. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0058_attributechoice_is_default.py +0 -0
  145. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0059_auto_20230217_2006.py +0 -0
  146. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0060_alter_orderitem_product_variant.py +0 -0
  147. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0061_auto_20230223_1435.py +0 -0
  148. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0062_auto_20230226_2005.py +0 -0
  149. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0063_alter_store_payment_methods.py +0 -0
  150. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0064_auto_20230228_1814.py +0 -0
  151. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0065_auto_20230228_1932.py +0 -0
  152. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0066_auto_20230304_1532.py +0 -0
  153. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0067_auto_20230309_2014.py +0 -0
  154. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0068_auto_20230309_2251.py +0 -0
  155. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0069_alter_cartitem_options.py +0 -0
  156. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0070_auto_20230323_1628.py +0 -0
  157. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0071_auto_20230328_1825.py +0 -0
  158. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0072_alter_order_extra_infos.py +0 -0
  159. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0073_wallettransaction_is_cashback.py +0 -0
  160. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0074_productvariant_label.py +0 -0
  161. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0075_auto_20230419_0259.py +0 -0
  162. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0076_auto_20230421_1343.py +0 -0
  163. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0077_auto_20230502_2005.py +0 -0
  164. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0078_auto_20230503_1259.py +0 -0
  165. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0079_auto_20230504_1919.py +0 -0
  166. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0080_productvariant_description.py +0 -0
  167. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0081_storeattributechoice.py +0 -0
  168. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0082_auto_20230613_1424.py +0 -0
  169. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0083_productvariant_is_special.py +0 -0
  170. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0084_payment_result.py +0 -0
  171. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0085_auto_20230726_1528.py +0 -0
  172. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0086_wallet_is_active.py +0 -0
  173. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0087_auto_20230828_2138.py +0 -0
  174. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0088_alter_paymentmethod_payment_provider.py +0 -0
  175. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0089_discount_partner_partnerauthinfo_partneremaildomain_partnerotpauth.py +0 -0
  176. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0090_auto_20231006_1356.py +0 -0
  177. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0091_auto_20231010_1740.py +0 -0
  178. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0092_auto_20231012_1339.py +0 -0
  179. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0093_auto_20231017_2033.py +0 -0
  180. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0094_countrypaymentmethod.py +0 -0
  181. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0095_auto_20231101_1531.py +0 -0
  182. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0096_discount_discount_pos_id.py +0 -0
  183. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0097_auto_20231108_1939.py +0 -0
  184. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0098_alter_discount_discount_rate.py +0 -0
  185. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0099_alter_product_name_arabic.py +0 -0
  186. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0100_remove_shippingmethod_type_arabic.py +0 -0
  187. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0101_store_is_digital.py +0 -0
  188. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0102_partner_name_arabic.py +0 -0
  189. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0103_alter_paymentmethod_payment_provider.py +0 -0
  190. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0104_wallettransaction_is_redeemed.py +0 -0
  191. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0105_store_is_open_after_midnight.py +0 -0
  192. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0106_alter_paymentmethod_payment_provider.py +0 -0
  193. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0107_auto_20250425_2059.py +0 -0
  194. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0108_alter_paymentmethod_payment_provider.py +0 -0
  195. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0109_wallettransaction_cashback_type.py +0 -0
  196. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/0110_auto_20250923_1714.py +0 -0
  197. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/migrations/__init__.py +0 -0
  198. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/models/_address.py +0 -0
  199. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/models/_cart.py +0 -0
  200. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/models/_favorite.py +0 -0
  201. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/models/_feedback.py +0 -0
  202. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/models/_inventory.py +0 -0
  203. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/models/_partner.py +0 -0
  204. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/models/_product.py +0 -0
  205. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/models/_wallet.py +0 -0
  206. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/receivers.py +0 -0
  207. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/settings_validation.py +0 -0
  208. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/core/stores/utils.py +0 -0
  209. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/utils/__init__.py +0 -0
  210. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/utils/helpers.py +0 -0
  211. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/utils/model.py +0 -0
  212. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store/utils/utils.py +0 -0
  213. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store.egg-info/dependency_links.txt +0 -0
  214. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store.egg-info/requires.txt +0 -0
  215. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/ob_dj_store.egg-info/top_level.txt +0 -0
  216. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/pytest.ini +0 -0
  217. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/setup.cfg +0 -0
  218. {ob_dj_store-0.0.22.3 → ob_dj_store-0.0.22.5}/setup.py +0 -0
@@ -1,2 +1,2 @@
1
1
  [settings]
2
- known_third_party = PIL,dateutil,dj_database_url,django,django_auto_prefetching,django_countries,django_filters,drf_yasg,factory,faker,import_export,leaflet,mock,ob_dj_otp,phonenumber_field,pilkit,pkg_resources,pycountry,pytest,pytz,requests,rest_framework,rest_framework_gis,rest_framework_nested,setuptools,stripe
2
+ known_third_party = PIL,dateutil,dj_database_url,django,django_auto_prefetching,django_countries,django_filters,drf_yasg,factory,faker,import_export,leaflet,mock,ob_dj_otp,phonenumber_field,pilkit,pkg_resources,pycountry,pytest,pytz,requests,rest_framework,rest_framework_gis,rest_framework_nested,setuptools,stripe,timezone_field
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ob-dj-store
3
- Version: 0.0.22.3
3
+ Version: 0.0.22.5
4
4
  Summary: OBytes django application for managing ecommerce stores.
5
5
  Home-page: https://www.obytes.com/
6
6
  Author: OBytes
@@ -33,6 +33,7 @@ django-import-export = "==2.8.0"
33
33
  ob-dj-otp = "==0.0.25"
34
34
  stripe = ">=5.0.0"
35
35
  us = ">=2.0.0"
36
+ django-timezone-field = "==7.1"
36
37
 
37
38
  [dev-packages]
38
39
  mock = "==4.0.3"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "_meta": {
3
3
  "hash": {
4
- "sha256": "ca35d3de2cf2dc23c82f7c4ec8deb4c434e8058b8e976f944279b66619ee0c44"
4
+ "sha256": "ce203ab33ab36c5d1a2a6b9d1312b495db76a2637733ad163a44b976dad30fa2"
5
5
  },
6
6
  "pipfile-spec": 6,
7
7
  "requires": {
@@ -36,11 +36,11 @@
36
36
  },
37
37
  "asgiref": {
38
38
  "hashes": [
39
- "sha256:a5ab6582236218e5ef1648f242fd9f10626cfd4de8dc377db215d5d5098e3142",
40
- "sha256:f3bba7092a48005b5f5bacd747d36ee4a5a61f4a269a6df590b43144355ebd2c"
39
+ "sha256:aef8a81283a34d0ab31630c9b7dfe70c812c95eba78171367ca8745e88124734",
40
+ "sha256:d89f2d8cd8b56dada7d52fa7dc8075baa08fb836560710d38c292a7a3f78c04e"
41
41
  ],
42
42
  "markers": "python_version >= '3.9'",
43
- "version": "==3.9.1"
43
+ "version": "==3.10.0"
44
44
  },
45
45
  "certifi": {
46
46
  "hashes": [
@@ -369,6 +369,15 @@
369
369
  "markers": "python_version >= '3.6'",
370
370
  "version": "==6.0.0"
371
371
  },
372
+ "django-timezone-field": {
373
+ "hashes": [
374
+ "sha256:93914713ed882f5bccda080eda388f7006349f25930b6122e9b07bf8db49c4b4",
375
+ "sha256:b3ef409d88a2718b566fabe10ea996f2838bc72b22d3a2900c0aa905c761380c"
376
+ ],
377
+ "index": "pypi",
378
+ "markers": "python_version >= '3.8' and python_version < '4.0'",
379
+ "version": "==7.1"
380
+ },
372
381
  "djangorestframework": {
373
382
  "hashes": [
374
383
  "sha256:0c33407ce23acc68eca2a6e46424b008c9c02eceb8cf18581921d0092bc1f2ee",
@@ -1075,11 +1084,11 @@
1075
1084
  },
1076
1085
  "typing-extensions": {
1077
1086
  "hashes": [
1078
- "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36",
1079
- "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76"
1087
+ "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466",
1088
+ "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"
1080
1089
  ],
1081
1090
  "markers": "python_version >= '3.9'",
1082
- "version": "==4.14.1"
1091
+ "version": "==4.15.0"
1083
1092
  },
1084
1093
  "uritemplate": {
1085
1094
  "hashes": [
@@ -284,6 +284,8 @@ class OrderSerializer(serializers.ModelSerializer):
284
284
  "created_at",
285
285
  "updated_at",
286
286
  "store_name",
287
+ "tip_percentage",
288
+ "tip_value",
287
289
  )
288
290
  extra_kwargs = {
289
291
  "customer": {"read_only": True},
@@ -401,8 +403,7 @@ class OrderSerializer(serializers.ModelSerializer):
401
403
 
402
404
  def _validate_pickup_time(self, store, pickup_time):
403
405
  # validate that the pickup_time is always in the future
404
-
405
- if pickup_time < localtime(now()):
406
+ if pickup_time < localtime(now(), self._get_store().timezone):
406
407
  raise serializers.ValidationError(_("Pickup time must be in the future"))
407
408
  pickup_time_time = pickup_time.time()
408
409
  # validate that the pickup_time is between store's opening hours and closing hours
@@ -615,7 +616,11 @@ class OrderSerializer(serializers.ModelSerializer):
615
616
  attributes=list(item.attribute_choices.all()),
616
617
  notes=item.notes,
617
618
  )
619
+ if order.tip_percentage:
620
+ order.tip_value = order.calculate_tip()
621
+ order.save()
618
622
  orders.append(order)
623
+
619
624
  amount = Decimal(
620
625
  sum(map(lambda order: Decimal(order.total_amount) or 0, orders))
621
626
  )
@@ -1059,11 +1064,13 @@ class SubCategorySerializer(ArabicFieldsMixin, serializers.ModelSerializer):
1059
1064
  def get_is_available(self, obj) -> bool:
1060
1065
  store_id = self.context["request"].query_params.get("store", None)
1061
1066
  if store_id:
1067
+ local_tz = Store.objects.get(id=store_id).timezone
1068
+ current_time = localtime(now(), local_tz) if local_tz else localtime(now())
1062
1069
  for availability_hours in obj.parent.availability_hours.all():
1063
1070
  if availability_hours.category == obj.parent:
1064
1071
  return (
1065
1072
  availability_hours.from_hour
1066
- <= localtime(now()).time()
1073
+ <= current_time.time()
1067
1074
  <= availability_hours.to_hour
1068
1075
  )
1069
1076
  return False
@@ -1095,11 +1102,13 @@ class CategorySerializer(ArabicFieldsMixin, serializers.ModelSerializer):
1095
1102
  def get_is_available(self, obj) -> bool:
1096
1103
  store_id = self.context["request"].query_params.get("store", None)
1097
1104
  if store_id:
1105
+ local_tz = Store.objects.get(id=store_id).timezone
1106
+ current_time = localtime(now(), local_tz) if local_tz else localtime(now())
1098
1107
  for availability_hours in obj.availability_hours.all():
1099
1108
  if availability_hours.category == obj:
1100
1109
  return (
1101
1110
  availability_hours.from_hour
1102
- <= localtime(now()).time()
1111
+ <= current_time.time()
1103
1112
  <= availability_hours.to_hour
1104
1113
  )
1105
1114
  return False
@@ -1210,6 +1219,7 @@ class StoreSerializer(ArabicFieldsMixin, FavoriteMixin, serializers.ModelSeriali
1210
1219
  shipping_methods = ShippingMethodSerializer(many=True, read_only=True)
1211
1220
  distance = serializers.SerializerMethodField()
1212
1221
  current_day_opening_hours = serializers.SerializerMethodField()
1222
+ timezone = serializers.SerializerMethodField()
1213
1223
 
1214
1224
  class Meta:
1215
1225
  model = Store
@@ -1238,6 +1248,7 @@ class StoreSerializer(ArabicFieldsMixin, FavoriteMixin, serializers.ModelSeriali
1238
1248
  "image",
1239
1249
  "busy_mode",
1240
1250
  "name_arabic",
1251
+ "timezone",
1241
1252
  )
1242
1253
  extra_kwargs = {
1243
1254
  "image": {"read_only": True, "required": False},
@@ -1246,12 +1257,12 @@ class StoreSerializer(ArabicFieldsMixin, FavoriteMixin, serializers.ModelSeriali
1246
1257
  def get_is_closed(self, obj):
1247
1258
  if obj.busy_mode:
1248
1259
  return True
1249
- current_time = localtime(now())
1260
+ current_time = localtime(now(), obj.timezone)
1250
1261
  current_op_hour = obj.current_opening_hours
1251
1262
  if current_op_hour:
1252
1263
  from_hour = current_op_hour.from_hour
1253
1264
  to_hour = current_op_hour.to_hour
1254
- if current_time.tzinfo.zone != "Asia/Dubai":
1265
+ if current_time.tzinfo != "Asia/Dubai":
1255
1266
  if obj.currency == "AED":
1256
1267
  try:
1257
1268
  current_time += timedelta(hours=1)
@@ -1365,6 +1376,9 @@ class StoreSerializer(ArabicFieldsMixin, FavoriteMixin, serializers.ModelSeriali
1365
1376
  op_hour = f"{settings.DEFAULT_OPENING_HOURS[0]['from_hour']} - {settings.DEFAULT_OPENING_HOURS[0]['to_hour']}"
1366
1377
  return op_hour
1367
1378
 
1379
+ def get_timezone(self, obj):
1380
+ return str(obj.timezone)
1381
+
1368
1382
  def to_representation(self, instance):
1369
1383
  return super().to_representation(instance)
1370
1384
 
@@ -1403,10 +1417,15 @@ class TaxSerializer(serializers.ModelSerializer):
1403
1417
 
1404
1418
 
1405
1419
  class StoreListSerializer(ArabicFieldsMixin, serializers.ModelSerializer):
1420
+ timezone = serializers.SerializerMethodField()
1421
+
1406
1422
  class Meta:
1407
1423
  model = Store
1408
1424
  fields = "__all__"
1409
1425
 
1426
+ def get_timezone(self, obj):
1427
+ return str(obj.timezone)
1428
+
1410
1429
 
1411
1430
  class GenericSerializer(serializers.Serializer):
1412
1431
  """
@@ -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
  ]
@@ -24,6 +24,7 @@ from ob_dj_store.core.stores.admin_inlines import (
24
24
  ProductAttributeInlineAdmin,
25
25
  ProductMediaInlineAdmin,
26
26
  ProductVariantInlineAdmin,
27
+ TipAmountInlineAdmin,
27
28
  )
28
29
 
29
30
 
@@ -112,6 +113,7 @@ class StoreAdmin(LeafletGeoAdmin):
112
113
  "pickup_addresses",
113
114
  "image",
114
115
  "currency",
116
+ "timezone",
115
117
  )
116
118
  },
117
119
  ),
@@ -534,6 +536,23 @@ class PartnerAuthInfoAdmin(admin.ModelAdmin):
534
536
  list_filter = ["authentication_expires", "partner"]
535
537
 
536
538
 
539
+ class TipAdmin(admin.ModelAdmin):
540
+ list_display = (
541
+ "id",
542
+ "name",
543
+ "description",
544
+ "is_active",
545
+ "country",
546
+ )
547
+ search_fields = [
548
+ "name",
549
+ ]
550
+ list_filter = ("country",)
551
+ inlines = [
552
+ TipAmountInlineAdmin,
553
+ ]
554
+
555
+
537
556
  admin.site.register(models.Store, StoreAdmin)
538
557
  admin.site.register(models.ShippingMethod, ShippingMethodAdmin)
539
558
  admin.site.register(models.PaymentMethod, PaymentMethodAdmin)
@@ -558,3 +577,4 @@ admin.site.register(models.Partner, PartnerAdmin)
558
577
  admin.site.register(models.Discount, DiscountAdmin)
559
578
  admin.site.register(models.PartnerAuthInfo, PartnerAuthInfoAdmin)
560
579
  admin.site.register(models.CountryPaymentMethod, CountryPaymentMethodAdmin)
580
+ admin.site.register(models.Tip, TipAdmin)
@@ -120,3 +120,8 @@ class InventoryOperationInlineAdmin(admin.TabularInline):
120
120
  class PartnerEmailDomainInlineAdmin(admin.TabularInline):
121
121
  model = models.PartnerEmailDomain
122
122
  extra = 1
123
+
124
+
125
+ class TipAmountInlineAdmin(admin.TabularInline):
126
+ model = models.TipAmount
127
+ extra = 0
@@ -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
+ ]
@@ -0,0 +1,98 @@
1
+ # Generated by Django 3.2.8 on 2025-10-27 14:39
2
+
3
+ import django.db.models.deletion
4
+ import django_countries.fields
5
+ from django.db import migrations, models
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ dependencies = [
11
+ ("stores", "0111_auto_20251023_1700"),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.CreateModel(
16
+ name="Tip",
17
+ fields=[
18
+ (
19
+ "id",
20
+ models.AutoField(
21
+ auto_created=True,
22
+ primary_key=True,
23
+ serialize=False,
24
+ verbose_name="ID",
25
+ ),
26
+ ),
27
+ ("name", models.CharField(max_length=150)),
28
+ ("description", models.TextField(blank=True, null=True)),
29
+ ("is_applied", models.BooleanField(default=True)),
30
+ (
31
+ "country",
32
+ django_countries.fields.CountryField(
33
+ blank=True, default="KW", max_length=2, null=True
34
+ ),
35
+ ),
36
+ ("is_active", models.BooleanField(default=False)),
37
+ ("created_at", models.DateTimeField(auto_now_add=True)),
38
+ ("updated_at", models.DateTimeField(auto_now=True)),
39
+ ],
40
+ options={"verbose_name": "Tip", "verbose_name_plural": "Tips",},
41
+ ),
42
+ migrations.AddField(
43
+ model_name="order",
44
+ name="tip_percentage",
45
+ field=models.DecimalField(
46
+ blank=True,
47
+ decimal_places=2,
48
+ help_text="Percentage value of the tip (e.g., 10 for 10%)",
49
+ max_digits=5,
50
+ null=True,
51
+ ),
52
+ ),
53
+ migrations.AddField(
54
+ model_name="order",
55
+ name="tip_value",
56
+ field=models.DecimalField(
57
+ blank=True, decimal_places=2, max_digits=5, null=True
58
+ ),
59
+ ),
60
+ migrations.CreateModel(
61
+ name="TipAmount",
62
+ fields=[
63
+ (
64
+ "id",
65
+ models.AutoField(
66
+ auto_created=True,
67
+ primary_key=True,
68
+ serialize=False,
69
+ verbose_name="ID",
70
+ ),
71
+ ),
72
+ (
73
+ "percentage",
74
+ models.DecimalField(
75
+ blank=True,
76
+ decimal_places=2,
77
+ help_text="Percentage value of the tip (e.g., 10 for 10%)",
78
+ max_digits=5,
79
+ null=True,
80
+ ),
81
+ ),
82
+ (
83
+ "tip",
84
+ models.ForeignKey(
85
+ blank=True,
86
+ null=True,
87
+ on_delete=django.db.models.deletion.CASCADE,
88
+ related_name="tip_amounts",
89
+ to="stores.tip",
90
+ ),
91
+ ),
92
+ ],
93
+ options={
94
+ "verbose_name": "Tip Amount",
95
+ "verbose_name_plural": "Tip Amounts",
96
+ },
97
+ ),
98
+ ]
@@ -7,7 +7,13 @@ from ob_dj_store.core.stores.models._feedback import (
7
7
  FeedbackConfig,
8
8
  )
9
9
  from ob_dj_store.core.stores.models._inventory import Inventory, InventoryOperations
10
- from ob_dj_store.core.stores.models._order import Order, OrderHistory, OrderItem
10
+ from ob_dj_store.core.stores.models._order import (
11
+ Order,
12
+ OrderHistory,
13
+ OrderItem,
14
+ Tip,
15
+ TipAmount,
16
+ )
11
17
  from ob_dj_store.core.stores.models._partner import (
12
18
  Discount,
13
19
  Partner,
@@ -85,4 +91,6 @@ __all__ = [
85
91
  "PartnerOTPAuth",
86
92
  "Discount",
87
93
  "CountryPaymentMethod",
94
+ "Tip",
95
+ "TipAmount",
88
96
  ]
@@ -1,10 +1,11 @@
1
- from decimal import Decimal
1
+ from decimal import ROUND_HALF_UP, Decimal
2
2
 
3
3
  from django.contrib.auth import get_user_model
4
4
  from django.core.exceptions import ObjectDoesNotExist, ValidationError
5
5
  from django.core.validators import MinValueValidator
6
6
  from django.db import models
7
7
  from django.utils.translation import gettext_lazy as _
8
+ from django_countries.fields import CountryField
8
9
 
9
10
  from ob_dj_store.core.stores.managers import OrderItemManager, OrderManager
10
11
  from ob_dj_store.utils.model import DjangoModelCleanMixin
@@ -92,6 +93,16 @@ class Order(DjangoModelCleanMixin, models.Model):
92
93
  init_data = models.JSONField(null=True, blank=True)
93
94
  offer_redeemed = models.BooleanField(default=False)
94
95
  offer_id = models.IntegerField(null=True, blank=True, default=None)
96
+ tip_percentage = models.DecimalField(
97
+ max_digits=5,
98
+ decimal_places=2,
99
+ null=True,
100
+ blank=True,
101
+ help_text=_("Percentage value of the tip (e.g., 10 for 10%)"),
102
+ )
103
+ tip_value = models.DecimalField(
104
+ max_digits=5, decimal_places=2, null=True, blank=True,
105
+ )
95
106
  # TODO: add pick_up_time maybe ?
96
107
  # audit fields
97
108
  created_at = models.DateTimeField(auto_now_add=True)
@@ -156,6 +167,17 @@ class Order(DjangoModelCleanMixin, models.Model):
156
167
  return self.OrderType.WALLET.value
157
168
  return self.OrderType.PHYSICAL.value
158
169
 
170
+ def calculate_tip(self):
171
+ """
172
+ Returns the tip amount based on a total order amount.
173
+ """
174
+ if not self.tip_percentage:
175
+ return Decimal("0.00")
176
+ tip_value = (self.total_amount * self.tip_percentage / Decimal("100")).quantize(
177
+ Decimal("0.01"), rounding=ROUND_HALF_UP
178
+ )
179
+ return tip_value
180
+
159
181
  def save(self, **kwargs):
160
182
  if not self.pk and self.shipping_address:
161
183
  self.immutable_shipping_address = self.shipping_address.to_immutable()
@@ -277,3 +299,38 @@ class OrderHistory(DjangoModelCleanMixin, models.Model):
277
299
 
278
300
  def __str__(self):
279
301
  return f"OrderHistory - {self.status}"
302
+
303
+
304
+ class TipAmount(models.Model):
305
+ percentage = models.DecimalField(
306
+ max_digits=5,
307
+ decimal_places=2,
308
+ null=True,
309
+ blank=True,
310
+ help_text=_("Percentage value of the tip (e.g., 10 for 10%)"),
311
+ )
312
+ tip = models.ForeignKey(
313
+ "Tip",
314
+ related_name="tip_amounts",
315
+ on_delete=models.CASCADE,
316
+ null=True,
317
+ blank=True,
318
+ )
319
+
320
+ class Meta:
321
+ verbose_name = _("Tip Amount")
322
+ verbose_name_plural = _("Tip Amounts")
323
+
324
+
325
+ class Tip(models.Model):
326
+ name = models.CharField(max_length=150)
327
+ description = models.TextField(null=True, blank=True)
328
+ is_applied = models.BooleanField(default=True)
329
+ country = CountryField(blank=True, null=True, default="KW")
330
+ is_active = models.BooleanField(default=False)
331
+ created_at = models.DateTimeField(auto_now_add=True)
332
+ updated_at = models.DateTimeField(auto_now=True)
333
+
334
+ class Meta:
335
+ verbose_name = _("Tip")
336
+ verbose_name_plural = _("Tips")
@@ -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=5,
39
- decimal_places=3,
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
  )
@@ -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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ob-dj-store
3
- Version: 0.0.22.3
3
+ Version: 0.0.22.5
4
4
  Summary: OBytes django application for managing ecommerce stores.
5
5
  Home-page: https://www.obytes.com/
6
6
  Author: OBytes
@@ -196,6 +196,8 @@ ob_dj_store/core/stores/migrations/0107_auto_20250425_2059.py
196
196
  ob_dj_store/core/stores/migrations/0108_alter_paymentmethod_payment_provider.py
197
197
  ob_dj_store/core/stores/migrations/0109_wallettransaction_cashback_type.py
198
198
  ob_dj_store/core/stores/migrations/0110_auto_20250923_1714.py
199
+ ob_dj_store/core/stores/migrations/0111_auto_20251023_1700.py
200
+ ob_dj_store/core/stores/migrations/0112_auto_20251027_1739.py
199
201
  ob_dj_store/core/stores/migrations/__init__.py
200
202
  ob_dj_store/core/stores/models/__init__.py
201
203
  ob_dj_store/core/stores/models/_address.py
File without changes
File without changes
File without changes