ob-dj-store 0.0.22.4__tar.gz → 0.0.22.6__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.4 → ob_dj_store-0.0.22.6}/PKG-INFO +1 -1
  2. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/stores/filters.py +15 -0
  3. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/stores/rest/serializers/serializers.py +39 -0
  4. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/stores/urls.py +4 -0
  5. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/stores/views.py +30 -0
  6. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/admin.py +19 -0
  7. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/admin_inlines.py +5 -0
  8. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/managers.py +4 -0
  9. ob_dj_store-0.0.22.6/ob_dj_store/core/stores/migrations/0112_auto_20251027_1739.py +98 -0
  10. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/models/__init__.py +9 -1
  11. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/models/_order.py +63 -2
  12. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store.egg-info/PKG-INFO +1 -1
  13. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store.egg-info/SOURCES.txt +1 -0
  14. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/.github/dependabot.yml +0 -0
  15. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/.github/workflows/docs.yml +0 -0
  16. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/.github/workflows/pre-release.yml +0 -0
  17. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/.github/workflows/release.yml +0 -0
  18. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/.github/workflows/test-build.yml +0 -0
  19. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/.gitignore +0 -0
  20. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/.isort.cfg +0 -0
  21. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/.pre-commit-config.yaml +0 -0
  22. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/Dockerfile +0 -0
  23. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/MANIFEST.in +0 -0
  24. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/Makefile +0 -0
  25. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/Pipfile +0 -0
  26. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/Pipfile.lock +0 -0
  27. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/README.md +0 -0
  28. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/config/__init__.py +0 -0
  29. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/config/settings.py +0 -0
  30. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/config/urls.py +0 -0
  31. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/config/wsgi.py +0 -0
  32. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/docker-compose.env +0 -0
  33. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/docker-compose.yml +0 -0
  34. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/docs/Makefile +0 -0
  35. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/docs/make.bat +0 -0
  36. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/docs/source/admin.rst +0 -0
  37. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/docs/source/conf.py +0 -0
  38. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/docs/source/index.rst +0 -0
  39. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/docs/source/installation.rst +0 -0
  40. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/docs/source/models.rst +0 -0
  41. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/docs/source/rest_endpoints.rst +0 -0
  42. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/fixtures/initial_users.yaml +0 -0
  43. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/fixtures/stores.yaml +0 -0
  44. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/manage.py +0 -0
  45. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/__init__.py +0 -0
  46. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/__init__.py +0 -0
  47. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/stores/__init__.py +0 -0
  48. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/stripe/__init__.py +0 -0
  49. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/stripe/serializers.py +0 -0
  50. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/stripe/urls.py +0 -0
  51. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/stripe/views.py +0 -0
  52. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/tap/__init__.py +0 -0
  53. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/tap/serializers.py +0 -0
  54. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/tap/urls.py +0 -0
  55. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/apis/tap/views.py +0 -0
  56. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/__init__.py +0 -0
  57. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/__init__.py +0 -0
  58. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/apps.py +0 -0
  59. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/__init__.py +0 -0
  60. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/stripe/__init__.py +0 -0
  61. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/stripe/admin.py +0 -0
  62. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/stripe/apps.py +0 -0
  63. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/stripe/managers.py +0 -0
  64. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/stripe/migrations/0001_initial.py +0 -0
  65. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/stripe/migrations/__init__.py +0 -0
  66. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/stripe/models.py +0 -0
  67. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/stripe/utils.py +0 -0
  68. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/__init__.py +0 -0
  69. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/admin.py +0 -0
  70. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/apps.py +0 -0
  71. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/managers.py +0 -0
  72. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/migrations/0001_initial.py +0 -0
  73. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/migrations/0002_auto_20220815_1610.py +0 -0
  74. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/migrations/0003_auto_20220818_1938.py +0 -0
  75. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/migrations/0004_tapcustomer.py +0 -0
  76. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/migrations/0005_alter_tappayment_payment_url.py +0 -0
  77. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/migrations/0006_alter_tappayment_source.py +0 -0
  78. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/migrations/0007_alter_tappayment_source.py +0 -0
  79. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/migrations/0008_alter_tappayment_user.py +0 -0
  80. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/migrations/__init__.py +0 -0
  81. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/models.py +0 -0
  82. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/gateway/tap/utils.py +0 -0
  83. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0001_initial.py +0 -0
  84. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0002_auto_20220422_0205.py +0 -0
  85. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0003_openinghours.py +0 -0
  86. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0004_auto_20220422_2326.py +0 -0
  87. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0005_auto_20220425_2119.py +0 -0
  88. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0005_auto_20220427_1729.py +0 -0
  89. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0006_auto_20220428_0100.py +0 -0
  90. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0007_cart_cartitem_order_orderitem.py +0 -0
  91. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0008_order_status.py +0 -0
  92. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0009_auto_20220508_2142.py +0 -0
  93. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0010_auto_20220509_1633.py +0 -0
  94. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0011_favorite.py +0 -0
  95. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0012_auto_20220514_0633.py +0 -0
  96. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0013_auto_20220518_1539.py +0 -0
  97. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0014_auto_20220519_0018.py +0 -0
  98. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0015_inventory_inventoryoperations.py +0 -0
  99. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0016_productvariant_preparation_time.py +0 -0
  100. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0017_auto_20220524_0912.py +0 -0
  101. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0018_auto_20220524_1613.py +0 -0
  102. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0019_product_is_featured.py +0 -0
  103. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0020_orderhistory.py +0 -0
  104. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0021_auto_20220531_1849.py +0 -0
  105. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0022_order_pickup_time.py +0 -0
  106. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0023_feedback_feedbackattribute_feedbackconfig.py +0 -0
  107. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0024_auto_20220609_1552.py +0 -0
  108. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0025_productvariant_is_primary.py +0 -0
  109. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0026_auto_20220630_1913.py +0 -0
  110. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0027_auto_20220713_1759.py +0 -0
  111. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0028_phonecontact.py +0 -0
  112. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0029_auto_20220726_1750.py +0 -0
  113. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0030_category_parent.py +0 -0
  114. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0031_auto_20220811_1733.py +0 -0
  115. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0032_auto_20220812_1951.py +0 -0
  116. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0033_auto_20220815_0133.py +0 -0
  117. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0034_auto_20220815_1528.py +0 -0
  118. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0035_auto_20220818_1938.py +0 -0
  119. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0036_productattribute_is_mandatory.py +0 -0
  120. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0037_auto_20220825_1736.py +0 -0
  121. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0038_cartitem_extra_infos.py +0 -0
  122. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0039_auto_20220831_1521.py +0 -0
  123. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0040_auto_20220902_1806.py +0 -0
  124. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0041_auto_20220912_1506.py +0 -0
  125. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0042_wallet_wallettransaction.py +0 -0
  126. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0043_auto_20220919_1854.py +0 -0
  127. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0044_remove_productvariant_has_inventory.py +0 -0
  128. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0045_shippingmethod_type.py +0 -0
  129. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0046_auto_20221014_1720.py +0 -0
  130. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0047_auto_20221018_1433.py +0 -0
  131. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0048_auto_20221026_1933.py +0 -0
  132. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0049_auto_20221029_1524.py +0 -0
  133. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0050_favoriteextra.py +0 -0
  134. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0051_order_car_id.py +0 -0
  135. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0052_auto_20221129_1732.py +0 -0
  136. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0053_inventory_plu.py +0 -0
  137. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0054_auto_20221230_1501.py +0 -0
  138. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0055_store_image.py +0 -0
  139. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0056_auto_20230213_2224.py +0 -0
  140. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0057_auto_20230214_1724.py +0 -0
  141. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0058_attributechoice_is_default.py +0 -0
  142. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0059_auto_20230217_2006.py +0 -0
  143. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0060_alter_orderitem_product_variant.py +0 -0
  144. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0061_auto_20230223_1435.py +0 -0
  145. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0062_auto_20230226_2005.py +0 -0
  146. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0063_alter_store_payment_methods.py +0 -0
  147. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0064_auto_20230228_1814.py +0 -0
  148. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0065_auto_20230228_1932.py +0 -0
  149. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0066_auto_20230304_1532.py +0 -0
  150. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0067_auto_20230309_2014.py +0 -0
  151. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0068_auto_20230309_2251.py +0 -0
  152. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0069_alter_cartitem_options.py +0 -0
  153. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0070_auto_20230323_1628.py +0 -0
  154. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0071_auto_20230328_1825.py +0 -0
  155. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0072_alter_order_extra_infos.py +0 -0
  156. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0073_wallettransaction_is_cashback.py +0 -0
  157. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0074_productvariant_label.py +0 -0
  158. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0075_auto_20230419_0259.py +0 -0
  159. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0076_auto_20230421_1343.py +0 -0
  160. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0077_auto_20230502_2005.py +0 -0
  161. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0078_auto_20230503_1259.py +0 -0
  162. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0079_auto_20230504_1919.py +0 -0
  163. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0080_productvariant_description.py +0 -0
  164. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0081_storeattributechoice.py +0 -0
  165. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0082_auto_20230613_1424.py +0 -0
  166. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0083_productvariant_is_special.py +0 -0
  167. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0084_payment_result.py +0 -0
  168. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0085_auto_20230726_1528.py +0 -0
  169. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0086_wallet_is_active.py +0 -0
  170. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0087_auto_20230828_2138.py +0 -0
  171. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0088_alter_paymentmethod_payment_provider.py +0 -0
  172. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0089_discount_partner_partnerauthinfo_partneremaildomain_partnerotpauth.py +0 -0
  173. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0090_auto_20231006_1356.py +0 -0
  174. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0091_auto_20231010_1740.py +0 -0
  175. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0092_auto_20231012_1339.py +0 -0
  176. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0093_auto_20231017_2033.py +0 -0
  177. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0094_countrypaymentmethod.py +0 -0
  178. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0095_auto_20231101_1531.py +0 -0
  179. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0096_discount_discount_pos_id.py +0 -0
  180. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0097_auto_20231108_1939.py +0 -0
  181. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0098_alter_discount_discount_rate.py +0 -0
  182. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0099_alter_product_name_arabic.py +0 -0
  183. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0100_remove_shippingmethod_type_arabic.py +0 -0
  184. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0101_store_is_digital.py +0 -0
  185. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0102_partner_name_arabic.py +0 -0
  186. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0103_alter_paymentmethod_payment_provider.py +0 -0
  187. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0104_wallettransaction_is_redeemed.py +0 -0
  188. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0105_store_is_open_after_midnight.py +0 -0
  189. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0106_alter_paymentmethod_payment_provider.py +0 -0
  190. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0107_auto_20250425_2059.py +0 -0
  191. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0108_alter_paymentmethod_payment_provider.py +0 -0
  192. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0109_wallettransaction_cashback_type.py +0 -0
  193. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0110_auto_20250923_1714.py +0 -0
  194. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/0111_auto_20251023_1700.py +0 -0
  195. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/migrations/__init__.py +0 -0
  196. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/models/_address.py +0 -0
  197. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/models/_cart.py +0 -0
  198. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/models/_favorite.py +0 -0
  199. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/models/_feedback.py +0 -0
  200. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/models/_inventory.py +0 -0
  201. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/models/_partner.py +0 -0
  202. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/models/_payment.py +0 -0
  203. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/models/_product.py +0 -0
  204. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/models/_store.py +0 -0
  205. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/models/_wallet.py +0 -0
  206. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/receivers.py +0 -0
  207. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/settings_validation.py +0 -0
  208. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/core/stores/utils.py +0 -0
  209. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/utils/__init__.py +0 -0
  210. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/utils/helpers.py +0 -0
  211. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/utils/model.py +0 -0
  212. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store/utils/utils.py +0 -0
  213. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store.egg-info/dependency_links.txt +0 -0
  214. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store.egg-info/requires.txt +0 -0
  215. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/ob_dj_store.egg-info/top_level.txt +0 -0
  216. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/pytest.ini +0 -0
  217. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/setup.cfg +0 -0
  218. {ob_dj_store-0.0.22.4 → ob_dj_store-0.0.22.6}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ob-dj-store
