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.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/payments/admin/__init__.py +3 -2
- django_cfg/apps/payments/admin/balance_admin.py +18 -18
- django_cfg/apps/payments/admin/currencies_admin.py +319 -131
- django_cfg/apps/payments/admin/payments_admin.py +15 -4
- django_cfg/apps/payments/config/module.py +2 -2
- django_cfg/apps/payments/config/utils.py +2 -2
- django_cfg/apps/payments/decorators.py +2 -2
- django_cfg/apps/payments/management/commands/README.md +95 -127
- django_cfg/apps/payments/management/commands/currency_stats.py +5 -24
- django_cfg/apps/payments/management/commands/manage_currencies.py +229 -0
- django_cfg/apps/payments/management/commands/manage_providers.py +235 -0
- django_cfg/apps/payments/managers/__init__.py +3 -2
- django_cfg/apps/payments/managers/balance_manager.py +2 -2
- django_cfg/apps/payments/managers/currency_manager.py +272 -49
- django_cfg/apps/payments/managers/payment_manager.py +161 -13
- django_cfg/apps/payments/middleware/api_access.py +2 -2
- django_cfg/apps/payments/middleware/rate_limiting.py +8 -18
- django_cfg/apps/payments/middleware/usage_tracking.py +20 -17
- django_cfg/apps/payments/migrations/0002_network_providercurrency_and_more.py +241 -0
- django_cfg/apps/payments/migrations/0003_add_usd_rate_cache.py +30 -0
- django_cfg/apps/payments/models/__init__.py +3 -2
- django_cfg/apps/payments/models/currencies.py +187 -71
- django_cfg/apps/payments/models/payments.py +3 -2
- django_cfg/apps/payments/serializers/__init__.py +3 -2
- django_cfg/apps/payments/serializers/currencies.py +20 -12
- django_cfg/apps/payments/services/cache/simple_cache.py +2 -2
- django_cfg/apps/payments/services/core/balance_service.py +2 -2
- django_cfg/apps/payments/services/core/fallback_service.py +2 -2
- django_cfg/apps/payments/services/core/payment_service.py +3 -6
- django_cfg/apps/payments/services/core/subscription_service.py +4 -7
- django_cfg/apps/payments/services/internal_types.py +171 -7
- django_cfg/apps/payments/services/monitoring/api_schemas.py +58 -204
- django_cfg/apps/payments/services/monitoring/provider_health.py +2 -2
- django_cfg/apps/payments/services/providers/base.py +144 -43
- django_cfg/apps/payments/services/providers/cryptapi/__init__.py +4 -0
- django_cfg/apps/payments/services/providers/cryptapi/config.py +8 -0
- django_cfg/apps/payments/services/providers/cryptapi/models.py +192 -0
- django_cfg/apps/payments/services/providers/cryptapi/provider.py +439 -0
- django_cfg/apps/payments/services/providers/cryptomus/__init__.py +4 -0
- django_cfg/apps/payments/services/providers/cryptomus/models.py +176 -0
- django_cfg/apps/payments/services/providers/cryptomus/provider.py +429 -0
- django_cfg/apps/payments/services/providers/cryptomus/provider_v2.py +564 -0
- django_cfg/apps/payments/services/providers/models/__init__.py +34 -0
- django_cfg/apps/payments/services/providers/models/currencies.py +190 -0
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -0
- django_cfg/apps/payments/services/providers/nowpayments/models.py +196 -0
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +380 -0
- django_cfg/apps/payments/services/providers/registry.py +294 -11
- django_cfg/apps/payments/services/providers/stripe/__init__.py +4 -0
- django_cfg/apps/payments/services/providers/stripe/models.py +184 -0
- django_cfg/apps/payments/services/providers/stripe/provider.py +109 -0
- django_cfg/apps/payments/services/security/error_handler.py +6 -8
- django_cfg/apps/payments/services/security/payment_notifications.py +2 -2
- django_cfg/apps/payments/services/security/webhook_validator.py +3 -4
- django_cfg/apps/payments/signals/api_key_signals.py +2 -2
- django_cfg/apps/payments/signals/payment_signals.py +11 -5
- django_cfg/apps/payments/signals/subscription_signals.py +2 -2
- django_cfg/apps/payments/static/payments/css/payments.css +340 -0
- django_cfg/apps/payments/static/payments/js/notifications.js +202 -0
- django_cfg/apps/payments/static/payments/js/payment-utils.js +318 -0
- django_cfg/apps/payments/static/payments/js/theme.js +86 -0
- django_cfg/apps/payments/tasks/webhook_processing.py +2 -2
- django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +50 -0
- django_cfg/apps/payments/templates/payments/base.html +182 -0
- django_cfg/apps/payments/templates/payments/components/payment_card.html +201 -0
- django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +109 -0
- django_cfg/apps/payments/templates/payments/components/progress_bar.html +43 -0
- django_cfg/apps/payments/templates/payments/components/provider_stats.html +40 -0
- django_cfg/apps/payments/templates/payments/components/status_badge.html +34 -0
- django_cfg/apps/payments/templates/payments/components/status_overview.html +148 -0
- django_cfg/apps/payments/templates/payments/dashboard.html +258 -0
- django_cfg/apps/payments/templates/payments/dashboard_simple_test.html +35 -0
- django_cfg/apps/payments/templates/payments/payment_create.html +579 -0
- django_cfg/apps/payments/templates/payments/payment_detail.html +373 -0
- django_cfg/apps/payments/templates/payments/payment_list.html +354 -0
- django_cfg/apps/payments/templates/payments/stats.html +261 -0
- django_cfg/apps/payments/templates/payments/test.html +213 -0
- django_cfg/apps/payments/templatetags/__init__.py +1 -0
- django_cfg/apps/payments/templatetags/payments_tags.py +315 -0
- django_cfg/apps/payments/urls.py +3 -1
- django_cfg/apps/payments/urls_admin.py +58 -0
- django_cfg/apps/payments/utils/__init__.py +1 -3
- django_cfg/apps/payments/utils/billing_utils.py +2 -2
- django_cfg/apps/payments/utils/config_utils.py +2 -8
- django_cfg/apps/payments/utils/validation_utils.py +2 -2
- django_cfg/apps/payments/views/__init__.py +3 -2
- django_cfg/apps/payments/views/currency_views.py +31 -20
- django_cfg/apps/payments/views/payment_views.py +2 -2
- django_cfg/apps/payments/views/templates/__init__.py +25 -0
- django_cfg/apps/payments/views/templates/ajax.py +451 -0
- django_cfg/apps/payments/views/templates/base.py +212 -0
- django_cfg/apps/payments/views/templates/dashboard.py +60 -0
- django_cfg/apps/payments/views/templates/payment_detail.py +102 -0
- django_cfg/apps/payments/views/templates/payment_management.py +158 -0
- django_cfg/apps/payments/views/templates/qr_code.py +174 -0
- django_cfg/apps/payments/views/templates/stats.py +244 -0
- django_cfg/apps/payments/views/templates/utils.py +181 -0
- django_cfg/apps/payments/views/webhook_views.py +2 -2
- django_cfg/apps/payments/viewsets.py +3 -2
- django_cfg/apps/tasks/urls.py +0 -2
- django_cfg/apps/tasks/urls_admin.py +14 -0
- django_cfg/apps/urls.py +6 -3
- django_cfg/core/config.py +35 -0
- django_cfg/models/payments.py +2 -8
- django_cfg/modules/django_currency/__init__.py +16 -11
- django_cfg/modules/django_currency/clients/__init__.py +4 -4
- django_cfg/modules/django_currency/clients/coinpaprika_client.py +289 -0
- django_cfg/modules/django_currency/clients/yahoo_client.py +157 -0
- django_cfg/modules/django_currency/core/__init__.py +1 -7
- django_cfg/modules/django_currency/core/converter.py +18 -23
- django_cfg/modules/django_currency/core/models.py +122 -11
- django_cfg/modules/django_currency/database/__init__.py +4 -4
- django_cfg/modules/django_currency/database/database_loader.py +190 -309
- django_cfg/modules/django_unfold/dashboard.py +7 -2
- django_cfg/registry/core.py +1 -0
- django_cfg/template_archive/.gitignore +1 -0
- django_cfg/template_archive/django_sample.zip +0 -0
- django_cfg/templates/admin/components/action_grid.html +9 -9
- django_cfg/templates/admin/components/metric_card.html +5 -5
- django_cfg/templates/admin/components/status_badge.html +2 -2
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html +152 -24
- django_cfg/templates/admin/snippets/components/quick_actions.html +3 -3
- django_cfg/templates/admin/snippets/components/system_health.html +1 -1
- django_cfg/templates/admin/snippets/tabs/overview_tab.html +49 -52
- {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/METADATA +13 -18
- {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/RECORD +130 -83
- django_cfg/apps/payments/management/commands/populate_currencies.py +0 -246
- django_cfg/apps/payments/management/commands/update_currencies.py +0 -336
- django_cfg/apps/payments/services/providers/cryptapi.py +0 -273
- django_cfg/apps/payments/services/providers/cryptomus.py +0 -310
- django_cfg/apps/payments/services/providers/nowpayments.py +0 -293
- django_cfg/apps/payments/services/validators/__init__.py +0 -8
- django_cfg/modules/django_currency/clients/coingecko_client.py +0 -257
- django_cfg/modules/django_currency/clients/yfinance_client.py +0 -246
- {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/licenses/LICENSE +0 -0
@@ -3,17 +3,18 @@ Usage Tracking Middleware.
|
|
3
3
|
Tracks API usage for billing, analytics, and monitoring.
|
4
4
|
"""
|
5
5
|
|
6
|
-
import
|
6
|
+
from django_cfg.modules.django_logger import get_logger
|
7
7
|
import json
|
8
8
|
from typing import Optional, Dict, Any
|
9
9
|
from django.http import HttpRequest, HttpResponse
|
10
10
|
from django.utils.deprecation import MiddlewareMixin
|
11
11
|
from django.conf import settings
|
12
12
|
from django.utils import timezone
|
13
|
+
from django.core.cache import cache
|
13
14
|
from ..models import APIKey, Subscription, Transaction
|
14
15
|
from ..services import RateLimitCache
|
15
16
|
|
16
|
-
logger =
|
17
|
+
logger = get_logger("usage_tracking")
|
17
18
|
|
18
19
|
|
19
20
|
class UsageTrackingMiddleware(MiddlewareMixin):
|
@@ -30,7 +31,6 @@ class UsageTrackingMiddleware(MiddlewareMixin):
|
|
30
31
|
|
31
32
|
def __init__(self, get_response=None):
|
32
33
|
super().__init__(get_response)
|
33
|
-
self.redis_service = RedisService()
|
34
34
|
|
35
35
|
# Enable/disable usage tracking
|
36
36
|
self.enabled = getattr(settings, 'PAYMENTS_USAGE_TRACKING_ENABLED', True)
|
@@ -236,28 +236,31 @@ class UsageTrackingMiddleware(MiddlewareMixin):
|
|
236
236
|
date_key = usage_data['start_time'].strftime('%Y-%m-%d')
|
237
237
|
user_id = usage_data['user_id']
|
238
238
|
|
239
|
-
# Increment counters
|
240
|
-
|
239
|
+
# Increment counters using Django cache
|
240
|
+
daily_usage_key = f"payments:daily_usage:{user_id}:{date_key}"
|
241
|
+
current_usage = cache.get(daily_usage_key, 0)
|
242
|
+
cache.set(daily_usage_key, current_usage + 1, timeout=86400) # 24 hours
|
241
243
|
|
242
244
|
if usage_data.get('subscription_id'):
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
)
|
245
|
+
sub_usage_key = f"payments:subscription_usage:{usage_data['subscription_id']}:{date_key}"
|
246
|
+
current_sub_usage = cache.get(sub_usage_key, 0)
|
247
|
+
cache.set(sub_usage_key, current_sub_usage + 1, timeout=86400) # 24 hours
|
247
248
|
|
248
249
|
# Store performance metrics
|
249
250
|
if usage_data['response_time_ms'] > 0:
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
251
|
+
perf_key = f"payments:performance:{usage_data['path'].replace('/', '_')}"
|
252
|
+
response_times = cache.get(perf_key, [])
|
253
|
+
response_times.append(usage_data['response_time_ms'])
|
254
|
+
# Keep only last 100 measurements
|
255
|
+
if len(response_times) > 100:
|
256
|
+
response_times = response_times[-100:]
|
257
|
+
cache.set(perf_key, response_times, timeout=3600) # 1 hour
|
254
258
|
|
255
259
|
# Store error metrics
|
256
260
|
if usage_data.get('is_error'):
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
)
|
261
|
+
error_key = f"payments:errors:{usage_data['path'].replace('/', '_')}:{usage_data['status_code']}"
|
262
|
+
current_errors = cache.get(error_key, 0)
|
263
|
+
cache.set(error_key, current_errors + 1, timeout=3600) # 1 hour
|
261
264
|
|
262
265
|
except Exception as e:
|
263
266
|
logger.error(f"Error storing usage data in Redis: {e}")
|
@@ -0,0 +1,241 @@
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-24 19:54
|
2
|
+
|
3
|
+
import django.db.models.deletion
|
4
|
+
from django.db import migrations, models
|
5
|
+
|
6
|
+
|
7
|
+
class Migration(migrations.Migration):
|
8
|
+
dependencies = [
|
9
|
+
("django_cfg_payments", "0001_initial"),
|
10
|
+
]
|
11
|
+
|
12
|
+
operations = [
|
13
|
+
migrations.CreateModel(
|
14
|
+
name="Network",
|
15
|
+
fields=[
|
16
|
+
(
|
17
|
+
"id",
|
18
|
+
models.BigAutoField(
|
19
|
+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
20
|
+
),
|
21
|
+
),
|
22
|
+
("created_at", models.DateTimeField(auto_now_add=True, db_index=True)),
|
23
|
+
("updated_at", models.DateTimeField(auto_now=True)),
|
24
|
+
(
|
25
|
+
"code",
|
26
|
+
models.CharField(
|
27
|
+
help_text="Network code: ethereum, bitcoin, tron, bsc",
|
28
|
+
max_length=20,
|
29
|
+
unique=True,
|
30
|
+
),
|
31
|
+
),
|
32
|
+
(
|
33
|
+
"name",
|
34
|
+
models.CharField(
|
35
|
+
help_text="Network name: Ethereum, Bitcoin, TRON, BSC", max_length=100
|
36
|
+
),
|
37
|
+
),
|
38
|
+
],
|
39
|
+
options={
|
40
|
+
"verbose_name": "Network",
|
41
|
+
"verbose_name_plural": "Networks",
|
42
|
+
"db_table": "payment_networks",
|
43
|
+
"ordering": ["name"],
|
44
|
+
},
|
45
|
+
),
|
46
|
+
migrations.CreateModel(
|
47
|
+
name="ProviderCurrency",
|
48
|
+
fields=[
|
49
|
+
(
|
50
|
+
"id",
|
51
|
+
models.BigAutoField(
|
52
|
+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
53
|
+
),
|
54
|
+
),
|
55
|
+
("created_at", models.DateTimeField(auto_now_add=True, db_index=True)),
|
56
|
+
("updated_at", models.DateTimeField(auto_now=True)),
|
57
|
+
(
|
58
|
+
"provider_name",
|
59
|
+
models.CharField(
|
60
|
+
help_text="Provider: nowpayments, stripe, cryptomus", max_length=50
|
61
|
+
),
|
62
|
+
),
|
63
|
+
(
|
64
|
+
"provider_currency_code",
|
65
|
+
models.CharField(
|
66
|
+
help_text="Provider code: USDTERC20, USDTBSC, usd", max_length=20
|
67
|
+
),
|
68
|
+
),
|
69
|
+
(
|
70
|
+
"min_amount",
|
71
|
+
models.DecimalField(
|
72
|
+
blank=True,
|
73
|
+
decimal_places=8,
|
74
|
+
help_text="Minimum payment amount",
|
75
|
+
max_digits=20,
|
76
|
+
null=True,
|
77
|
+
),
|
78
|
+
),
|
79
|
+
(
|
80
|
+
"max_amount",
|
81
|
+
models.DecimalField(
|
82
|
+
blank=True,
|
83
|
+
decimal_places=8,
|
84
|
+
help_text="Maximum payment amount (null = no limit)",
|
85
|
+
max_digits=20,
|
86
|
+
null=True,
|
87
|
+
),
|
88
|
+
),
|
89
|
+
("is_enabled", models.BooleanField(default=True, help_text="Enabled by provider")),
|
90
|
+
(
|
91
|
+
"available_for_payment",
|
92
|
+
models.BooleanField(default=True, help_text="Can receive payments"),
|
93
|
+
),
|
94
|
+
(
|
95
|
+
"available_for_payout",
|
96
|
+
models.BooleanField(default=True, help_text="Can send payouts"),
|
97
|
+
),
|
98
|
+
(
|
99
|
+
"is_popular",
|
100
|
+
models.BooleanField(default=False, help_text="Popular/recommended by provider"),
|
101
|
+
),
|
102
|
+
(
|
103
|
+
"is_stable",
|
104
|
+
models.BooleanField(default=False, help_text="Stable coin (USDT, USDC, etc.)"),
|
105
|
+
),
|
106
|
+
(
|
107
|
+
"priority",
|
108
|
+
models.IntegerField(
|
109
|
+
default=0, help_text="Display priority (higher = shown first)"
|
110
|
+
),
|
111
|
+
),
|
112
|
+
(
|
113
|
+
"logo_url",
|
114
|
+
models.URLField(blank=True, help_text="Currency logo/icon URL from provider"),
|
115
|
+
),
|
116
|
+
(
|
117
|
+
"metadata",
|
118
|
+
models.JSONField(
|
119
|
+
blank=True,
|
120
|
+
default=dict,
|
121
|
+
help_text="All provider-specific data: logo_url, smart_contract, wallet_regex, commission_percent, etc.",
|
122
|
+
),
|
123
|
+
),
|
124
|
+
],
|
125
|
+
options={
|
126
|
+
"verbose_name": "Provider Currency",
|
127
|
+
"verbose_name_plural": "Provider Currencies",
|
128
|
+
"db_table": "payment_provider_currencies",
|
129
|
+
"ordering": ["-priority", "provider_name", "base_currency__code"],
|
130
|
+
},
|
131
|
+
),
|
132
|
+
migrations.AlterUniqueTogether(
|
133
|
+
name="currencynetwork",
|
134
|
+
unique_together=None,
|
135
|
+
),
|
136
|
+
migrations.RemoveField(
|
137
|
+
model_name="currencynetwork",
|
138
|
+
name="currency",
|
139
|
+
),
|
140
|
+
migrations.AlterModelOptions(
|
141
|
+
name="currency",
|
142
|
+
options={
|
143
|
+
"ordering": ["currency_type", "code"],
|
144
|
+
"verbose_name": "Currency",
|
145
|
+
"verbose_name_plural": "Currencies",
|
146
|
+
},
|
147
|
+
),
|
148
|
+
migrations.RemoveIndex(
|
149
|
+
model_name="currency",
|
150
|
+
name="payment_cur_code_e2a506_idx",
|
151
|
+
),
|
152
|
+
migrations.RemoveIndex(
|
153
|
+
model_name="currency",
|
154
|
+
name="payment_cur_currenc_6057a9_idx",
|
155
|
+
),
|
156
|
+
migrations.RemoveIndex(
|
157
|
+
model_name="currency",
|
158
|
+
name="payment_cur_is_acti_8d558f_idx",
|
159
|
+
),
|
160
|
+
migrations.RemoveField(
|
161
|
+
model_name="currency",
|
162
|
+
name="decimal_places",
|
163
|
+
),
|
164
|
+
migrations.RemoveField(
|
165
|
+
model_name="currency",
|
166
|
+
name="is_active",
|
167
|
+
),
|
168
|
+
migrations.RemoveField(
|
169
|
+
model_name="currency",
|
170
|
+
name="min_payment_amount",
|
171
|
+
),
|
172
|
+
migrations.RemoveField(
|
173
|
+
model_name="currency",
|
174
|
+
name="rate_updated_at",
|
175
|
+
),
|
176
|
+
migrations.RemoveField(
|
177
|
+
model_name="currency",
|
178
|
+
name="symbol",
|
179
|
+
),
|
180
|
+
migrations.RemoveField(
|
181
|
+
model_name="currency",
|
182
|
+
name="usd_rate",
|
183
|
+
),
|
184
|
+
migrations.AlterField(
|
185
|
+
model_name="currency",
|
186
|
+
name="code",
|
187
|
+
field=models.CharField(
|
188
|
+
help_text="Clean currency code: BTC, USDT, ETH, USD (NO network suffixes)",
|
189
|
+
max_length=10,
|
190
|
+
unique=True,
|
191
|
+
),
|
192
|
+
),
|
193
|
+
migrations.AlterField(
|
194
|
+
model_name="currency",
|
195
|
+
name="currency_type",
|
196
|
+
field=models.CharField(
|
197
|
+
choices=[("fiat", "Fiat Currency"), ("crypto", "Cryptocurrency")],
|
198
|
+
help_text="fiat or crypto",
|
199
|
+
max_length=10,
|
200
|
+
),
|
201
|
+
),
|
202
|
+
migrations.AlterField(
|
203
|
+
model_name="currency",
|
204
|
+
name="name",
|
205
|
+
field=models.CharField(
|
206
|
+
help_text="Currency name: Bitcoin, Tether USD, Ethereum", max_length=100
|
207
|
+
),
|
208
|
+
),
|
209
|
+
migrations.AddField(
|
210
|
+
model_name="providercurrency",
|
211
|
+
name="base_currency",
|
212
|
+
field=models.ForeignKey(
|
213
|
+
help_text="Base currency: BTC, USDT, ETH",
|
214
|
+
on_delete=django.db.models.deletion.CASCADE,
|
215
|
+
related_name="provider_mappings",
|
216
|
+
to="django_cfg_payments.currency",
|
217
|
+
),
|
218
|
+
),
|
219
|
+
migrations.AddField(
|
220
|
+
model_name="providercurrency",
|
221
|
+
name="network",
|
222
|
+
field=models.ForeignKey(
|
223
|
+
blank=True,
|
224
|
+
help_text="Network for crypto (null for fiat)",
|
225
|
+
null=True,
|
226
|
+
on_delete=django.db.models.deletion.CASCADE,
|
227
|
+
related_name="provider_currencies",
|
228
|
+
to="django_cfg_payments.network",
|
229
|
+
),
|
230
|
+
),
|
231
|
+
migrations.DeleteModel(
|
232
|
+
name="CurrencyNetwork",
|
233
|
+
),
|
234
|
+
migrations.AlterUniqueTogether(
|
235
|
+
name="providercurrency",
|
236
|
+
unique_together={
|
237
|
+
("provider_name", "base_currency", "network"),
|
238
|
+
("provider_name", "provider_currency_code"),
|
239
|
+
},
|
240
|
+
),
|
241
|
+
]
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-25 06:06
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
|
5
|
+
|
6
|
+
class Migration(migrations.Migration):
|
7
|
+
dependencies = [
|
8
|
+
("django_cfg_payments", "0002_network_providercurrency_and_more"),
|
9
|
+
]
|
10
|
+
|
11
|
+
operations = [
|
12
|
+
migrations.AddField(
|
13
|
+
model_name="currency",
|
14
|
+
name="rate_updated_at",
|
15
|
+
field=models.DateTimeField(
|
16
|
+
blank=True, help_text="When the USD rate was last updated", null=True
|
17
|
+
),
|
18
|
+
),
|
19
|
+
migrations.AddField(
|
20
|
+
model_name="currency",
|
21
|
+
name="usd_rate",
|
22
|
+
field=models.DecimalField(
|
23
|
+
blank=True,
|
24
|
+
decimal_places=8,
|
25
|
+
help_text="Cached USD exchange rate (1 CURRENCY = X USD)",
|
26
|
+
max_digits=20,
|
27
|
+
null=True,
|
28
|
+
),
|
29
|
+
),
|
30
|
+
]
|
@@ -8,7 +8,7 @@ Django ORM models for the universal payments system.
|
|
8
8
|
from .base import TimestampedModel
|
9
9
|
|
10
10
|
# Currency models
|
11
|
-
from .currencies import Currency,
|
11
|
+
from .currencies import Currency, Network, ProviderCurrency
|
12
12
|
|
13
13
|
# Payment models
|
14
14
|
from .payments import UniversalPayment
|
@@ -43,7 +43,8 @@ __all__ = [
|
|
43
43
|
|
44
44
|
# Currencies
|
45
45
|
'Currency',
|
46
|
-
'
|
46
|
+
'Network',
|
47
|
+
'ProviderCurrency',
|
47
48
|
|
48
49
|
# Models
|
49
50
|
'UniversalPayment',
|