django-cfg 1.2.27__py3-none-any.whl → 1.2.31__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.
Files changed (138) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/payments/admin/__init__.py +3 -2
  3. django_cfg/apps/payments/admin/balance_admin.py +18 -18
  4. django_cfg/apps/payments/admin/currencies_admin.py +319 -131
  5. django_cfg/apps/payments/admin/payments_admin.py +15 -4
  6. django_cfg/apps/payments/config/module.py +2 -2
  7. django_cfg/apps/payments/config/utils.py +2 -2
  8. django_cfg/apps/payments/decorators.py +2 -2
  9. django_cfg/apps/payments/management/commands/README.md +95 -127
  10. django_cfg/apps/payments/management/commands/currency_stats.py +5 -24
  11. django_cfg/apps/payments/management/commands/manage_currencies.py +229 -0
  12. django_cfg/apps/payments/management/commands/manage_providers.py +235 -0
  13. django_cfg/apps/payments/managers/__init__.py +3 -2
  14. django_cfg/apps/payments/managers/balance_manager.py +2 -2
  15. django_cfg/apps/payments/managers/currency_manager.py +272 -49
  16. django_cfg/apps/payments/managers/payment_manager.py +161 -13
  17. django_cfg/apps/payments/middleware/api_access.py +2 -2
  18. django_cfg/apps/payments/middleware/rate_limiting.py +8 -18
  19. django_cfg/apps/payments/middleware/usage_tracking.py +20 -17
  20. django_cfg/apps/payments/migrations/0002_network_providercurrency_and_more.py +241 -0
  21. django_cfg/apps/payments/migrations/0003_add_usd_rate_cache.py +30 -0
  22. django_cfg/apps/payments/models/__init__.py +3 -2
  23. django_cfg/apps/payments/models/currencies.py +187 -71
  24. django_cfg/apps/payments/models/payments.py +3 -2
  25. django_cfg/apps/payments/serializers/__init__.py +3 -2
  26. django_cfg/apps/payments/serializers/currencies.py +20 -12
  27. django_cfg/apps/payments/services/cache/simple_cache.py +2 -2
  28. django_cfg/apps/payments/services/core/balance_service.py +2 -2
  29. django_cfg/apps/payments/services/core/fallback_service.py +2 -2
  30. django_cfg/apps/payments/services/core/payment_service.py +3 -6
  31. django_cfg/apps/payments/services/core/subscription_service.py +4 -7
  32. django_cfg/apps/payments/services/internal_types.py +171 -7
  33. django_cfg/apps/payments/services/monitoring/api_schemas.py +58 -204
  34. django_cfg/apps/payments/services/monitoring/provider_health.py +2 -2
  35. django_cfg/apps/payments/services/providers/base.py +144 -43
  36. django_cfg/apps/payments/services/providers/cryptapi/__init__.py +4 -0
  37. django_cfg/apps/payments/services/providers/cryptapi/config.py +8 -0
  38. django_cfg/apps/payments/services/providers/cryptapi/models.py +192 -0
  39. django_cfg/apps/payments/services/providers/cryptapi/provider.py +439 -0
  40. django_cfg/apps/payments/services/providers/cryptomus/__init__.py +4 -0
  41. django_cfg/apps/payments/services/providers/cryptomus/models.py +176 -0
  42. django_cfg/apps/payments/services/providers/cryptomus/provider.py +429 -0
  43. django_cfg/apps/payments/services/providers/cryptomus/provider_v2.py +564 -0
  44. django_cfg/apps/payments/services/providers/models/__init__.py +34 -0
  45. django_cfg/apps/payments/services/providers/models/currencies.py +190 -0
  46. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -0
  47. django_cfg/apps/payments/services/providers/nowpayments/models.py +196 -0
  48. django_cfg/apps/payments/services/providers/nowpayments/provider.py +380 -0
  49. django_cfg/apps/payments/services/providers/registry.py +294 -11
  50. django_cfg/apps/payments/services/providers/stripe/__init__.py +4 -0
  51. django_cfg/apps/payments/services/providers/stripe/models.py +184 -0
  52. django_cfg/apps/payments/services/providers/stripe/provider.py +109 -0
  53. django_cfg/apps/payments/services/security/error_handler.py +6 -8
  54. django_cfg/apps/payments/services/security/payment_notifications.py +2 -2
  55. django_cfg/apps/payments/services/security/webhook_validator.py +3 -4
  56. django_cfg/apps/payments/signals/api_key_signals.py +2 -2
  57. django_cfg/apps/payments/signals/payment_signals.py +11 -5
  58. django_cfg/apps/payments/signals/subscription_signals.py +2 -2
  59. django_cfg/apps/payments/static/payments/css/payments.css +340 -0
  60. django_cfg/apps/payments/static/payments/js/notifications.js +202 -0
  61. django_cfg/apps/payments/static/payments/js/payment-utils.js +318 -0
  62. django_cfg/apps/payments/static/payments/js/theme.js +86 -0
  63. django_cfg/apps/payments/tasks/webhook_processing.py +2 -2
  64. django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +50 -0
  65. django_cfg/apps/payments/templates/payments/base.html +182 -0
  66. django_cfg/apps/payments/templates/payments/components/payment_card.html +201 -0
  67. django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +109 -0
  68. django_cfg/apps/payments/templates/payments/components/progress_bar.html +43 -0
  69. django_cfg/apps/payments/templates/payments/components/provider_stats.html +40 -0
  70. django_cfg/apps/payments/templates/payments/components/status_badge.html +34 -0
  71. django_cfg/apps/payments/templates/payments/components/status_overview.html +148 -0
  72. django_cfg/apps/payments/templates/payments/dashboard.html +258 -0
  73. django_cfg/apps/payments/templates/payments/dashboard_simple_test.html +35 -0
  74. django_cfg/apps/payments/templates/payments/payment_create.html +579 -0
  75. django_cfg/apps/payments/templates/payments/payment_detail.html +373 -0
  76. django_cfg/apps/payments/templates/payments/payment_list.html +354 -0
  77. django_cfg/apps/payments/templates/payments/stats.html +261 -0
  78. django_cfg/apps/payments/templates/payments/test.html +213 -0
  79. django_cfg/apps/payments/templatetags/__init__.py +1 -0
  80. django_cfg/apps/payments/templatetags/payments_tags.py +315 -0
  81. django_cfg/apps/payments/urls.py +3 -1
  82. django_cfg/apps/payments/urls_admin.py +58 -0
  83. django_cfg/apps/payments/utils/__init__.py +1 -3
  84. django_cfg/apps/payments/utils/billing_utils.py +2 -2
  85. django_cfg/apps/payments/utils/config_utils.py +2 -8
  86. django_cfg/apps/payments/utils/validation_utils.py +2 -2
  87. django_cfg/apps/payments/views/__init__.py +3 -2
  88. django_cfg/apps/payments/views/currency_views.py +31 -20
  89. django_cfg/apps/payments/views/payment_views.py +2 -2
  90. django_cfg/apps/payments/views/templates/__init__.py +25 -0
  91. django_cfg/apps/payments/views/templates/ajax.py +451 -0
  92. django_cfg/apps/payments/views/templates/base.py +212 -0
  93. django_cfg/apps/payments/views/templates/dashboard.py +60 -0
  94. django_cfg/apps/payments/views/templates/payment_detail.py +102 -0
  95. django_cfg/apps/payments/views/templates/payment_management.py +158 -0
  96. django_cfg/apps/payments/views/templates/qr_code.py +174 -0
  97. django_cfg/apps/payments/views/templates/stats.py +244 -0
  98. django_cfg/apps/payments/views/templates/utils.py +181 -0
  99. django_cfg/apps/payments/views/webhook_views.py +2 -2
  100. django_cfg/apps/payments/viewsets.py +3 -2
  101. django_cfg/apps/tasks/urls.py +0 -2
  102. django_cfg/apps/tasks/urls_admin.py +14 -0
  103. django_cfg/apps/urls.py +6 -3
  104. django_cfg/core/config.py +35 -0
  105. django_cfg/models/payments.py +2 -8
  106. django_cfg/modules/django_currency/__init__.py +16 -11
  107. django_cfg/modules/django_currency/clients/__init__.py +4 -4
  108. django_cfg/modules/django_currency/clients/coinpaprika_client.py +289 -0
  109. django_cfg/modules/django_currency/clients/yahoo_client.py +157 -0
  110. django_cfg/modules/django_currency/core/__init__.py +1 -7
  111. django_cfg/modules/django_currency/core/converter.py +18 -23
  112. django_cfg/modules/django_currency/core/models.py +122 -11
  113. django_cfg/modules/django_currency/database/__init__.py +4 -4
  114. django_cfg/modules/django_currency/database/database_loader.py +190 -309
  115. django_cfg/modules/django_unfold/dashboard.py +7 -2
  116. django_cfg/registry/core.py +1 -0
  117. django_cfg/template_archive/.gitignore +1 -0
  118. django_cfg/template_archive/django_sample.zip +0 -0
  119. django_cfg/templates/admin/components/action_grid.html +9 -9
  120. django_cfg/templates/admin/components/metric_card.html +5 -5
  121. django_cfg/templates/admin/components/status_badge.html +2 -2
  122. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +152 -24
  123. django_cfg/templates/admin/snippets/components/quick_actions.html +3 -3
  124. django_cfg/templates/admin/snippets/components/system_health.html +1 -1
  125. django_cfg/templates/admin/snippets/tabs/overview_tab.html +49 -52
  126. {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/METADATA +13 -18
  127. {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/RECORD +130 -83
  128. django_cfg/apps/payments/management/commands/populate_currencies.py +0 -246
  129. django_cfg/apps/payments/management/commands/update_currencies.py +0 -336
  130. django_cfg/apps/payments/services/providers/cryptapi.py +0 -273
  131. django_cfg/apps/payments/services/providers/cryptomus.py +0 -310
  132. django_cfg/apps/payments/services/providers/nowpayments.py +0 -293
  133. django_cfg/apps/payments/services/validators/__init__.py +0 -8
  134. django_cfg/modules/django_currency/clients/coingecko_client.py +0 -257
  135. django_cfg/modules/django_currency/clients/yfinance_client.py +0 -246
  136. {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/WHEEL +0 -0
  137. {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/entry_points.txt +0 -0
  138. {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/licenses/LICENSE +0 -0
@@ -10,6 +10,9 @@ from unfold.decorators import display
10
10
 
11
11
  from ..models import UniversalPayment
12
12
  from .filters import PaymentStatusFilter, PaymentAmountFilter, UserEmailFilter, RecentActivityFilter
13
+ from django_cfg.modules.django_logger import get_logger
14
+
15
+ logger = get_logger("payments_admin")
13
16
 
14
17
 
15
18
  @admin.register(UniversalPayment)
@@ -35,6 +38,10 @@ class UniversalPaymentAdmin(ModelAdmin):
35
38
  'user__last_name'
36
39
  ]
37
40
 
41
+ def get_queryset(self, request):
42
+ """Optimize queryset to prevent N+1 queries."""
43
+ return super().get_queryset(request).optimized()
44
+
38
45
  list_filter = [
39
46
  PaymentStatusFilter,
40
47
  PaymentAmountFilter,
@@ -59,12 +66,16 @@ class UniversalPaymentAdmin(ModelAdmin):
59
66
  ('Payment Details', {
60
67
  'fields': ['internal_payment_id', 'provider_payment_id', 'provider', 'status']
61
68
  }),
69
+ ('Crypto Details', {
70
+ 'fields': ['pay_address', 'pay_amount', 'network', 'security_nonce', 'transaction_hash', 'sender_address', 'receiver_address', 'crypto_amount', 'confirmations_count'],
71
+ 'classes': ['collapse']
72
+ }),
62
73
  ('Provider Data', {
63
- 'fields': ['provider_data'],
74
+ 'fields': ['metadata', 'webhook_data'],
64
75
  'classes': ['collapse']
65
76
  }),
66
77
  ('Timestamps', {
67
- 'fields': ['created_at', 'updated_at'],
78
+ 'fields': ['created_at', 'updated_at', 'expires_at', 'completed_at', 'processed_at'],
68
79
  'classes': ['collapse']
69
80
  })
70
81
  ]
@@ -91,8 +102,8 @@ class UniversalPaymentAdmin(ModelAdmin):
91
102
  def amount_display(self, obj):
92
103
  """Display amount with currency."""
93
104
  return format_html(
94
- '<span style="font-weight: bold; font-size: 14px;">${:.2f}</span><br><small>{}</small>',
95
- obj.amount_usd,
105
+ '<span style="font-weight: bold; font-size: 14px;">${}</span><br><small>{}</small>',
106
+ f"{float(obj.amount_usd):.2f}",
96
107
  obj.currency_code
97
108
  )
98
109
 
@@ -5,12 +5,12 @@ Handles loading and managing payment configurations from project settings.
5
5
  """
6
6
 
7
7
  from typing import Optional
8
- import logging
8
+ from django_cfg.modules.django_logger import get_logger
9
9
 
10
10
  from django_cfg.modules.base import BaseCfgModule
11
11
  from .settings import PaymentsSettings
12
12
 
13
- logger = logging.getLogger(__name__)
13
+ logger = get_logger("config_module")
14
14
 
15
15
 
16
16
  class PaymentsCfgModule(BaseCfgModule):
@@ -5,13 +5,13 @@ Helper functions for working with payment configurations.
5
5
  """
6
6
 
7
7
  from typing import Optional
8
- import logging
8
+ from django_cfg.modules.django_logger import get_logger
9
9
 
10
10
  from .module import PaymentsCfgModule
11
11
  from .settings import PaymentsSettings
12
12
  from django_cfg.models.payments import PaymentProviderConfig
13
13
 
14
- logger = logging.getLogger(__name__)
14
+ logger = get_logger("config_utils")
15
15
 
16
16
  # Global payments configuration instance
17
17
  _payments_config = PaymentsCfgModule()
@@ -3,14 +3,14 @@ Decorators for API access control and endpoint registration.
3
3
  """
4
4
 
5
5
  import functools
6
- import logging
6
+ from django_cfg.modules.django_logger import get_logger
7
7
  from typing import Optional, List, Callable, Any
8
8
  from django.http import JsonResponse
9
9
  from django.conf import settings
10
10
  from django.utils import timezone
11
11
  from .models import EndpointGroup, Subscription
12
12
 
13
- logger = logging.getLogger(__name__)
13
+ logger = get_logger("decorators")
14
14
 
15
15
 
16
16
  def require_api_key(func: Callable) -> Callable:
@@ -1,178 +1,146 @@
1
- # Currency Management Commands
1
+ # Payment Management Commands
2
2
 
3
- Management команды для работы с валютами в Universal Payments System.
3
+ Optimized management commands for Django CFG payments system.
4
4
 
5
- ## Команды
5
+ ## Available Commands
6
6
 
7
- ### 🪙 `populate_currencies` - Первоначальное заполнение
7
+ ### 1. `manage_currencies` - Currency and Rate Management
8
8
 
9
- Заполняет пустую базу данных валютами из внешних API (CoinGecko, YFinance).
9
+ Universal command for all currency-related operations.
10
10
 
11
- ```bash
12
- # Быстрое заполнение (50 криптовалют + 20 фиатных)
13
- python manage.py populate_currencies --quick
14
-
15
- # Стандартное заполнение (200 криптовалют + 30 фиатных)
16
- python manage.py populate_currencies
17
-
18
- # Только криптовалюты
19
- python manage.py populate_currencies --crypto-only
20
-
21
- # Только фиатные валюты
22
- python manage.py populate_currencies --fiat-only
23
-
24
- # Пропустить существующие валюты
25
- python manage.py populate_currencies --skip-existing
26
- ```
27
-
28
- ### 🔄 `update_currencies` - Обновление курсов
29
-
30
- Обновляет курсы валют с внешних API.
11
+ #### Usage Examples:
31
12
 
32
13
  ```bash
33
- # Обновить устаревшие курсы (старше 6 часов)
34
- python manage.py update_currencies
14
+ # Update USD exchange rates only
15
+ python manage.py manage_currencies --rates-only
35
16
 
36
- # Принудительно обновить все валюты
37
- python manage.py update_currencies --force-update
17
+ # Update specific currency rate
18
+ python manage.py manage_currencies --rates-only --currency ETH
38
19
 
39
- # Сухой прогон (показать что будет обновлено)
40
- python manage.py update_currencies --dry-run
20
+ # Initial population (empty database)
21
+ python manage.py manage_currencies --populate
41
22
 
42
- # Кастомные лимиты
43
- python manage.py update_currencies --max-crypto 100 --max-fiat 30
23
+ # Full update with fresh rates
24
+ python manage.py manage_currencies --force
44
25
 
45
- # Исключить стейблкоины
46
- python manage.py update_currencies --exclude-stablecoins
26
+ # Dry run to see what would be updated
27
+ python manage.py manage_currencies --dry-run
47
28
 
48
- # Подробный вывод
49
- python manage.py update_currencies --verbose
29
+ # Limit number of currencies processed
30
+ python manage.py manage_currencies --populate --max-crypto 100 --max-fiat 20
50
31
  ```
51
32
 
52
- ### 📊 `currency_stats` - Статистика валют
33
+ #### Options:
34
+ - `--populate` - Initial population mode for empty database
35
+ - `--rates-only` - Only update USD exchange rates
36
+ - `--currency CODE` - Update specific currency (e.g., BTC, ETH)
37
+ - `--force` - Force refresh all data even if fresh
38
+ - `--dry-run` - Show what would be done without changes
39
+ - `--max-crypto N` - Limit crypto currencies (default: 200)
40
+ - `--max-fiat N` - Limit fiat currencies (default: 50)
53
41
 
54
- Показывает статистику базы данных валют.
42
+ ---
55
43
 
56
- ```bash
57
- # Базовая статистика
58
- python manage.py currency_stats
44
+ ### 2. `manage_providers` - Payment Provider Management
59
45
 
60
- # Детальная статистика
61
- python manage.py currency_stats --detailed
46
+ Universal command for all provider-related operations.
62
47
 
63
- # Показать топ-10 валют
64
- python manage.py currency_stats --top 10
48
+ #### Usage Examples:
65
49
 
66
- # Проверить устаревшие курсы
67
- python manage.py currency_stats --check-rates
50
+ ```bash
51
+ # Sync all active providers
52
+ python manage.py manage_providers
68
53
 
69
- # Экспортировать в CSV
70
- python manage.py currency_stats --export-csv currencies.csv
71
- ```
54
+ # Sync specific provider
55
+ python manage.py manage_providers --provider nowpayments
72
56
 
73
- ## Автоматизация
57
+ # Sync multiple providers
58
+ python manage.py manage_providers --provider nowpayments,cryptomus
74
59
 
75
- ### Cron для регулярного обновления
60
+ # Sync providers + update USD rates
61
+ python manage.py manage_providers --with-rates
76
62
 
77
- ```bash
78
- # Обновлять курсы каждые 6 часов
79
- 0 */6 * * * cd /path/to/project && poetry run python manage.py update_currencies
63
+ # Show provider statistics
64
+ python manage.py manage_providers --stats
80
65
 
81
- # Ежедневная проверка статистики
82
- 0 9 * * * cd /path/to/project && poetry run python manage.py currency_stats --check-rates
66
+ # Dry run to see what would be synced
67
+ python manage.py manage_providers --dry-run --verbose
83
68
  ```
84
69
 
85
- ### Docker
70
+ #### Options:
71
+ - `--provider NAME` - Specific provider(s) to sync (comma-separated)
72
+ - `--all` - Sync all available providers
73
+ - `--with-rates` - Also update USD exchange rates after sync
74
+ - `--stats` - Show provider statistics
75
+ - `--dry-run` - Show what would be synced without changes
76
+ - `--verbose` - Show detailed progress information
86
77
 
87
- ```bash
88
- # В Docker контейнере
89
- docker exec -it container_name poetry run python manage.py populate_currencies --quick
90
- docker exec -it container_name poetry run python manage.py update_currencies
91
- ```
78
+ ---
92
79
 
93
- ## Примеры использования
80
+ ### 3. `currency_stats` - Statistics and Reports
94
81
 
95
- ### Первоначальная настройка
82
+ Display currency database statistics and health information.
96
83
 
97
- ```bash
98
- # 1. Заполнить базу данных валютами
99
- python manage.py populate_currencies --quick
84
+ #### Usage Examples:
100
85
 
101
- # 2. Проверить результат
86
+ ```bash
87
+ # Basic statistics
102
88
  python manage.py currency_stats
103
- ```
104
89
 
105
- ### Регулярное обслуживание
90
+ # Detailed breakdown
91
+ python manage.py currency_stats --detailed
106
92
 
107
- ```bash
108
- # 1. Обновить курсы
109
- python manage.py update_currencies --verbose
93
+ # Top currencies by value
94
+ python manage.py currency_stats --top 10
110
95
 
111
- # 2. Проверить устаревшие курсы
96
+ # Check rate freshness
112
97
  python manage.py currency_stats --check-rates
113
-
114
- # 3. При необходимости - принудительное обновление
115
- python manage.py update_currencies --force-update
116
98
  ```
117
99
 
118
- ### Production обслуживание
100
+ ---
119
101
 
120
- ```bash
121
- # Обновление с минимальными API запросами
122
- python manage.py update_currencies --max-crypto 50 --max-fiat 20
102
+ ## Migration from Old Commands
123
103
 
124
- # Мониторинг состояния
125
- python manage.py currency_stats --detailed --export-csv daily_report.csv
126
- ```
104
+ | Old Command | New Command |
105
+ |-------------|-------------|
106
+ | `populate_currencies` | `manage_currencies --populate` |
107
+ | `update_currencies` | `manage_currencies` |
108
+ | `update_currency_rates` | `manage_currencies --rates-only` |
109
+ | `sync_providers` | `manage_providers` |
110
+ | `currency_stats` | `currency_stats` (unchanged) |
127
111
 
128
- ## Интеграция с django_currency
112
+ ## Automation Examples
129
113
 
130
- Команды используют модуль `django_currency.database.database_loader` для:
131
-
132
- - Получения списка валют с CoinGecko
133
- - Загрузки курсов фиатных валют с YFinance
134
- - ✅ Rate limiting для защиты от API throttling
135
- - ✅ Кэширования для оптимизации производительности
136
- - ✅ Pydantic валидации для типобезопасности
137
-
138
- ## Конфигурация
139
-
140
- Настройки в `DatabaseLoaderConfig`:
114
+ ### Daily Rate Updates (Crontab)
115
+ ```bash
116
+ # Update rates every 6 hours
117
+ 0 */6 * * * cd /path/to/project && python manage.py manage_currencies --rates-only
141
118
 
142
- ```python
143
- config = DatabaseLoaderConfig(
144
- max_cryptocurrencies=500, # Максимум криптовалют
145
- max_fiat_currencies=50, # Максимум фиатных валют
146
- min_market_cap_usd=1_000_000, # Минимальная капитализация
147
- coingecko_delay=1.5, # Задержка между запросами
148
- yfinance_delay=0.5, # Задержка для YFinance
149
- exclude_stablecoins=False, # Исключить стейблкоины
150
- cache_ttl_hours=24 # TTL кэша в часах
151
- )
119
+ # Sync providers once daily
120
+ 0 2 * * * cd /path/to/project && python manage.py manage_providers --with-rates
152
121
  ```
153
122
 
154
- ## Мониторинг
155
-
156
- ### Логи
123
+ ### Initial Setup
124
+ ```bash
125
+ # 1. Populate base currencies
126
+ python manage.py manage_currencies --populate
157
127
 
158
- Команды логируют в `django_cfg.apps.payments.management.commands`:
128
+ # 2. Sync payment providers
129
+ python manage.py manage_providers
159
130
 
160
- ```python
161
- import logging
162
- logger = logging.getLogger('django_cfg.apps.payments.management.commands')
131
+ # 3. Check statistics
132
+ python manage.py manage_providers --stats
133
+ python manage.py currency_stats
163
134
  ```
164
135
 
165
- ### Метрики
166
-
167
- - Количество созданных/обновленных валют
168
- - Время выполнения API запросов
169
- - Ошибки валидации и API
170
- - Статистика курсов валют
136
+ ---
171
137
 
172
- ## Безопасность
138
+ ## Features
173
139
 
174
- - Rate limiting для API запросов
175
- - Atomic транзакции для консистентности
176
- - Graceful handling ошибок API
177
- - Валидация данных с Pydantic
178
- - Rollback при критических ошибках
140
+ - **🚀 Fast**: Optimized database queries and caching
141
+ - **📊 Progress**: Real-time progress reporting and statistics
142
+ - **🔄 Atomic**: Transaction safety with rollback on errors
143
+ - **🎯 Flexible**: Multiple operation modes and options
144
+ - **📈 Pydantic**: Full type safety with Pydantic models
145
+ - **🛡️ Safe**: Dry-run mode for testing changes
146
+ - **📝 Verbose**: Detailed logging and error reporting
@@ -76,7 +76,7 @@ class Command(BaseCommand):
76
76
 
77
77
  # Basic counts
78
78
  total = Currency.objects.count()
79
- active = Currency.objects.filter(is_active=True).count()
79
+ active = Currency.objects.count()
80
80
  inactive = total - active
81
81
 
82
82
  fiat_count = Currency.objects.filter(currency_type=Currency.CurrencyType.FIAT).count()
@@ -84,11 +84,9 @@ class Command(BaseCommand):
84
84
 
85
85
  active_fiat = Currency.objects.filter(
86
86
  currency_type=Currency.CurrencyType.FIAT,
87
- is_active=True
88
87
  ).count()
89
88
  active_crypto = Currency.objects.filter(
90
89
  currency_type=Currency.CurrencyType.CRYPTO,
91
- is_active=True
92
90
  ).count()
93
91
 
94
92
  self.stdout.write(f"\n📈 Overview:")
@@ -119,7 +117,6 @@ class Command(BaseCommand):
119
117
  # Top cryptocurrencies by USD value
120
118
  top_crypto = Currency.objects.filter(
121
119
  currency_type=Currency.CurrencyType.CRYPTO,
122
- is_active=True
123
120
  ).order_by('-usd_rate')[:options['top']]
124
121
 
125
122
  if top_crypto:
@@ -134,7 +131,6 @@ class Command(BaseCommand):
134
131
  major_fiat = Currency.objects.filter(
135
132
  currency_type=Currency.CurrencyType.FIAT,
136
133
  code__in=['USD', 'EUR', 'GBP', 'JPY', 'CNY'],
137
- is_active=True
138
134
  ).order_by('code')
139
135
 
140
136
  if major_fiat:
@@ -162,12 +158,10 @@ class Command(BaseCommand):
162
158
  # Average rates by type
163
159
  crypto_avg = Currency.objects.filter(
164
160
  currency_type=Currency.CurrencyType.CRYPTO,
165
- is_active=True
166
161
  ).aggregate(avg_rate=Avg('usd_rate'))['avg_rate']
167
162
 
168
163
  fiat_avg = Currency.objects.filter(
169
164
  currency_type=Currency.CurrencyType.FIAT,
170
- is_active=True
171
165
  ).aggregate(avg_rate=Avg('usd_rate'))['avg_rate']
172
166
 
173
167
  self.stdout.write(f"\n📊 Average USD Rates:")
@@ -177,13 +171,8 @@ class Command(BaseCommand):
177
171
  self.stdout.write(f" Fiat currencies: ${fiat_avg:.6f}")
178
172
 
179
173
  # Min payment amounts
180
- min_payment_stats = Currency.objects.values('min_payment_amount').annotate(
181
- count=Count('min_payment_amount')
182
- ).order_by('min_payment_amount')[:5]
183
-
184
- self.stdout.write(f"\n💰 Top Min Payment Amounts:")
185
- for stat in min_payment_stats:
186
- self.stdout.write(f" ${stat['min_payment_amount']}: {stat['count']} currencies")
174
+ # Note: min_payment_amount field was removed - now handled at provider level
175
+ self.stdout.write(f"\n💰 Payment amounts now managed at provider level (ProviderCurrency)")
187
176
 
188
177
  # Rate freshness distribution
189
178
  now = timezone.now()
@@ -219,7 +208,6 @@ class Command(BaseCommand):
219
208
  very_old_threshold = now - timedelta(days=30)
220
209
  very_old = Currency.objects.filter(
221
210
  Q(rate_updated_at__lt=very_old_threshold) | Q(rate_updated_at__isnull=True),
222
- is_active=True
223
211
  )
224
212
 
225
213
  if very_old.exists():
@@ -237,7 +225,6 @@ class Command(BaseCommand):
237
225
  old_currencies = Currency.objects.filter(
238
226
  rate_updated_at__lt=old_threshold,
239
227
  rate_updated_at__gte=very_old_threshold,
240
- is_active=True
241
228
  )
242
229
 
243
230
  if old_currencies.exists():
@@ -249,7 +236,6 @@ class Command(BaseCommand):
249
236
  fresh_threshold = now - timedelta(hours=24)
250
237
  fresh = Currency.objects.filter(
251
238
  rate_updated_at__gte=fresh_threshold,
252
- is_active=True
253
239
  ).count()
254
240
 
255
241
  if fresh > 0:
@@ -258,7 +244,7 @@ class Command(BaseCommand):
258
244
  )
259
245
 
260
246
  # Recommendations
261
- total_active = Currency.objects.filter(is_active=True).count()
247
+ total_active = Currency.objects.count()
262
248
  if very_old.count() > 0:
263
249
  self.stdout.write(f"\n💡 Recommendations:")
264
250
  self.stdout.write(f" • Run: python manage.py update_currencies --force-update")
@@ -294,8 +280,7 @@ class Command(BaseCommand):
294
280
 
295
281
  # Header
296
282
  writer.writerow([
297
- 'code', 'name', 'symbol', 'currency_type', 'decimal_places',
298
- 'usd_rate', 'min_payment_amount', 'is_active', 'rate_updated_at'
283
+ 'code', 'name', 'currency_type', 'usd_rate', 'rate_updated_at'
299
284
  ])
300
285
 
301
286
  # Data
@@ -304,12 +289,8 @@ class Command(BaseCommand):
304
289
  writer.writerow([
305
290
  currency.code,
306
291
  currency.name,
307
- currency.symbol,
308
292
  currency.currency_type,
309
- currency.decimal_places,
310
293
  currency.usd_rate,
311
- currency.min_payment_amount,
312
- currency.is_active,
313
294
  currency.rate_updated_at.isoformat() if currency.rate_updated_at else None
314
295
  ])
315
296