3
- Version: 0.0.22.4
3
+ Version: 0.0.22.6
4
4
  Summary: OBytes django application for managing ecommerce stores.
5
5
  Home-page: https://www.obytes.com/
6
6
  Author: OBytes
@@ -19,6 +19,7 @@ from ob_dj_store.core.stores.models import (
19
19
  Product,
20
20
  ProductVariant,
21
21
  Store,
22
+ Tip,
22
23
  )
23
24
  from ob_dj_store.core.stores.models._inventory import Inventory
24
25
  from ob_dj_store.core.stores.models._wallet import Wallet
@@ -322,3 +323,17 @@ class CountryPaymentMethodFilter(filters.FilterSet):
322
323
  def by_country(self, queryset, name, value):
323
324
  if value:
324
325
  return queryset.filter(country=value)
326
+
327
+
328
+ class TipFilter(filters.FilterSet):
329
+
330
+ country = filters.CharFilter(method="by_country")
331
+
332
+ class Meta:
333
+ model = Tip
334
+ fields = []
335
+
336
+ def by_country(self, queryset, name, value):
337
+ if value:
338
+ queryset = queryset.filter(country=value)
339
+ return queryset
@@ -52,6 +52,8 @@ from ob_dj_store.core.stores.models import (
52
52
  ShippingMethod,
53
53
  Store,
54
54
  Tax,
55
+ Tip,
56
+ TipAmount,
55
57
  Wallet,
56
58
  WalletMedia,
57
59
  WalletTransaction,
@@ -284,6 +286,8 @@ class OrderSerializer(serializers.ModelSerializer):
284
286
  "created_at",
285
287
  "updated_at",
286
288
  "store_name",
289
+ "tip_percentage",
290
+ "tip_value",
287
291
  )
