django-cfg 1.4.21__py3-none-any.whl → 1.4.23__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 +4 -4
- django_cfg/apps/accounts/__init__.py +1 -1
- django_cfg/apps/accounts/__models.py +30 -29
- django_cfg/apps/accounts/admin/__init__.py +14 -3
- django_cfg/apps/accounts/admin/activity_admin.py +19 -19
- django_cfg/apps/accounts/admin/filters.py +7 -6
- django_cfg/apps/accounts/admin/group_admin.py +10 -16
- django_cfg/apps/accounts/admin/inlines.py +21 -19
- django_cfg/apps/accounts/admin/otp_admin.py +12 -12
- django_cfg/apps/accounts/admin/registration_admin.py +24 -24
- django_cfg/apps/accounts/admin/resources.py +49 -48
- django_cfg/apps/accounts/admin/twilio_admin.py +37 -37
- django_cfg/apps/accounts/admin/user_admin.py +45 -41
- django_cfg/apps/accounts/management/commands/otp_test.py +11 -11
- django_cfg/apps/accounts/managers/__init__.py +1 -1
- django_cfg/apps/accounts/managers/user_manager.py +6 -7
- django_cfg/apps/accounts/migrations/0001_initial.py +3 -2
- django_cfg/apps/accounts/models/__init__.py +15 -16
- django_cfg/apps/accounts/models/activity.py +5 -5
- django_cfg/apps/accounts/models/integrations.py +15 -15
- django_cfg/apps/accounts/models/registration.py +3 -2
- django_cfg/apps/accounts/models/user.py +3 -2
- django_cfg/apps/accounts/serializers/__init__.py +10 -3
- django_cfg/apps/accounts/serializers/otp.py +5 -4
- django_cfg/apps/accounts/serializers/profile.py +4 -5
- django_cfg/apps/accounts/serializers/webhook.py +13 -13
- django_cfg/apps/accounts/services/activity_service.py +13 -12
- django_cfg/apps/accounts/services/otp_service.py +16 -14
- django_cfg/apps/accounts/signals.py +18 -16
- django_cfg/apps/accounts/urls.py +10 -5
- django_cfg/apps/accounts/utils/notifications.py +22 -22
- django_cfg/apps/accounts/views/__init__.py +1 -1
- django_cfg/apps/accounts/views/otp.py +15 -14
- django_cfg/apps/accounts/views/profile.py +14 -10
- django_cfg/apps/accounts/views/webhook.py +46 -48
- django_cfg/apps/agents/__init__.py +3 -3
- django_cfg/apps/agents/admin/__init__.py +1 -1
- django_cfg/apps/agents/admin/execution_admin.py +68 -72
- django_cfg/apps/agents/admin/registry_admin.py +50 -54
- django_cfg/apps/agents/admin/toolsets_admin.py +63 -67
- django_cfg/apps/agents/apps.py +3 -3
- django_cfg/apps/agents/core/__init__.py +4 -4
- django_cfg/apps/agents/core/dependencies.py +24 -23
- django_cfg/apps/agents/core/django_agent.py +41 -39
- django_cfg/apps/agents/core/exceptions.py +12 -12
- django_cfg/apps/agents/core/models.py +16 -15
- django_cfg/apps/agents/core/orchestrator.py +58 -58
- django_cfg/apps/agents/examples/simple_example.py +24 -19
- django_cfg/apps/agents/integration/__init__.py +1 -1
- django_cfg/apps/agents/integration/middleware.py +12 -11
- django_cfg/apps/agents/integration/registry.py +52 -49
- django_cfg/apps/agents/integration/signals.py +5 -5
- django_cfg/apps/agents/management/commands/create_agent.py +39 -38
- django_cfg/apps/agents/management/commands/orchestrator_status.py +40 -39
- django_cfg/apps/agents/managers/__init__.py +8 -3
- django_cfg/apps/agents/managers/execution.py +42 -41
- django_cfg/apps/agents/managers/registry.py +40 -39
- django_cfg/apps/agents/managers/toolsets.py +87 -86
- django_cfg/apps/agents/migrations/0001_initial.py +2 -1
- django_cfg/apps/agents/models/__init__.py +2 -2
- django_cfg/apps/agents/models/execution.py +43 -42
- django_cfg/apps/agents/models/registry.py +46 -45
- django_cfg/apps/agents/models/toolsets.py +63 -62
- django_cfg/apps/agents/patterns/__init__.py +5 -5
- django_cfg/apps/agents/patterns/content_agents.py +17 -16
- django_cfg/apps/agents/toolsets/__init__.py +3 -3
- django_cfg/apps/agents/toolsets/cache_toolset.py +56 -55
- django_cfg/apps/agents/toolsets/django_toolset.py +43 -42
- django_cfg/apps/agents/toolsets/file_toolset.py +64 -63
- django_cfg/apps/agents/toolsets/orm_toolset.py +75 -74
- django_cfg/apps/agents/urls.py +3 -2
- django_cfg/apps/api/commands/urls.py +1 -0
- django_cfg/apps/api/commands/views.py +23 -26
- django_cfg/apps/api/endpoints/checker.py +5 -4
- django_cfg/apps/api/endpoints/drf_views.py +2 -2
- django_cfg/apps/api/endpoints/tests.py +6 -5
- django_cfg/apps/api/endpoints/urls.py +2 -1
- django_cfg/apps/api/endpoints/views.py +1 -0
- django_cfg/apps/api/health/drf_views.py +6 -6
- django_cfg/apps/api/health/urls.py +2 -1
- django_cfg/apps/api/health/views.py +41 -41
- django_cfg/{modules/django_ipc_client → apps/ipc}/__init__.py +6 -6
- django_cfg/apps/ipc/apps.py +28 -0
- django_cfg/apps/ipc/serializers/__init__.py +19 -0
- django_cfg/apps/ipc/serializers/serializers.py +229 -0
- django_cfg/apps/ipc/services/__init__.py +7 -0
- django_cfg/apps/ipc/services/client/__init__.py +23 -0
- django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/client.py +7 -6
- django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/exceptions.py +1 -1
- django_cfg/{modules/django_ipc_client/dashboard → apps/ipc/services}/monitor.py +23 -5
- django_cfg/{modules/django_ipc_client/dashboard/static/django_ipc_dashboard/js/dashboard.js → apps/ipc/static/django_cfg_ipc/js/dashboard.mjs} +131 -63
- django_cfg/{modules/django_ipc_client/dashboard/templates/django_ipc_dashboard → apps/ipc/templates/django_cfg_ipc}/base.html +5 -10
- django_cfg/apps/ipc/templates/django_cfg_ipc/dashboard.html +202 -0
- django_cfg/apps/ipc/urls.py +21 -0
- django_cfg/apps/ipc/urls_admin.py +20 -0
- django_cfg/apps/ipc/views/__init__.py +8 -0
- django_cfg/apps/ipc/views/dashboard.py +15 -0
- django_cfg/apps/ipc/views/viewsets.py +245 -0
- django_cfg/apps/knowbase/admin/__init__.py +2 -2
- django_cfg/apps/knowbase/admin/actions/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/actions/visibility_actions.py +2 -1
- django_cfg/apps/knowbase/admin/archive_admin.py +81 -84
- django_cfg/apps/knowbase/admin/chat_admin.py +70 -72
- django_cfg/apps/knowbase/admin/document_admin.py +10 -11
- django_cfg/apps/knowbase/admin/external_data_admin.py +69 -71
- django_cfg/apps/knowbase/admin/helpers/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/helpers/configs.py +2 -2
- django_cfg/apps/knowbase/admin/helpers/statistics.py +1 -1
- django_cfg/apps/knowbase/apps.py +13 -13
- django_cfg/apps/knowbase/config/__init__.py +7 -6
- django_cfg/apps/knowbase/config/constance_fields.py +14 -12
- django_cfg/apps/knowbase/config/constance_settings.py +32 -31
- django_cfg/apps/knowbase/config/settings.py +28 -28
- django_cfg/apps/knowbase/examples/external_data_usage.py +35 -32
- django_cfg/apps/knowbase/management/commands/knowbase_stats.py +33 -32
- django_cfg/apps/knowbase/management/commands/setup_knowbase.py +11 -13
- django_cfg/apps/knowbase/managers/__init__.py +2 -2
- django_cfg/apps/knowbase/managers/archive.py +86 -85
- django_cfg/apps/knowbase/managers/base.py +5 -5
- django_cfg/apps/knowbase/managers/chat.py +29 -28
- django_cfg/apps/knowbase/managers/document.py +39 -39
- django_cfg/apps/knowbase/managers/external_data.py +74 -73
- django_cfg/apps/knowbase/migrations/0001_initial.py +2 -1
- django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +2 -1
- django_cfg/apps/knowbase/mixins/__init__.py +4 -4
- django_cfg/apps/knowbase/mixins/config/__init__.py +1 -1
- django_cfg/apps/knowbase/mixins/config/meta_config.py +1 -1
- django_cfg/apps/knowbase/mixins/config.py +19 -18
- django_cfg/apps/knowbase/mixins/creator.py +7 -7
- django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +29 -28
- django_cfg/apps/knowbase/mixins/external_data_mixin.py +6 -5
- django_cfg/apps/knowbase/mixins/generators/__init__.py +1 -1
- django_cfg/apps/knowbase/mixins/generators/content_generator.py +2 -2
- django_cfg/apps/knowbase/mixins/service.py +47 -45
- django_cfg/apps/knowbase/models/__init__.py +7 -7
- django_cfg/apps/knowbase/models/archive.py +72 -72
- django_cfg/apps/knowbase/models/base.py +12 -13
- django_cfg/apps/knowbase/models/chat.py +20 -19
- django_cfg/apps/knowbase/models/document.py +37 -35
- django_cfg/apps/knowbase/models/external_data.py +41 -42
- django_cfg/apps/knowbase/serializers/__init__.py +7 -7
- django_cfg/apps/knowbase/serializers/archive_serializers.py +50 -42
- django_cfg/apps/knowbase/serializers/chat_serializers.py +16 -15
- django_cfg/apps/knowbase/serializers/document_serializers.py +13 -12
- django_cfg/apps/knowbase/serializers/external_data_serializers.py +31 -31
- django_cfg/apps/knowbase/serializers/public_serializers.py +10 -9
- django_cfg/apps/knowbase/services/__init__.py +7 -7
- django_cfg/apps/knowbase/services/archive/__init__.py +7 -7
- django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +1 -1
- django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +1 -1
- django_cfg/apps/knowbase/services/archive/archive_service.py +109 -112
- django_cfg/apps/knowbase/services/archive/chunking/__init__.py +3 -3
- django_cfg/apps/knowbase/services/archive/chunking/base.py +1 -0
- django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +4 -3
- django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +5 -4
- django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +6 -5
- django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +4 -3
- django_cfg/apps/knowbase/services/archive/chunking_service.py +3 -7
- django_cfg/apps/knowbase/services/archive/context/__init__.py +1 -1
- django_cfg/apps/knowbase/services/archive/context/builders.py +2 -1
- django_cfg/apps/knowbase/services/archive/context/models.py +2 -1
- django_cfg/apps/knowbase/services/archive/exceptions.py +5 -5
- django_cfg/apps/knowbase/services/archive/extraction_service.py +111 -110
- django_cfg/apps/knowbase/services/archive/vectorization_service.py +80 -77
- django_cfg/apps/knowbase/services/base.py +11 -9
- django_cfg/apps/knowbase/services/chat_service.py +40 -39
- django_cfg/apps/knowbase/services/document_service.py +28 -27
- django_cfg/apps/knowbase/services/embedding/__init__.py +9 -9
- django_cfg/apps/knowbase/services/embedding/async_processor.py +38 -40
- django_cfg/apps/knowbase/services/embedding/batch_processor.py +45 -42
- django_cfg/apps/knowbase/services/embedding/batch_result.py +7 -6
- django_cfg/apps/knowbase/services/embedding/models.py +52 -51
- django_cfg/apps/knowbase/services/embedding/processors.py +24 -23
- django_cfg/apps/knowbase/services/embedding/utils.py +17 -17
- django_cfg/apps/knowbase/services/prompt_builder.py +24 -23
- django_cfg/apps/knowbase/services/search_service.py +52 -49
- django_cfg/apps/knowbase/signals/__init__.py +2 -5
- django_cfg/apps/knowbase/signals/archive_signals.py +35 -34
- django_cfg/apps/knowbase/signals/chat_signals.py +6 -5
- django_cfg/apps/knowbase/signals/document_signals.py +22 -22
- django_cfg/apps/knowbase/signals/external_data_signals.py +22 -22
- django_cfg/apps/knowbase/tasks/__init__.py +6 -7
- django_cfg/apps/knowbase/tasks/archive_tasks.py +41 -41
- django_cfg/apps/knowbase/tasks/document_processing.py +49 -44
- django_cfg/apps/knowbase/tasks/external_data_tasks.py +46 -44
- django_cfg/apps/knowbase/tasks/maintenance.py +26 -24
- django_cfg/apps/knowbase/urls.py +3 -2
- django_cfg/apps/knowbase/urls_admin.py +6 -3
- django_cfg/apps/knowbase/urls_system.py +4 -5
- django_cfg/apps/knowbase/utils/chunk_settings.py +22 -20
- django_cfg/apps/knowbase/utils/text_processing.py +76 -75
- django_cfg/apps/knowbase/utils/validation.py +9 -9
- django_cfg/apps/knowbase/views/__init__.py +5 -5
- django_cfg/apps/knowbase/views/archive_views.py +90 -87
- django_cfg/apps/knowbase/views/base.py +9 -12
- django_cfg/apps/knowbase/views/chat_views.py +32 -32
- django_cfg/apps/knowbase/views/document_views.py +27 -28
- django_cfg/apps/knowbase/views/public_views.py +19 -19
- django_cfg/apps/leads/admin/leads_admin.py +41 -45
- django_cfg/apps/leads/admin/resources.py +14 -14
- django_cfg/apps/leads/admin.py +7 -9
- django_cfg/apps/leads/apps.py +1 -1
- django_cfg/apps/leads/models.py +17 -17
- django_cfg/apps/leads/serializers.py +5 -4
- django_cfg/apps/leads/signals.py +7 -7
- django_cfg/apps/leads/tests.py +47 -47
- django_cfg/apps/leads/urls.py +2 -2
- django_cfg/apps/leads/views.py +11 -11
- django_cfg/apps/maintenance/__init__.py +3 -3
- django_cfg/apps/maintenance/admin/__init__.py +1 -1
- django_cfg/apps/maintenance/admin/api_key_admin.py +36 -36
- django_cfg/apps/maintenance/admin/log_admin.py +35 -37
- django_cfg/apps/maintenance/admin/scheduled_admin.py +47 -51
- django_cfg/apps/maintenance/admin/site_admin.py +49 -52
- django_cfg/apps/maintenance/apps.py +2 -2
- django_cfg/apps/maintenance/management/commands/maintenance.py +53 -52
- django_cfg/apps/maintenance/management/commands/process_scheduled_maintenance.py +44 -44
- django_cfg/apps/maintenance/management/commands/sync_cloudflare.py +32 -32
- django_cfg/apps/maintenance/managers/__init__.py +1 -1
- django_cfg/apps/maintenance/managers/cloudflare_site_manager.py +39 -38
- django_cfg/apps/maintenance/managers/maintenance_log_manager.py +32 -31
- django_cfg/apps/maintenance/migrations/0001_initial.py +1 -0
- django_cfg/apps/maintenance/models/__init__.py +2 -2
- django_cfg/apps/maintenance/models/cloudflare_api_key.py +15 -15
- django_cfg/apps/maintenance/models/cloudflare_site.py +24 -22
- django_cfg/apps/maintenance/models/maintenance_log.py +15 -14
- django_cfg/apps/maintenance/models/scheduled_maintenance.py +53 -52
- django_cfg/apps/maintenance/services/__init__.py +3 -3
- django_cfg/apps/maintenance/services/bulk_operations_service.py +68 -68
- django_cfg/apps/maintenance/services/maintenance_service.py +59 -58
- django_cfg/apps/maintenance/services/scheduled_maintenance_service.py +52 -52
- django_cfg/apps/maintenance/services/site_sync_service.py +64 -65
- django_cfg/apps/maintenance/utils/__init__.py +1 -1
- django_cfg/apps/maintenance/utils/retry_utils.py +17 -17
- django_cfg/apps/newsletter/admin/__init__.py +12 -16
- django_cfg/apps/newsletter/admin/newsletter_admin.py +90 -87
- django_cfg/apps/newsletter/admin/resources.py +29 -29
- django_cfg/apps/newsletter/admin.py +39 -32
- django_cfg/apps/newsletter/management/commands/test_newsletter.py +3 -3
- django_cfg/apps/newsletter/managers/__init__.py +1 -1
- django_cfg/apps/newsletter/migrations/0001_initial.py +2 -1
- django_cfg/apps/newsletter/models.py +34 -33
- django_cfg/apps/newsletter/serializers.py +13 -13
- django_cfg/apps/newsletter/services/email_service.py +42 -40
- django_cfg/apps/newsletter/signals.py +4 -3
- django_cfg/apps/newsletter/urls.py +7 -7
- django_cfg/apps/newsletter/views/__init__.py +14 -19
- django_cfg/apps/newsletter/views/campaigns.py +19 -19
- django_cfg/apps/newsletter/views/emails.py +20 -20
- django_cfg/apps/newsletter/views/newsletters.py +5 -5
- django_cfg/apps/newsletter/views/subscriptions.py +24 -24
- django_cfg/apps/newsletter/views/tracking.py +6 -5
- django_cfg/apps/payments/admin/__init__.py +6 -5
- django_cfg/apps/payments/admin/api_keys_admin.py +43 -45
- django_cfg/apps/payments/admin/balance_admin.py +41 -47
- django_cfg/apps/payments/admin/currencies_admin.py +60 -62
- django_cfg/apps/payments/admin/endpoint_groups_admin.py +14 -28
- django_cfg/apps/payments/admin/filters.py +59 -59
- django_cfg/apps/payments/admin/networks_admin.py +36 -50
- django_cfg/apps/payments/admin/payments_admin.py +47 -49
- django_cfg/apps/payments/admin/subscriptions_admin.py +30 -32
- django_cfg/apps/payments/admin/tariffs_admin.py +37 -42
- django_cfg/apps/payments/admin_interface/serializers/__init__.py +12 -13
- django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +28 -27
- django_cfg/apps/payments/admin_interface/serializers/webhook_serializers.py +4 -5
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +407 -3
- django_cfg/apps/payments/admin_interface/templates/payments/components/ngrok_status.html +13 -13
- django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +5 -1
- django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +105 -49
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +4 -1
- django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +16 -8
- django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +16 -8
- django_cfg/apps/payments/admin_interface/views/__init__.py +8 -9
- django_cfg/apps/payments/admin_interface/views/api/__init__.py +3 -3
- django_cfg/apps/payments/admin_interface/views/api/payments.py +52 -54
- django_cfg/apps/payments/admin_interface/views/api/stats.py +33 -30
- django_cfg/apps/payments/admin_interface/views/api/users.py +10 -11
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +46 -51
- django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +9 -9
- django_cfg/apps/payments/admin_interface/views/base.py +17 -19
- django_cfg/apps/payments/admin_interface/views/dashboard.py +10 -10
- django_cfg/apps/payments/admin_interface/views/forms.py +21 -20
- django_cfg/apps/payments/apps.py +7 -6
- django_cfg/apps/payments/config/__init__.py +4 -4
- django_cfg/apps/payments/config/django_cfg_integration.py +22 -21
- django_cfg/apps/payments/config/helpers.py +14 -12
- django_cfg/apps/payments/management/commands/cleanup_expired_data.py +85 -86
- django_cfg/apps/payments/management/commands/currency_stats.py +84 -87
- django_cfg/apps/payments/management/commands/manage_currencies.py +59 -58
- django_cfg/apps/payments/management/commands/manage_providers.py +103 -105
- django_cfg/apps/payments/management/commands/process_pending_payments.py +67 -70
- django_cfg/apps/payments/management/commands/test_providers.py +83 -84
- django_cfg/apps/payments/middleware/__init__.py +1 -1
- django_cfg/apps/payments/middleware/api_access.py +77 -78
- django_cfg/apps/payments/middleware/rate_limiting.py +72 -72
- django_cfg/apps/payments/middleware/usage_tracking.py +66 -64
- django_cfg/apps/payments/migrations/0001_initial.py +2 -1
- django_cfg/apps/payments/models/__init__.py +11 -12
- django_cfg/apps/payments/models/api_keys.py +29 -27
- django_cfg/apps/payments/models/balance.py +38 -38
- django_cfg/apps/payments/models/base.py +12 -11
- django_cfg/apps/payments/models/currencies.py +53 -52
- django_cfg/apps/payments/models/managers/__init__.py +13 -14
- django_cfg/apps/payments/models/managers/api_key_managers.py +55 -53
- django_cfg/apps/payments/models/managers/balance_managers.py +98 -97
- django_cfg/apps/payments/models/managers/currency_managers.py +70 -69
- django_cfg/apps/payments/models/managers/payment_managers.py +113 -111
- django_cfg/apps/payments/models/managers/subscription_managers.py +99 -97
- django_cfg/apps/payments/models/payments.py +167 -73
- django_cfg/apps/payments/models/subscriptions.py +56 -54
- django_cfg/apps/payments/models/tariffs.py +35 -34
- django_cfg/apps/payments/services/__init__.py +33 -36
- django_cfg/apps/payments/services/cache/__init__.py +7 -1
- django_cfg/apps/payments/services/cache_service/__init__.py +22 -20
- django_cfg/apps/payments/services/cache_service/api_key_cache.py +6 -5
- django_cfg/apps/payments/services/cache_service/interfaces.py +5 -5
- django_cfg/apps/payments/services/cache_service/keys.py +8 -8
- django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +8 -7
- django_cfg/apps/payments/services/cache_service/simple_cache.py +17 -14
- django_cfg/apps/payments/services/core/__init__.py +3 -3
- django_cfg/apps/payments/services/core/balance_service.py +69 -65
- django_cfg/apps/payments/services/core/base.py +25 -22
- django_cfg/apps/payments/services/core/currency/__init__.py +1 -1
- django_cfg/apps/payments/services/core/currency/currency_converter.py +2 -0
- django_cfg/apps/payments/services/core/currency_service.py +68 -66
- django_cfg/apps/payments/services/core/operations/__init__.py +1 -1
- django_cfg/apps/payments/services/core/operations/payment_canceller.py +2 -1
- django_cfg/apps/payments/services/core/operations/payment_creator.py +2 -1
- django_cfg/apps/payments/services/core/operations/status_checker.py +2 -1
- django_cfg/apps/payments/services/core/payment_service.py +10 -7
- django_cfg/apps/payments/services/core/providers/provider_client.py +2 -2
- django_cfg/apps/payments/services/core/subscription_service.py +77 -74
- django_cfg/apps/payments/services/core/utils/data_converter.py +1 -0
- django_cfg/apps/payments/services/core/utils/statistics_calculator.py +1 -0
- django_cfg/apps/payments/services/core/webhook_service.py +67 -63
- django_cfg/apps/payments/services/integrations/__init__.py +3 -3
- django_cfg/apps/payments/services/integrations/ngrok_service.py +1 -0
- django_cfg/apps/payments/services/integrations/providers_config.py +3 -2
- django_cfg/apps/payments/services/providers/base.py +59 -57
- django_cfg/apps/payments/services/providers/models/__init__.py +7 -14
- django_cfg/apps/payments/services/providers/models/base.py +15 -15
- django_cfg/apps/payments/services/providers/models/providers.py +13 -12
- django_cfg/apps/payments/services/providers/models/universal.py +6 -5
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -4
- django_cfg/apps/payments/services/providers/nowpayments/config.py +9 -8
- django_cfg/apps/payments/services/providers/nowpayments/models.py +15 -15
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +2 -2
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +26 -26
- django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +3 -2
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +95 -99
- django_cfg/apps/payments/services/providers/nowpayments/sync.py +41 -40
- django_cfg/apps/payments/services/providers/registry.py +65 -63
- django_cfg/apps/payments/services/providers/sync_service.py +50 -50
- django_cfg/apps/payments/services/types/__init__.py +21 -22
- django_cfg/apps/payments/services/types/data.py +14 -13
- django_cfg/apps/payments/services/types/requests.py +21 -22
- django_cfg/apps/payments/services/types/responses.py +16 -15
- django_cfg/apps/payments/services/types/webhooks.py +30 -30
- django_cfg/apps/payments/signals/__init__.py +4 -6
- django_cfg/apps/payments/signals/api_key_signals.py +33 -32
- django_cfg/apps/payments/signals/balance_signals.py +28 -26
- django_cfg/apps/payments/signals/payment_signals.py +29 -28
- django_cfg/apps/payments/signals/subscription_signals.py +39 -38
- django_cfg/apps/payments/static/payments/js/ngrok-status.js +12 -8
- django_cfg/apps/payments/static/payments/js/payment-detail.js +1 -1
- django_cfg/apps/payments/static/payments/js/payment-form.js +3 -3
- django_cfg/apps/payments/static/payments/js/payment-list.js +13 -6
- django_cfg/apps/payments/static/payments/js/webhook-dashboard-mjs.js +241 -0
- django_cfg/apps/payments/tasks/__init__.py +11 -12
- django_cfg/apps/payments/tasks/types.py +10 -9
- django_cfg/apps/payments/tasks/usage_tracking.py +44 -46
- django_cfg/apps/payments/templatetags/payment_tags.py +27 -27
- django_cfg/apps/payments/urls.py +31 -14
- django_cfg/apps/payments/urls_admin.py +10 -10
- django_cfg/apps/payments/views/api/__init__.py +32 -33
- django_cfg/apps/payments/views/api/api_keys.py +62 -62
- django_cfg/apps/payments/views/api/balances.py +63 -64
- django_cfg/apps/payments/views/api/base.py +52 -52
- django_cfg/apps/payments/views/api/currencies.py +75 -63
- django_cfg/apps/payments/views/api/payments.py +73 -74
- django_cfg/apps/payments/views/api/subscriptions.py +71 -72
- django_cfg/apps/payments/views/api/webhooks.py +85 -84
- django_cfg/apps/payments/views/overview/__init__.py +7 -7
- django_cfg/apps/payments/views/overview/serializers.py +13 -14
- django_cfg/apps/payments/views/overview/services.py +66 -67
- django_cfg/apps/payments/views/overview/urls.py +2 -1
- django_cfg/apps/payments/views/overview/views.py +31 -31
- django_cfg/apps/payments/views/serializers/__init__.py +35 -36
- django_cfg/apps/payments/views/serializers/api_keys.py +59 -57
- django_cfg/apps/payments/views/serializers/balances.py +34 -33
- django_cfg/apps/payments/views/serializers/currencies.py +36 -34
- django_cfg/apps/payments/views/serializers/payments.py +48 -47
- django_cfg/apps/payments/views/serializers/subscriptions.py +50 -45
- django_cfg/apps/payments/views/serializers/webhooks.py +17 -16
- django_cfg/apps/support/admin/__init__.py +3 -3
- django_cfg/apps/support/admin/resources.py +26 -26
- django_cfg/apps/support/admin/support_admin.py +44 -48
- django_cfg/apps/support/admin.py +16 -15
- django_cfg/apps/support/apps.py +1 -1
- django_cfg/apps/support/managers/message_manager.py +4 -4
- django_cfg/apps/support/managers/ticket_manager.py +13 -12
- django_cfg/apps/support/migrations/0001_initial.py +2 -1
- django_cfg/apps/support/models.py +3 -1
- django_cfg/apps/support/serializers.py +4 -2
- django_cfg/apps/support/signals.py +12 -10
- django_cfg/apps/support/urls.py +4 -3
- django_cfg/apps/support/utils/support_email_service.py +11 -9
- django_cfg/apps/support/views/__init__.py +3 -3
- django_cfg/apps/support/views/admin.py +9 -9
- django_cfg/apps/support/views/api.py +10 -9
- django_cfg/apps/support/views/chat.py +14 -14
- django_cfg/apps/tasks/admin/tasks_admin.py +65 -74
- django_cfg/apps/tasks/apps.py +2 -2
- django_cfg/apps/tasks/serializers.py +6 -6
- django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +44 -20
- django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +7 -5
- django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +5 -3
- django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +5 -3
- django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +5 -3
- django_cfg/apps/tasks/tasks/demo_tasks.py +12 -11
- django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +269 -0
- django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +168 -0
- django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +21 -2
- django_cfg/apps/tasks/urls.py +3 -2
- django_cfg/apps/tasks/urls_admin.py +1 -0
- django_cfg/apps/tasks/utils/simulator.py +49 -52
- django_cfg/apps/tasks/views/api.py +75 -73
- django_cfg/apps/tasks/views/dashboard.py +5 -4
- django_cfg/apps/urls.py +20 -11
- django_cfg/apps.py +6 -5
- django_cfg/cli/commands/create_project.py +7 -6
- django_cfg/cli/commands/info.py +25 -25
- django_cfg/cli/utils.py +27 -27
- django_cfg/config.py +1 -1
- django_cfg/core/__init__.py +8 -8
- django_cfg/core/base/config_model.py +13 -12
- django_cfg/core/builders/apps_builder.py +2 -2
- django_cfg/core/builders/middleware_builder.py +1 -1
- django_cfg/core/builders/security_builder.py +1 -1
- django_cfg/core/config.py +2 -2
- django_cfg/core/environment/detector.py +27 -28
- django_cfg/core/exceptions.py +1 -1
- django_cfg/core/generation/core_generators/settings.py +1 -1
- django_cfg/core/generation/core_generators/static.py +11 -5
- django_cfg/core/generation/core_generators/templates.py +1 -1
- django_cfg/core/generation/data_generators/__init__.py +1 -1
- django_cfg/core/generation/data_generators/cache.py +1 -1
- django_cfg/core/generation/data_generators/database.py +1 -1
- django_cfg/core/generation/generation.py +1 -3
- django_cfg/core/generation/integration_generators/__init__.py +2 -2
- django_cfg/core/generation/integration_generators/api.py +12 -2
- django_cfg/core/generation/integration_generators/sessions.py +1 -1
- django_cfg/core/generation/integration_generators/tailwind.py +1 -1
- django_cfg/core/generation/integration_generators/tasks.py +1 -1
- django_cfg/core/generation/integration_generators/third_party.py +1 -1
- django_cfg/core/generation/orchestrator.py +1 -1
- django_cfg/core/generation/protocols.py +1 -1
- django_cfg/core/generation/utility_generators/__init__.py +1 -1
- django_cfg/core/generation/utility_generators/email.py +1 -1
- django_cfg/core/generation/utility_generators/i18n.py +1 -1
- django_cfg/core/generation/utility_generators/limits.py +1 -1
- django_cfg/core/generation/utility_generators/logging.py +1 -1
- django_cfg/core/generation/utility_generators/security.py +1 -1
- django_cfg/core/generation/utils/helpers.py +1 -1
- django_cfg/core/integration/__init__.py +5 -5
- django_cfg/core/integration/commands_collector.py +38 -39
- django_cfg/core/integration/display/__init__.py +2 -2
- django_cfg/core/integration/display/base.py +30 -30
- django_cfg/core/integration/display/ngrok.py +35 -36
- django_cfg/core/integration/display/startup.py +149 -139
- django_cfg/core/integration/url_integration.py +10 -10
- django_cfg/core/integration/version_checker.py +20 -19
- django_cfg/core/services/config_service.py +4 -4
- django_cfg/core/state/__init__.py +1 -1
- django_cfg/core/state/registry.py +1 -1
- django_cfg/core/types/__init__.py +8 -1
- django_cfg/core/validation.py +36 -39
- django_cfg/management/commands/check_endpoints.py +3 -1
- django_cfg/management/commands/check_settings.py +3 -1
- django_cfg/management/commands/clear_constance.py +3 -1
- django_cfg/management/commands/create_token.py +3 -1
- django_cfg/management/commands/generate_clients.py +3 -1
- django_cfg/management/commands/migrate_all.py +3 -1
- django_cfg/management/commands/rundramatiq.py +3 -1
- django_cfg/management/commands/rundramatiq_simulator.py +3 -1
- django_cfg/management/commands/runserver_ngrok.py +3 -1
- django_cfg/management/commands/show_config.py +3 -1
- django_cfg/management/commands/superuser.py +3 -1
- django_cfg/management/commands/task_clear.py +3 -1
- django_cfg/management/commands/task_status.py +3 -1
- django_cfg/management/commands/test_email.py +3 -1
- django_cfg/management/commands/test_telegram.py +3 -1
- django_cfg/management/commands/test_twilio.py +3 -1
- django_cfg/management/commands/validate_openapi.py +3 -1
- django_cfg/middleware/pagination.py +8 -8
- django_cfg/middleware/public_endpoints.py +24 -23
- django_cfg/middleware/user_activity.py +27 -25
- django_cfg/models/__init__.py +19 -20
- django_cfg/models/api/__init__.py +4 -4
- django_cfg/models/api/config.py +23 -21
- django_cfg/models/api/cors.py +17 -16
- django_cfg/models/api/drf/__init__.py +1 -1
- django_cfg/models/api/drf/config.py +2 -1
- django_cfg/models/api/drf/redoc.py +2 -1
- django_cfg/models/api/drf/spectacular.py +4 -2
- django_cfg/models/api/drf/swagger.py +2 -1
- django_cfg/models/api/jwt.py +37 -36
- django_cfg/models/api/keys.py +13 -12
- django_cfg/models/api/limits.py +31 -30
- django_cfg/models/base/config.py +40 -41
- django_cfg/models/base/module.py +8 -8
- django_cfg/models/django/__init__.py +1 -1
- django_cfg/models/django/constance.py +8 -7
- django_cfg/models/django/environment.py +5 -3
- django_cfg/models/django/openapi.py +6 -16
- django_cfg/models/django/revolution_legacy.py +17 -16
- django_cfg/models/infrastructure/__init__.py +1 -1
- django_cfg/models/infrastructure/cache.py +46 -45
- django_cfg/models/infrastructure/database/config.py +4 -6
- django_cfg/models/infrastructure/database/converters.py +1 -1
- django_cfg/models/infrastructure/database/parsers.py +1 -1
- django_cfg/models/infrastructure/database/validators.py +1 -1
- django_cfg/models/infrastructure/logging.py +59 -57
- django_cfg/models/infrastructure/security.py +26 -24
- django_cfg/models/ngrok/auth.py +2 -1
- django_cfg/models/ngrok/config.py +3 -2
- django_cfg/models/ngrok/tunnel.py +2 -1
- django_cfg/models/payments/__init__.py +1 -1
- django_cfg/models/payments/api_keys.py +3 -1
- django_cfg/models/payments/config.py +4 -1
- django_cfg/models/payments/providers/base.py +2 -1
- django_cfg/models/payments/providers/nowpayments.py +3 -1
- django_cfg/models/services/__init__.py +1 -1
- django_cfg/models/services/base.py +2 -1
- django_cfg/models/services/email.py +28 -26
- django_cfg/models/services/telegram.py +2 -1
- django_cfg/models/tasks/__init__.py +2 -2
- django_cfg/models/tasks/backends.py +4 -3
- django_cfg/models/tasks/config.py +6 -4
- django_cfg/models/tasks/utils.py +3 -3
- django_cfg/modules/base.py +18 -17
- django_cfg/modules/django_admin/__init__.py +14 -15
- django_cfg/modules/django_admin/decorators/__init__.py +1 -1
- django_cfg/modules/django_admin/decorators/actions.py +8 -7
- django_cfg/modules/django_admin/decorators/display.py +9 -7
- django_cfg/modules/django_admin/icons/__init__.py +1 -1
- django_cfg/modules/django_admin/icons/constants.py +27 -27
- django_cfg/modules/django_admin/icons/generate_icons.py +54 -54
- django_cfg/modules/django_admin/management/commands/check_endpoints.py +5 -3
- django_cfg/modules/django_admin/management/commands/check_settings.py +40 -44
- django_cfg/modules/django_admin/management/commands/clear_constance.py +29 -30
- django_cfg/modules/django_admin/management/commands/create_token.py +42 -42
- django_cfg/modules/django_admin/management/commands/list_urls.py +37 -38
- django_cfg/modules/django_admin/management/commands/migrate_all.py +13 -15
- django_cfg/modules/django_admin/management/commands/migrator.py +17 -17
- django_cfg/modules/django_admin/management/commands/script.py +58 -60
- django_cfg/modules/django_admin/management/commands/show_config.py +32 -30
- django_cfg/modules/django_admin/management/commands/show_urls.py +46 -44
- django_cfg/modules/django_admin/management/commands/superuser.py +47 -48
- django_cfg/modules/django_admin/management/commands/tree.py +50 -54
- django_cfg/modules/django_admin/mixins/display_mixin.py +16 -15
- django_cfg/modules/django_admin/mixins/optimization_mixin.py +9 -8
- django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +25 -24
- django_cfg/modules/django_admin/models/__init__.py +4 -4
- django_cfg/modules/django_admin/models/action_models.py +3 -1
- django_cfg/modules/django_admin/models/badge_models.py +4 -2
- django_cfg/modules/django_admin/models/base.py +3 -3
- django_cfg/modules/django_admin/models/display_models.py +1 -0
- django_cfg/modules/django_admin/utils/badges.py +27 -26
- django_cfg/modules/django_admin/utils/displays.py +49 -49
- django_cfg/modules/django_client/apps.py +21 -3
- django_cfg/modules/django_client/core/__init__.py +9 -10
- django_cfg/modules/django_client/core/archive/manager.py +2 -2
- django_cfg/modules/django_client/core/cli/main.py +1 -3
- django_cfg/modules/django_client/core/config/config.py +3 -1
- django_cfg/modules/django_client/core/config/group.py +1 -0
- django_cfg/modules/django_client/core/config/service.py +2 -1
- django_cfg/modules/django_client/core/generator/__init__.py +1 -1
- django_cfg/modules/django_client/core/generator/base.py +2 -2
- django_cfg/modules/django_client/core/generator/python/async_client_gen.py +1 -1
- django_cfg/modules/django_client/core/generator/python/files_generator.py +1 -1
- django_cfg/modules/django_client/core/generator/python/generator.py +4 -4
- django_cfg/modules/django_client/core/generator/python/models_generator.py +1 -1
- django_cfg/modules/django_client/core/generator/python/operations_generator.py +2 -2
- django_cfg/modules/django_client/core/generator/python/sync_client_gen.py +1 -1
- django_cfg/modules/django_client/core/generator/typescript/client_generator.py +3 -1
- django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py +14 -13
- django_cfg/modules/django_client/core/generator/typescript/files_generator.py +1 -0
- django_cfg/modules/django_client/core/generator/typescript/generator.py +6 -6
- django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +12 -10
- django_cfg/modules/django_client/core/generator/typescript/models_generator.py +2 -1
- django_cfg/modules/django_client/core/generator/typescript/naming.py +2 -3
- django_cfg/modules/django_client/core/generator/typescript/operations_generator.py +12 -10
- django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +3 -2
- django_cfg/modules/django_client/core/generator/typescript/templates/client/client.ts.jinja +14 -6
- django_cfg/modules/django_client/core/generator/typescript/templates/main_index.ts.jinja +4 -10
- django_cfg/modules/django_client/core/groups/__init__.py +1 -1
- django_cfg/modules/django_client/core/groups/detector.py +2 -1
- django_cfg/modules/django_client/core/groups/manager.py +2 -1
- django_cfg/modules/django_client/core/ir/schema.py +1 -1
- django_cfg/modules/django_client/core/parser/base.py +0 -2
- django_cfg/modules/django_client/core/parser/models/schema.py +1 -1
- django_cfg/modules/django_client/core/validation/__init__.py +1 -1
- django_cfg/modules/django_client/core/validation/fixer.py +1 -2
- django_cfg/modules/django_client/core/validation/reporter.py +2 -2
- django_cfg/modules/django_client/core/validation/safety.py +1 -1
- django_cfg/modules/django_client/management/commands/generate_client.py +14 -11
- django_cfg/modules/django_client/management/commands/validate_openapi.py +4 -6
- django_cfg/modules/django_client/spectacular/__init__.py +1 -1
- django_cfg/modules/django_client/spectacular/async_detection.py +3 -2
- django_cfg/modules/django_client/spectacular/enum_naming.py +1 -1
- django_cfg/modules/django_client/spectacular/schema.py +5 -5
- django_cfg/modules/django_client/system/__init__.py +24 -0
- django_cfg/modules/django_client/system/base_generator.py +123 -0
- django_cfg/modules/django_client/system/generate_mjs_clients.py +174 -0
- django_cfg/modules/django_client/system/mjs_generator.py +219 -0
- django_cfg/modules/django_client/system/schema_parser.py +195 -0
- django_cfg/modules/django_client/system/templates/api_client.js.j2 +87 -0
- django_cfg/modules/django_client/system/templates/app_index.js.j2 +13 -0
- django_cfg/modules/django_client/system/templates/base_client.js.j2 +166 -0
- django_cfg/modules/django_client/system/templates/main_index.js.j2 +80 -0
- django_cfg/modules/django_client/system/templates/types.js.j2 +24 -0
- django_cfg/modules/django_client/urls.py +3 -2
- django_cfg/modules/django_currency/__init__.py +17 -18
- django_cfg/modules/django_currency/clients/__init__.py +2 -2
- django_cfg/modules/django_currency/clients/coinpaprika_client.py +48 -48
- django_cfg/modules/django_currency/clients/hybrid_client.py +76 -75
- django_cfg/modules/django_currency/core/__init__.py +7 -13
- django_cfg/modules/django_currency/core/converter.py +25 -24
- django_cfg/modules/django_currency/core/models.py +9 -8
- django_cfg/modules/django_currency/database/__init__.py +4 -4
- django_cfg/modules/django_currency/database/database_loader.py +65 -66
- django_cfg/modules/django_currency/examples/example_database_usage.py +29 -28
- django_cfg/modules/django_currency/utils/cache.py +10 -11
- django_cfg/modules/django_dashboard/__init__.py +4 -5
- django_cfg/modules/django_dashboard/components.py +11 -7
- django_cfg/modules/django_dashboard/debug.py +1 -3
- django_cfg/modules/django_dashboard/management/commands/debug_dashboard.py +3 -3
- django_cfg/modules/django_dashboard/sections/base.py +2 -1
- django_cfg/modules/django_dashboard/sections/commands.py +3 -2
- django_cfg/modules/django_dashboard/sections/documentation.py +8 -6
- django_cfg/modules/django_dashboard/sections/overview.py +13 -9
- django_cfg/modules/django_dashboard/sections/stats.py +2 -2
- django_cfg/modules/django_dashboard/sections/system.py +2 -1
- django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +12 -4
- django_cfg/modules/django_email/management/commands/test_email.py +8 -7
- django_cfg/modules/django_email/service.py +5 -4
- django_cfg/modules/django_health/service.py +46 -44
- django_cfg/modules/django_import_export/__init__.py +7 -3
- django_cfg/modules/django_llm/__init__.py +3 -2
- django_cfg/modules/django_llm/example.py +58 -56
- django_cfg/modules/django_llm/llm/__init__.py +1 -1
- django_cfg/modules/django_llm/llm/cache.py +21 -20
- django_cfg/modules/django_llm/llm/client.py +9 -9
- django_cfg/modules/django_llm/llm/costs.py +14 -14
- django_cfg/modules/django_llm/llm/embeddings/__init__.py +1 -1
- django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +1 -2
- django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +1 -2
- django_cfg/modules/django_llm/llm/extractor.py +8 -8
- django_cfg/modules/django_llm/llm/models.py +5 -5
- django_cfg/modules/django_llm/llm/models_api/models_query.py +2 -2
- django_cfg/modules/django_llm/llm/models_cache.py +91 -92
- django_cfg/modules/django_llm/llm/providers/config_builder.py +1 -1
- django_cfg/modules/django_llm/llm/providers/provider_manager.py +2 -1
- django_cfg/modules/django_llm/llm/requests/cache_manager.py +1 -1
- django_cfg/modules/django_llm/llm/requests/chat_handler.py +2 -2
- django_cfg/modules/django_llm/llm/requests/embedding_handler.py +1 -1
- django_cfg/modules/django_llm/llm/responses/response_builder.py +2 -2
- django_cfg/modules/django_llm/llm/stats/stats_manager.py +1 -1
- django_cfg/modules/django_llm/llm/tokenizer.py +10 -9
- django_cfg/modules/django_llm/translator/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/cache.py +36 -35
- django_cfg/modules/django_llm/translator/detectors/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/detectors/script_detector.py +0 -1
- django_cfg/modules/django_llm/translator/stats/stats_tracker.py +1 -1
- django_cfg/modules/django_llm/translator/translator.py +5 -4
- django_cfg/modules/django_llm/translator/translators/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/translators/json_translator.py +1 -1
- django_cfg/modules/django_llm/translator/utils/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/utils/prompt_builder.py +0 -1
- django_cfg/modules/django_logging/__init__.py +1 -1
- django_cfg/modules/django_logging/django_logger.py +33 -34
- django_cfg/modules/django_logging/logger.py +3 -7
- django_cfg/modules/django_ngrok/__init__.py +7 -7
- django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +33 -30
- django_cfg/modules/django_ngrok/service.py +33 -32
- django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +4 -36
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +1 -1
- django_cfg/modules/django_tasks/__init__.py +5 -5
- django_cfg/modules/django_tasks/dramatiq_setup.py +1 -1
- django_cfg/modules/django_tasks/factory.py +1 -1
- django_cfg/modules/django_tasks/management/commands/rundramatiq.py +39 -40
- django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +79 -80
- django_cfg/modules/django_tasks/management/commands/task_clear.py +34 -34
- django_cfg/modules/django_tasks/management/commands/task_status.py +34 -34
- django_cfg/modules/django_tasks/service.py +4 -3
- django_cfg/modules/django_tasks/settings.py +1 -1
- django_cfg/modules/django_telegram/__init__.py +4 -4
- django_cfg/modules/django_telegram/management/commands/test_telegram.py +4 -5
- django_cfg/modules/django_telegram/service.py +4 -3
- django_cfg/modules/django_telegram/utils.py +1 -1
- django_cfg/modules/django_twilio/__init__.py +15 -16
- django_cfg/modules/django_twilio/_imports.py +1 -1
- django_cfg/modules/django_twilio/base.py +9 -5
- django_cfg/modules/django_twilio/email_otp.py +4 -3
- django_cfg/modules/django_twilio/exceptions.py +36 -36
- django_cfg/modules/django_twilio/management/commands/test_twilio.py +6 -7
- django_cfg/modules/django_twilio/models.py +54 -53
- django_cfg/modules/django_twilio/sendgrid_service.py +70 -72
- django_cfg/modules/django_twilio/simple_service.py +42 -41
- django_cfg/modules/django_twilio/sms.py +1 -0
- django_cfg/modules/django_twilio/twilio_service.py +79 -83
- django_cfg/modules/django_twilio/unified.py +6 -5
- django_cfg/modules/django_twilio/utils.py +2 -3
- django_cfg/modules/django_twilio/whatsapp.py +3 -2
- django_cfg/modules/django_unfold/__init__.py +7 -6
- django_cfg/modules/django_unfold/callbacks/actions.py +6 -5
- django_cfg/modules/django_unfold/callbacks/apizones.py +122 -0
- django_cfg/modules/django_unfold/callbacks/base.py +9 -8
- django_cfg/modules/django_unfold/callbacks/charts.py +36 -37
- django_cfg/modules/django_unfold/callbacks/commands.py +2 -2
- django_cfg/modules/django_unfold/callbacks/main.py +27 -27
- django_cfg/modules/django_unfold/callbacks/statistics.py +12 -12
- django_cfg/modules/django_unfold/callbacks/system.py +5 -5
- django_cfg/modules/django_unfold/callbacks/users.py +4 -4
- django_cfg/modules/django_unfold/dashboard.py +29 -29
- django_cfg/modules/django_unfold/models/__init__.py +23 -8
- django_cfg/modules/django_unfold/models/config.py +84 -81
- django_cfg/modules/django_unfold/models/dashboard.py +20 -19
- django_cfg/modules/django_unfold/models/dropdown.py +6 -4
- django_cfg/modules/django_unfold/models/navigation.py +6 -4
- django_cfg/modules/django_unfold/models/tabs.py +4 -3
- django_cfg/modules/django_unfold/models.py +2 -3
- django_cfg/modules/django_unfold/system_monitor.py +27 -25
- django_cfg/modules/django_unfold/tailwind.py +12 -14
- django_cfg/modules/django_unfold/utils.py +7 -6
- django_cfg/pyproject.toml +1 -1
- django_cfg/registry/__init__.py +3 -3
- django_cfg/registry/core.py +8 -8
- django_cfg/registry/modules.py +2 -2
- django_cfg/registry/services.py +2 -2
- django_cfg/registry/third_party.py +3 -3
- django_cfg/routing/__init__.py +3 -3
- django_cfg/routing/callbacks.py +27 -26
- django_cfg/routing/routers.py +2 -2
- django_cfg/static/js/api/accounts/client.mjs +69 -0
- django_cfg/static/js/api/accounts/index.mjs +13 -0
- django_cfg/static/js/api/base.mjs +166 -0
- django_cfg/static/js/api/index.mjs +100 -0
- django_cfg/static/js/api/ipc/client.mjs +74 -0
- django_cfg/static/js/api/ipc/index.mjs +13 -0
- django_cfg/static/js/api/leads/client.mjs +71 -0
- django_cfg/static/js/api/leads/index.mjs +13 -0
- django_cfg/static/js/api/newsletter/client.mjs +109 -0
- django_cfg/static/js/api/newsletter/index.mjs +13 -0
- django_cfg/static/js/api/payments/client.mjs +1264 -0
- django_cfg/static/js/api/payments/index.mjs +13 -0
- django_cfg/static/js/api/support/client.mjs +84 -0
- django_cfg/static/js/api/support/index.mjs +13 -0
- django_cfg/static/js/api/tasks/client.mjs +74 -0
- django_cfg/static/js/api/tasks/index.mjs +13 -0
- django_cfg/static/js/api/types.mjs +729 -0
- django_cfg/static/js/api-loader.mjs +169 -0
- django_cfg/templates/admin/snippets/zones/zones_table.html +4 -3
- django_cfg/templatetags/django_cfg.py +4 -4
- django_cfg/utils/path_resolution.py +49 -50
- django_cfg/utils/smart_defaults.py +27 -29
- django_cfg/utils/version_check.py +14 -14
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.23.dist-info}/METADATA +1 -1
- django_cfg-1.4.23.dist-info/RECORD +1137 -0
- django_cfg/apps/payments/static/payments/js/api-client.js +0 -408
- django_cfg/modules/django_ipc_client/dashboard/README.md +0 -517
- django_cfg/modules/django_ipc_client/dashboard/UNFOLD_INTEGRATION.md +0 -439
- django_cfg/modules/django_ipc_client/dashboard/__init__.py +0 -11
- django_cfg/modules/django_ipc_client/dashboard/apps.py +0 -22
- django_cfg/modules/django_ipc_client/dashboard/templates/django_ipc_dashboard/dashboard.html +0 -200
- django_cfg/modules/django_ipc_client/dashboard/urls.py +0 -22
- django_cfg/modules/django_ipc_client/dashboard/urls_admin.py +0 -9
- django_cfg/modules/django_ipc_client/dashboard/views.py +0 -251
- django_cfg/modules/django_rpc_old/POETRY.md +0 -344
- django_cfg/modules/django_rpc_old/README.md +0 -397
- django_cfg/modules/django_rpc_old/TESTING.md +0 -358
- django_cfg/modules/django_rpc_old/__init__.py +0 -39
- django_cfg/modules/django_rpc_old/client.py +0 -531
- django_cfg/modules/django_rpc_old/config.py +0 -279
- django_cfg/modules/django_rpc_old/exceptions.py +0 -172
- django_cfg/modules/django_unfold/callbacks/revolution.py +0 -81
- django_cfg-1.4.21.dist-info/RECORD +0 -1111
- /django_cfg/{modules/django_ipc_client → apps/ipc}/README.md +0 -0
- /django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/config.py +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.23.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.23.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.23.dist-info}/licenses/LICENSE +0 -0
@@ -4,12 +4,12 @@ Payment models for the Universal Payment System v2.0.
|
|
4
4
|
Core payment model with simplified architecture focused on NowPayments.
|
5
5
|
"""
|
6
6
|
|
7
|
-
from decimal import Decimal
|
8
|
-
from django.db import models
|
9
7
|
from django.contrib.auth import get_user_model
|
10
|
-
from django.core.validators import MinValueValidator, MaxValueValidator
|
11
8
|
from django.core.exceptions import ValidationError
|
9
|
+
from django.core.validators import MaxValueValidator, MinValueValidator
|
10
|
+
from django.db import models
|
12
11
|
from django.utils import timezone
|
12
|
+
|
13
13
|
from .base import UUIDTimestampedModel
|
14
14
|
from .currencies import Currency, Network
|
15
15
|
|
@@ -23,7 +23,7 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
23
23
|
Simplified v2.0 architecture focused on NowPayments with extensible design.
|
24
24
|
Uses float for USD amounts as per requirements for performance and API compatibility.
|
25
25
|
"""
|
26
|
-
|
26
|
+
|
27
27
|
class PaymentStatus(models.TextChoices):
|
28
28
|
PENDING = "pending", "Pending"
|
29
29
|
CONFIRMING = "confirming", "Confirming"
|
@@ -33,21 +33,21 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
33
33
|
EXPIRED = "expired", "Expired"
|
34
34
|
CANCELLED = "cancelled", "Cancelled"
|
35
35
|
REFUNDED = "refunded", "Refunded"
|
36
|
-
|
36
|
+
|
37
37
|
class PaymentProvider(models.TextChoices):
|
38
38
|
NOWPAYMENTS = "nowpayments", "NowPayments"
|
39
39
|
# Future providers can be added here
|
40
|
-
|
40
|
+
|
41
41
|
@classmethod
|
42
42
|
def get_crypto_providers(cls):
|
43
43
|
"""Get list of crypto provider values."""
|
44
44
|
return [cls.NOWPAYMENTS]
|
45
|
-
|
45
|
+
|
46
46
|
@classmethod
|
47
47
|
def is_crypto_provider(cls, provider_name: str) -> bool:
|
48
48
|
"""Check if provider handles cryptocurrency."""
|
49
49
|
return provider_name in cls.get_crypto_providers()
|
50
|
-
|
50
|
+
|
51
51
|
# User and identification
|
52
52
|
user = models.ForeignKey(
|
53
53
|
User,
|
@@ -55,20 +55,20 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
55
55
|
related_name='payments',
|
56
56
|
help_text="User who created this payment"
|
57
57
|
)
|
58
|
-
|
58
|
+
|
59
59
|
internal_payment_id = models.CharField(
|
60
60
|
max_length=100,
|
61
61
|
unique=True,
|
62
62
|
db_index=True,
|
63
63
|
help_text="Internal payment identifier"
|
64
64
|
)
|
65
|
-
|
65
|
+
|
66
66
|
# Financial information (USD as float per requirements)
|
67
67
|
amount_usd = models.FloatField(
|
68
68
|
validators=[MinValueValidator(1.0), MaxValueValidator(50000.0)],
|
69
69
|
help_text="Payment amount in USD (float for performance)"
|
70
70
|
)
|
71
|
-
|
71
|
+
|
72
72
|
# Cryptocurrency information
|
73
73
|
currency = models.ForeignKey(
|
74
74
|
Currency,
|
@@ -76,7 +76,7 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
76
76
|
related_name='payments',
|
77
77
|
help_text="Payment currency"
|
78
78
|
)
|
79
|
-
|
79
|
+
|
80
80
|
network = models.ForeignKey(
|
81
81
|
Network,
|
82
82
|
on_delete=models.PROTECT,
|
@@ -85,7 +85,7 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
85
85
|
blank=True,
|
86
86
|
help_text="Blockchain network (for crypto payments)"
|
87
87
|
)
|
88
|
-
|
88
|
+
|
89
89
|
# Crypto amounts use Decimal for precision
|
90
90
|
pay_amount = models.DecimalField(
|
91
91
|
max_digits=20,
|
@@ -94,19 +94,19 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
94
94
|
blank=True,
|
95
95
|
help_text="Amount to pay in cryptocurrency (Decimal for precision)"
|
96
96
|
)
|
97
|
-
|
97
|
+
|
98
98
|
actual_amount_usd = models.FloatField(
|
99
99
|
null=True,
|
100
100
|
blank=True,
|
101
101
|
help_text="Actual amount received in USD"
|
102
102
|
)
|
103
|
-
|
103
|
+
|
104
104
|
fee_amount_usd = models.FloatField(
|
105
105
|
null=True,
|
106
106
|
blank=True,
|
107
107
|
help_text="Fee amount in USD"
|
108
108
|
)
|
109
|
-
|
109
|
+
|
110
110
|
# Provider information
|
111
111
|
provider = models.CharField(
|
112
112
|
max_length=50,
|
@@ -114,7 +114,7 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
114
114
|
default=PaymentProvider.NOWPAYMENTS,
|
115
115
|
help_text="Payment provider"
|
116
116
|
)
|
117
|
-
|
117
|
+
|
118
118
|
provider_payment_id = models.CharField(
|
119
119
|
max_length=255,
|
120
120
|
null=True,
|
@@ -122,7 +122,7 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
122
122
|
db_index=True,
|
123
123
|
help_text="Provider's payment ID"
|
124
124
|
)
|
125
|
-
|
125
|
+
|
126
126
|
# Payment details
|
127
127
|
status = models.CharField(
|
128
128
|
max_length=20,
|
@@ -131,20 +131,20 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
131
131
|
db_index=True,
|
132
132
|
help_text="Current payment status"
|
133
133
|
)
|
134
|
-
|
134
|
+
|
135
135
|
pay_address = models.CharField(
|
136
136
|
max_length=255,
|
137
137
|
null=True,
|
138
138
|
blank=True,
|
139
139
|
help_text="Cryptocurrency payment address"
|
140
140
|
)
|
141
|
-
|
141
|
+
|
142
142
|
payment_url = models.URLField(
|
143
143
|
null=True,
|
144
144
|
blank=True,
|
145
145
|
help_text="Payment page URL"
|
146
146
|
)
|
147
|
-
|
147
|
+
|
148
148
|
# Transaction information
|
149
149
|
transaction_hash = models.CharField(
|
150
150
|
max_length=256,
|
@@ -153,12 +153,12 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
153
153
|
db_index=True,
|
154
154
|
help_text="Blockchain transaction hash"
|
155
155
|
)
|
156
|
-
|
156
|
+
|
157
157
|
confirmations_count = models.PositiveIntegerField(
|
158
158
|
default=0,
|
159
159
|
help_text="Number of blockchain confirmations"
|
160
160
|
)
|
161
|
-
|
161
|
+
|
162
162
|
# Security and validation
|
163
163
|
security_nonce = models.CharField(
|
164
164
|
max_length=64,
|
@@ -167,62 +167,62 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
167
167
|
db_index=True,
|
168
168
|
help_text="Security nonce for validation"
|
169
169
|
)
|
170
|
-
|
170
|
+
|
171
171
|
# Timestamps
|
172
172
|
expires_at = models.DateTimeField(
|
173
173
|
null=True,
|
174
174
|
blank=True,
|
175
175
|
help_text="When this payment expires"
|
176
176
|
)
|
177
|
-
|
177
|
+
|
178
178
|
completed_at = models.DateTimeField(
|
179
179
|
null=True,
|
180
180
|
blank=True,
|
181
181
|
help_text="When this payment was completed"
|
182
182
|
)
|
183
|
-
|
183
|
+
|
184
184
|
status_changed_at = models.DateTimeField(
|
185
185
|
null=True,
|
186
186
|
blank=True,
|
187
187
|
db_index=True,
|
188
188
|
help_text="When the payment status was last changed"
|
189
189
|
)
|
190
|
-
|
190
|
+
|
191
191
|
# Metadata and description
|
192
192
|
description = models.TextField(
|
193
193
|
blank=True,
|
194
194
|
help_text="Payment description"
|
195
195
|
)
|
196
|
-
|
196
|
+
|
197
197
|
callback_url = models.URLField(
|
198
198
|
null=True,
|
199
199
|
blank=True,
|
200
200
|
help_text="Success callback URL"
|
201
201
|
)
|
202
|
-
|
202
|
+
|
203
203
|
cancel_url = models.URLField(
|
204
204
|
null=True,
|
205
205
|
blank=True,
|
206
206
|
help_text="Cancellation URL"
|
207
207
|
)
|
208
|
-
|
208
|
+
|
209
209
|
# Structured metadata (validated by Pydantic in services)
|
210
210
|
provider_data = models.JSONField(
|
211
211
|
default=dict,
|
212
212
|
blank=True,
|
213
213
|
help_text="Provider-specific data (validated by Pydantic)"
|
214
214
|
)
|
215
|
-
|
215
|
+
|
216
216
|
webhook_data = models.JSONField(
|
217
217
|
default=dict,
|
218
218
|
blank=True,
|
219
219
|
help_text="Webhook data (validated by Pydantic)"
|
220
220
|
)
|
221
|
-
|
221
|
+
|
222
222
|
# Manager
|
223
223
|
from .managers.payment_managers import PaymentManager
|
224
224
|
objects = PaymentManager()
|
225
|
-
|
225
|
+
|
226
226
|
class Meta:
|
227
227
|
db_table = 'payments_universal'
|
228
228
|
verbose_name = 'Universal Payment'
|
@@ -246,40 +246,40 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
246
246
|
name='payments_max_amount_check'
|
247
247
|
),
|
248
248
|
]
|
249
|
-
|
249
|
+
|
250
250
|
def __str__(self):
|
251
251
|
return f"Payment {self.internal_payment_id} - ${self.amount_usd:.2f} {self.currency.code}"
|
252
|
-
|
252
|
+
|
253
253
|
@property
|
254
254
|
def qr_data(self) -> str:
|
255
255
|
"""Generate QR code data for payment."""
|
256
256
|
if not self.pay_address:
|
257
257
|
return None
|
258
|
-
|
258
|
+
|
259
259
|
# For crypto payments, use proper URI format
|
260
260
|
if self.currency and self.currency.currency_type == 'crypto':
|
261
261
|
currency_code = self.currency.code.lower()
|
262
|
-
|
262
|
+
|
263
263
|
if currency_code == 'btc' and self.pay_amount:
|
264
264
|
return f"bitcoin:{self.pay_address}?amount={self.pay_amount}"
|
265
265
|
elif currency_code == 'eth' and self.pay_amount:
|
266
266
|
return f"ethereum:{self.pay_address}?value={self.pay_amount}"
|
267
267
|
elif currency_code == 'ltc' and self.pay_amount:
|
268
268
|
return f"litecoin:{self.pay_address}?amount={self.pay_amount}"
|
269
|
-
|
269
|
+
|
270
270
|
# Default: just return the address
|
271
271
|
return self.pay_address
|
272
|
-
|
272
|
+
|
273
273
|
@property
|
274
274
|
def formatted_pay_amount(self) -> str:
|
275
275
|
"""Format cryptocurrency amount with proper precision."""
|
276
276
|
if not self.pay_amount or not self.currency:
|
277
277
|
return "0"
|
278
|
-
|
278
|
+
|
279
279
|
try:
|
280
280
|
amount = float(self.pay_amount)
|
281
281
|
currency_code = self.currency.code.upper()
|
282
|
-
|
282
|
+
|
283
283
|
# Different precision for different currencies
|
284
284
|
if currency_code in ['BTC', 'LTC', 'DOGE']:
|
285
285
|
# Bitcoin-like currencies - 8 decimal places
|
@@ -290,28 +290,80 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
290
290
|
else:
|
291
291
|
# Other currencies - 4 decimal places
|
292
292
|
formatted = f"{amount:.4f}".rstrip('0').rstrip('.')
|
293
|
-
|
293
|
+
|
294
294
|
return formatted if formatted else "0"
|
295
|
-
|
295
|
+
|
296
296
|
except (ValueError, TypeError):
|
297
297
|
return "0"
|
298
|
-
|
298
|
+
|
299
299
|
def get_qr_code_url(self, size=200) -> str:
|
300
300
|
"""Generate QR code URL using external service."""
|
301
301
|
if not self.qr_data:
|
302
302
|
return None
|
303
|
-
|
303
|
+
|
304
304
|
from urllib.parse import quote
|
305
|
-
|
305
|
+
|
306
306
|
# Using QR Server API (free service)
|
307
307
|
qr_data_encoded = quote(self.qr_data)
|
308
308
|
return f"https://api.qrserver.com/v1/create-qr-code/?size={size}x{size}&data={qr_data_encoded}"
|
309
|
-
|
309
|
+
|
310
|
+
def _detect_network_from_address(self) -> str:
|
311
|
+
"""Detect network from address format if network is not set."""
|
312
|
+
if not self.pay_address:
|
313
|
+
return None
|
314
|
+
|
315
|
+
address = self.pay_address.strip()
|
316
|
+
|
317
|
+
# Ethereum-like addresses (0x...)
|
318
|
+
if address.startswith('0x') and len(address) == 42:
|
319
|
+
# Try to detect from currency code
|
320
|
+
if self.currency:
|
321
|
+
currency_code = self.currency.code.upper()
|
322
|
+
if 'ETH' in currency_code:
|
323
|
+
return 'ethereum'
|
324
|
+
elif 'BNB' in currency_code or 'BSC' in currency_code:
|
325
|
+
return 'bsc'
|
326
|
+
elif 'MATIC' in currency_code or 'POL' in currency_code:
|
327
|
+
return 'polygon'
|
328
|
+
elif 'ARB' in currency_code:
|
329
|
+
return 'arbitrum'
|
330
|
+
elif 'OP' in currency_code:
|
331
|
+
return 'optimism'
|
332
|
+
elif 'AVAX' in currency_code:
|
333
|
+
return 'avalanche c-chain'
|
334
|
+
# Default to ethereum for 0x addresses
|
335
|
+
return 'ethereum'
|
336
|
+
|
337
|
+
# Bitcoin addresses
|
338
|
+
elif address.startswith(('1', '3', 'bc1')):
|
339
|
+
return 'bitcoin'
|
340
|
+
|
341
|
+
# Tron addresses (T...)
|
342
|
+
elif address.startswith('T') and len(address) == 34:
|
343
|
+
return 'tron'
|
344
|
+
|
345
|
+
# Litecoin addresses
|
346
|
+
elif address.startswith(('L', 'M', 'ltc1')):
|
347
|
+
return 'litecoin'
|
348
|
+
|
349
|
+
return None
|
350
|
+
|
310
351
|
def get_payment_explorer_link(self) -> str:
|
311
352
|
"""Generate blockchain explorer link for transaction."""
|
312
|
-
if not self.transaction_hash
|
353
|
+
if not self.transaction_hash:
|
354
|
+
return ""
|
355
|
+
|
356
|
+
# Try to get network name
|
357
|
+
network_name = None
|
358
|
+
if self.network:
|
359
|
+
network_name = self.network.name.lower() if hasattr(self.network, 'name') else str(self.network).lower()
|
360
|
+
else:
|
361
|
+
# Try to detect from address
|
362
|
+
network_name = self._detect_network_from_address()
|
363
|
+
|
364
|
+
if not network_name:
|
313
365
|
return ""
|
314
|
-
|
366
|
+
|
315
367
|
# Explorer URL templates for different networks
|
316
368
|
explorer_templates = {
|
317
369
|
'bitcoin': 'https://blockstream.info/tx/{txid}',
|
@@ -327,52 +379,94 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
327
379
|
'avalanche c-chain': 'https://snowtrace.io/tx/{txid}',
|
328
380
|
'base': 'https://basescan.org/tx/{txid}',
|
329
381
|
}
|
330
|
-
|
331
|
-
network_name = self.network.name.lower() if hasattr(self.network, 'name') else str(self.network).lower()
|
382
|
+
|
332
383
|
template = explorer_templates.get(network_name)
|
333
384
|
if template:
|
334
385
|
return template.format(txid=self.transaction_hash)
|
335
|
-
|
386
|
+
|
336
387
|
return ""
|
337
|
-
|
388
|
+
|
389
|
+
def get_address_explorer_link(self) -> str:
|
390
|
+
"""Generate blockchain explorer link for payment address."""
|
391
|
+
if not self.pay_address:
|
392
|
+
return ""
|
393
|
+
|
394
|
+
# Try to get network name
|
395
|
+
network_name = None
|
396
|
+
if self.network:
|
397
|
+
network_name = self.network.name.lower() if hasattr(self.network, 'name') else str(self.network).lower()
|
398
|
+
else:
|
399
|
+
# Try to detect from address
|
400
|
+
network_name = self._detect_network_from_address()
|
401
|
+
|
402
|
+
if not network_name:
|
403
|
+
return ""
|
404
|
+
|
405
|
+
# Explorer URL templates for address viewing
|
406
|
+
address_explorer_templates = {
|
407
|
+
'bitcoin': 'https://blockstream.info/address/{address}',
|
408
|
+
'ethereum': 'https://etherscan.io/address/{address}',
|
409
|
+
'tron': 'https://tronscan.org/#/address/{address}',
|
410
|
+
'polygon': 'https://polygonscan.com/address/{address}',
|
411
|
+
'bsc': 'https://bscscan.com/address/{address}',
|
412
|
+
'binance smart chain': 'https://bscscan.com/address/{address}',
|
413
|
+
'litecoin': 'https://blockchair.com/litecoin/address/{address}',
|
414
|
+
'dogecoin': 'https://blockchair.com/dogecoin/address/{address}',
|
415
|
+
'arbitrum': 'https://arbiscan.io/address/{address}',
|
416
|
+
'optimism': 'https://optimistic.etherscan.io/address/{address}',
|
417
|
+
'avalanche c-chain': 'https://snowtrace.io/address/{address}',
|
418
|
+
'base': 'https://basescan.org/address/{address}',
|
419
|
+
}
|
420
|
+
|
421
|
+
template = address_explorer_templates.get(network_name)
|
422
|
+
if template:
|
423
|
+
return template.format(address=self.pay_address)
|
424
|
+
|
425
|
+
return ""
|
426
|
+
|
427
|
+
def get_payment_status_url(self) -> str:
|
428
|
+
"""Generate URL for payment status page in admin interface."""
|
429
|
+
from django.urls import reverse
|
430
|
+
return reverse('cfg_payments_admin:payment-detail', kwargs={'pk': self.pk})
|
431
|
+
|
338
432
|
def save(self, *args, **kwargs):
|
339
433
|
"""Override save to generate internal payment ID."""
|
340
434
|
if not self.internal_payment_id:
|
341
435
|
# Generate internal payment ID
|
342
436
|
timestamp = timezone.now().strftime('%Y%m%d%H%M%S')
|
343
437
|
self.internal_payment_id = f"PAY_{timestamp}_{str(self.id)[:8]}"
|
344
|
-
|
438
|
+
|
345
439
|
super().save(*args, **kwargs)
|
346
|
-
|
440
|
+
|
347
441
|
def clean(self):
|
348
442
|
"""Model validation."""
|
349
443
|
# Crypto payments must have network
|
350
444
|
if self.currency and self.currency.is_crypto and not self.network:
|
351
445
|
raise ValidationError("Cryptocurrency payments must specify a network")
|
352
|
-
|
446
|
+
|
353
447
|
# Fiat payments should not have network
|
354
448
|
if self.currency and self.currency.is_fiat and self.network:
|
355
449
|
raise ValidationError("Fiat payments should not specify a network")
|
356
|
-
|
450
|
+
|
357
451
|
# Validate amount limits
|
358
452
|
if self.amount_usd and (self.amount_usd < 1.0 or self.amount_usd > 50000.0):
|
359
453
|
raise ValidationError("Payment amount must be between $1.00 and $50,000.00")
|
360
|
-
|
454
|
+
|
361
455
|
# Validate expiration
|
362
456
|
if self.expires_at and self.expires_at <= timezone.now():
|
363
457
|
raise ValidationError("Expiration time must be in the future")
|
364
|
-
|
458
|
+
|
365
459
|
# Status properties
|
366
460
|
@property
|
367
461
|
def is_pending(self) -> bool:
|
368
462
|
"""Check if payment is pending."""
|
369
463
|
return self.status == self.PaymentStatus.PENDING
|
370
|
-
|
464
|
+
|
371
465
|
@property
|
372
466
|
def is_completed(self) -> bool:
|
373
467
|
"""Check if payment is completed."""
|
374
468
|
return self.status == self.PaymentStatus.COMPLETED
|
375
|
-
|
469
|
+
|
376
470
|
@property
|
377
471
|
def is_failed(self) -> bool:
|
378
472
|
"""Check if payment failed."""
|
@@ -381,14 +475,14 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
381
475
|
self.PaymentStatus.EXPIRED,
|
382
476
|
self.PaymentStatus.CANCELLED
|
383
477
|
]
|
384
|
-
|
478
|
+
|
385
479
|
@property
|
386
480
|
def is_expired(self) -> bool:
|
387
481
|
"""Check if payment is expired."""
|
388
482
|
if not self.expires_at:
|
389
483
|
return False
|
390
484
|
return timezone.now() > self.expires_at
|
391
|
-
|
485
|
+
|
392
486
|
@property
|
393
487
|
def requires_confirmation(self) -> bool:
|
394
488
|
"""Check if payment requires blockchain confirmation."""
|
@@ -396,7 +490,7 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
396
490
|
self.PaymentStatus.CONFIRMING,
|
397
491
|
self.PaymentStatus.CONFIRMED
|
398
492
|
]
|
399
|
-
|
493
|
+
|
400
494
|
# Display properties
|
401
495
|
@property
|
402
496
|
def status_color(self) -> str:
|
@@ -412,19 +506,19 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
412
506
|
self.PaymentStatus.REFUNDED: 'warning',
|
413
507
|
}
|
414
508
|
return colors.get(self.status, 'secondary')
|
415
|
-
|
509
|
+
|
416
510
|
@property
|
417
511
|
def amount_display(self) -> str:
|
418
512
|
"""Formatted amount display."""
|
419
513
|
return f"${self.amount_usd:.2f} USD"
|
420
|
-
|
514
|
+
|
421
515
|
@property
|
422
516
|
def crypto_amount_display(self) -> str:
|
423
517
|
"""Formatted crypto amount display."""
|
424
518
|
if not self.pay_amount:
|
425
519
|
return "N/A"
|
426
520
|
return f"{self.pay_amount:.8f} {self.currency.code}"
|
427
|
-
|
521
|
+
|
428
522
|
# Business logic methods
|
429
523
|
def can_be_cancelled(self) -> bool:
|
430
524
|
"""Check if payment can be cancelled."""
|
@@ -432,25 +526,25 @@ class UniversalPayment(UUIDTimestampedModel):
|
|
432
526
|
self.PaymentStatus.PENDING,
|
433
527
|
self.PaymentStatus.CONFIRMING
|
434
528
|
]
|
435
|
-
|
529
|
+
|
436
530
|
def can_be_refunded(self) -> bool:
|
437
531
|
"""Check if payment can be refunded."""
|
438
532
|
return self.status == self.PaymentStatus.COMPLETED
|
439
|
-
|
533
|
+
|
440
534
|
def mark_completed(self, actual_amount_usd: float = None, transaction_hash: str = None):
|
441
535
|
"""Mark payment as completed (delegates to manager)."""
|
442
536
|
return self.__class__.objects.mark_payment_completed(
|
443
537
|
self, actual_amount_usd, transaction_hash
|
444
538
|
)
|
445
|
-
|
539
|
+
|
446
540
|
def mark_failed(self, reason: str = None, error_code: str = None):
|
447
541
|
"""Mark payment as failed (delegates to manager)."""
|
448
542
|
return self.__class__.objects.mark_payment_failed(
|
449
543
|
self, reason, error_code
|
450
544
|
)
|
451
|
-
|
545
|
+
|
452
546
|
def cancel(self, reason: str = None):
|
453
547
|
"""Cancel payment (delegates to manager)."""
|
454
548
|
return self.__class__.objects.cancel_payment(self, reason)
|
455
|
-
|
456
|
-
|
549
|
+
|
550
|
+
|