288
292
  extra_kwargs = {
289
293
  "customer": {"read_only": True},
@@ -614,7 +618,11 @@ class OrderSerializer(serializers.ModelSerializer):
614
618
  attributes=list(item.attribute_choices.all()),
615
619
  notes=item.notes,
616
620
  )
621
+ if order.tip_percentage:
622
+ order.tip_value = order.calculate_tip()
623
+ order.save()
617
624
  orders.append(order)
625
+
618
626
  amount = Decimal(
619
627
  sum(map(lambda order: Decimal(order.total_amount) or 0, orders))
620
628
  )
@@ -1990,3 +1998,34 @@ class CountryPaymentMethodSerialzier(serializers.ModelSerializer):
1990
1998
  instance=qs, context=self.context, many=True
1991
1999
  ).data
1992
2000
  return data
2001
+
2002
+
2003
+ class TipSerializer(serializers.ModelSerializer):
2004
+ tip_amounts = serializers.SerializerMethodField()
2005
+
2006
+ class Meta:
2007
+ model = Tip
2008
+ fields = (
2009
+ "id",
2010
+ "name",
2011
+ "description",
2012
+ "is_applied",
2013
+ "country",
2014
+ "is_active",
2015
+ "tip_amounts",
2016
+ )
2017
+
2018
+ def get_tip_amounts(self, obj):
2019
+ from .serializers import TipAmountSerializer # avoid circular import
2020
+
2021
+ tip_amounts = obj.tip_amounts.all()
2022
+ return TipAmountSerializer(tip_amounts, many=True).data
2023
+
2024
+
2025
+ class TipAmountSerializer(serializers.ModelSerializer):
2026
+ class Meta:
2027
+ model = TipAmount
2028
+ fields = (
2029
+ "id",
2030
+ "percentage",
2031
+ )
@@ -18,6 +18,7 @@ from ob_dj_store.apis.stores.views import (
18
18
  ShippingMethodViewSet,
19
19
  StoreView,
20
20
  TaxViewSet,
21
+ TipsViewSet,
21
22
  TransactionsViewSet,
22
23
  VariantView,
23
24
  WalletV2ViewSet,
@@ -54,6 +55,9 @@ router.register(
54
55
  CountryPaymentMethodsViewSet,
55
56
  basename="country-payment-methods",
56
57
  )
58
+ router.register(
59
+ r"tip", TipsViewSet, basename="tip",
60
+ )
57
61
 
58
62
  urlpatterns = [
59
63
  path(r"", include(router.urls)),
@@ -32,6 +32,7 @@ from ob_dj_store.apis.stores.filters import (
32
32
  PaymentMethodFilter,
33
33
  ProductFilter,
34
34
  StoreFilter,
35
+ TipFilter,
35
36
  VariantFilter,
36
37
  WalletFilter,
37
38
  )
@@ -58,6 +59,7 @@ from ob_dj_store.apis.stores.rest.serializers.serializers import (
58
59
  ShippingMethodSerializer,
59
60
  StoreSerializer,
60
61
  TaxSerializer,
62
+ TipSerializer,
61
63
  WalletMediaSerializer,
62
64
  WalletSerializer,
63
65
  WalletTopUpSerializer,
@@ -85,6 +87,7 @@ from ob_dj_store.core.stores.models import (
85
87
  ShippingMethod,
86
88
  Store,
87
89
  Tax,
90
+ Tip,
88
91
  Wallet,
89
92
  WalletMedia,
90
93
  )
@@ -1327,3 +1330,30 @@ class CountryPaymentMethodsViewSet(
1327
1330
  )
1328
1331
  def retrieve(self, request, *args, **kwargs):
1329
1332
  return super().retrieve(request, *args, **kwargs)
1333
+
1334
+
1335
+ class TipsViewSet(
1336
+ mixins.ListModelMixin, viewsets.GenericViewSet,
1337
+ ):
1338
+ queryset = Tip.objects.active()
1339
+ serializer_class = TipSerializer
1340
+ filterset_class = TipFilter
1341
+ filter_backends = [DjangoFilterBackend]
1342
+ permission_classes = [
1343
+ permissions.IsAuthenticated,
1344
+ ]
1345
+
1346
+ def get_queryset(self):
1347
+ return self.filter_queryset(super().get_queryset())
1348
+
1349
+ @swagger_auto_schema(
1350
+ operation_summary="list al tips",
1351
+ operation_description="""
1352
+ list all tips
1353
+ """,
1354
+ tags=["Tip",],
1355
+ )
1356
+ def list(
1357
+ self, request: Request, *args: typing.Any, **kwargs: typing.Any
1358
+ ) -> Response:
1359
+ return super().list(request=request, *args, **kwargs)
@@ -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
 
@@ -535,6 +536,23 @@ class PartnerAuthInfoAdmin(admin.ModelAdmin):
535
536
  list_filter = ["authentication_expires", "partner"]
536
537
 
537
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
+
538
556
  admin.site.register(models.Store, StoreAdmin)
539
557
  admin.site.register(models.ShippingMethod, ShippingMethodAdmin)
540
558
  admin.site.register(models.PaymentMethod, PaymentMethodAdmin)
@@ -559,3 +577,4 @@ admin.site.register(models.Partner, PartnerAdmin)
559
577
  admin.site.register(models.Discount, DiscountAdmin)
560
578
  admin.site.register(models.PartnerAuthInfo, PartnerAuthInfoAdmin)
561
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
@@ -291,3 +291,7 @@ class PartnerAuthInfoManager(models.Manager):
291
291
 
292
292
  class CountryPaymentMethodManager(ActiveMixin, models.Manager):
293
293
  pass
294
+
295
+
296
+ class TipManager(ActiveMixin, models.Manager):
297
+ pass
@@ -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,12 +1,13 @@
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
- from ob_dj_store.core.stores.managers import OrderItemManager, OrderManager
10
+ from ob_dj_store.core.stores.managers import OrderItemManager, OrderManager, TipManager
10
11
  from ob_dj_store.utils.model import DjangoModelCleanMixin
11
12
 
12
13
 
@@ -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)
@@ -137,6 +148,8 @@ class Order(DjangoModelCleanMixin, models.Model):
137
148
  )
138
149
  if self.shipping_method:
139
150
  amount += self.shipping_method.shipping_fee
151
+ if self.tip_value:
152
+ amount += self.tip_value
140
153
  amount -= self.get_discount_amount
141
154
  return amount
142
155
 
@@ -156,6 +169,17 @@ class Order(DjangoModelCleanMixin, models.Model):
156
169
  return self.OrderType.WALLET.value
157
170
  return self.OrderType.PHYSICAL.value
158
171
 
172
+ def calculate_tip(self):
173
+ """
174
+ Returns the tip amount based on a total order amount.
175
+ """
176
+ if not self.tip_percentage:
177
+ return Decimal("0.00")
178
+ tip_value = (self.total_amount * self.tip_percentage / Decimal("100")).quantize(
179
+ Decimal("0.01"), rounding=ROUND_HALF_UP
180
+ )
181
+ return tip_value
182
+
159
183
  def save(self, **kwargs):
160
184
  if not self.pk and self.shipping_address:
161
185
  self.immutable_shipping_address = self.shipping_address.to_immutable()
@@ -277,3 +301,40 @@ class OrderHistory(DjangoModelCleanMixin, models.Model):
277
301
 
278
302
  def __str__(self):
279
303
  return f"OrderHistory - {self.status}"
304
+
305
+
306
+ class TipAmount(models.Model):
307
+ percentage = models.DecimalField(
308
+ max_digits=5,
309
+ decimal_places=2,
310
+ null=True,
311
+ blank=True,
312
+ help_text=_("Percentage value of the tip (e.g., 10 for 10%)"),
313
+ )
314
+ tip = models.ForeignKey(
315
+ "Tip",
316
+ related_name="tip_amounts",
317
+ on_delete=models.CASCADE,
318
+ null=True,
319
+ blank=True,
320
+ )
321
+
322
+ class Meta:
323
+ verbose_name = _("Tip Amount")
324
+ verbose_name_plural = _("Tip Amounts")
325
+
326
+
327
+ class Tip(models.Model):
328
+ name = models.CharField(max_length=150)
329
+ description = models.TextField(null=True, blank=True)
330
+ is_applied = models.BooleanField(default=True)
331
+ country = CountryField(blank=True, null=True, default="KW")
332
+ is_active = models.BooleanField(default=False)
333
+ created_at = models.DateTimeField(auto_now_add=True)
334
+ updated_at = models.DateTimeField(auto_now=True)
335
+
336
+ objects = TipManager()
337
+
338
+ class Meta:
339
+ verbose_name = _("Tip")
340
+ verbose_name_plural = _("Tips")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ob-dj-store
3
- Version: 0.0.22.4
3
+ Version: 0.0.22.6
4
4
  Summary: OBytes django application for managing ecommerce stores.
5
5
  Home-page: https://www.obytes.com/
6
6
  Author: OBytes
@@ -197,6 +197,7 @@ 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
199
  ob_dj_store/core/stores/migrations/0111_auto_20251023_1700.py
200
+ ob_dj_store/core/stores/migrations/0112_auto_20251027_1739.py
200
201
  ob_dj_store/core/stores/migrations/__init__.py
201
202
  ob_dj_store/core/stores/models/__init__.py
202
203
  ob_dj_store/core/stores/models/_address.py
File without changes
File without changes
File without changes
File without changes