django-cfg 1.4.20__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/migrations/0003_alter_documentarchive_archive_type.py +29 -0
- 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 +35 -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 +36 -35
- 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 +12 -13
- 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.20.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.20.dist-info/RECORD +0 -1110
- /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.20.dist-info → django_cfg-1.4.23.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/licenses/LICENSE +0 -0
@@ -4,12 +4,14 @@ Payment managers for the Universal Payment System v2.0.
|
|
4
4
|
Optimized querysets and managers for payment operations.
|
5
5
|
"""
|
6
6
|
|
7
|
-
from typing import Optional, Dict, Any
|
8
|
-
from decimal import Decimal
|
9
7
|
from datetime import datetime
|
8
|
+
from decimal import Decimal
|
9
|
+
from typing import Any, Dict, Optional
|
10
|
+
|
10
11
|
from django.db import models
|
11
12
|
from django.utils import timezone
|
12
|
-
from pydantic import BaseModel,
|
13
|
+
from pydantic import BaseModel, ConfigDict, Field
|
14
|
+
|
13
15
|
from django_cfg.modules.django_logging import get_logger
|
14
16
|
|
15
17
|
logger = get_logger("payment_managers")
|
@@ -26,18 +28,18 @@ class PaymentStatusUpdateFields(BaseModel):
|
|
26
28
|
extra="forbid",
|
27
29
|
str_strip_whitespace=True
|
28
30
|
)
|
29
|
-
|
31
|
+
|
30
32
|
# Transaction related fields
|
31
33
|
transaction_hash: Optional[str] = Field(None, min_length=1, max_length=200, description="Blockchain transaction hash")
|
32
34
|
confirmations_count: Optional[int] = Field(None, ge=0, description="Number of blockchain confirmations")
|
33
|
-
|
34
|
-
# Amount related fields
|
35
|
+
|
36
|
+
# Amount related fields
|
35
37
|
actual_amount_usd: Optional[Decimal] = Field(None, gt=0, description="Actual amount received in USD")
|
36
38
|
fee_amount_usd: Optional[Decimal] = Field(None, ge=0, description="Fee amount in USD")
|
37
|
-
|
39
|
+
|
38
40
|
# Provider data
|
39
41
|
provider_data: Optional[Dict[str, Any]] = Field(None, description="Provider-specific data")
|
40
|
-
|
42
|
+
|
41
43
|
# Completion timestamp (auto-set by manager for completed status)
|
42
44
|
completed_at: Optional[datetime] = Field(None, description="Completion timestamp")
|
43
45
|
|
@@ -48,7 +50,7 @@ class PaymentQuerySet(models.QuerySet):
|
|
48
50
|
|
49
51
|
Provides efficient queries with proper indexing and select_related optimization.
|
50
52
|
"""
|
51
|
-
|
53
|
+
|
52
54
|
def optimized(self):
|
53
55
|
"""
|
54
56
|
Prevent N+1 queries with select_related and prefetch_related.
|
@@ -56,26 +58,26 @@ class PaymentQuerySet(models.QuerySet):
|
|
56
58
|
Use this for admin interfaces and API responses.
|
57
59
|
"""
|
58
60
|
return self.select_related(
|
59
|
-
'user',
|
60
|
-
'currency',
|
61
|
+
'user',
|
62
|
+
'currency',
|
61
63
|
'network'
|
62
64
|
).prefetch_related(
|
63
65
|
'user__payment_balance',
|
64
66
|
'user__payment_transactions'
|
65
67
|
)
|
66
|
-
|
68
|
+
|
67
69
|
def by_status(self, status):
|
68
70
|
"""Filter by payment status with index optimization."""
|
69
71
|
return self.filter(status=status)
|
70
|
-
|
72
|
+
|
71
73
|
def by_provider(self, provider):
|
72
74
|
"""Filter by payment provider."""
|
73
75
|
return self.filter(provider=provider)
|
74
|
-
|
76
|
+
|
75
77
|
def by_user(self, user):
|
76
78
|
"""Filter by user with proper indexing."""
|
77
79
|
return self.filter(user=user)
|
78
|
-
|
80
|
+
|
79
81
|
def by_amount_range(self, min_amount=None, max_amount=None):
|
80
82
|
"""
|
81
83
|
Filter by USD amount range.
|
@@ -90,36 +92,36 @@ class PaymentQuerySet(models.QuerySet):
|
|
90
92
|
if max_amount is not None:
|
91
93
|
queryset = queryset.filter(amount_usd__lte=max_amount)
|
92
94
|
return queryset
|
93
|
-
|
95
|
+
|
94
96
|
def by_currency(self, currency_code):
|
95
97
|
"""Filter by currency code."""
|
96
98
|
return self.filter(currency__code=currency_code)
|
97
|
-
|
99
|
+
|
98
100
|
def by_network(self, network_code):
|
99
101
|
"""Filter by blockchain network."""
|
100
102
|
return self.filter(network__code=network_code)
|
101
|
-
|
103
|
+
|
102
104
|
# Status-based filters
|
103
105
|
def completed(self):
|
104
106
|
"""Get completed payments."""
|
105
107
|
return self.filter(status='completed')
|
106
|
-
|
108
|
+
|
107
109
|
def pending(self):
|
108
110
|
"""Get pending payments."""
|
109
111
|
return self.filter(status='pending')
|
110
|
-
|
112
|
+
|
111
113
|
def failed(self):
|
112
114
|
"""Get failed payments (failed, expired, cancelled)."""
|
113
115
|
return self.filter(status__in=['failed', 'expired', 'cancelled'])
|
114
|
-
|
116
|
+
|
115
117
|
def confirming(self):
|
116
118
|
"""Get payments awaiting confirmation."""
|
117
119
|
return self.filter(status__in=['confirming', 'confirmed'])
|
118
|
-
|
120
|
+
|
119
121
|
def active(self):
|
120
122
|
"""Get active payments (not failed or completed)."""
|
121
123
|
return self.filter(status__in=['pending', 'confirming', 'confirmed'])
|
122
|
-
|
124
|
+
|
123
125
|
# Time-based filters
|
124
126
|
def recent(self, hours=24):
|
125
127
|
"""
|
@@ -130,22 +132,22 @@ class PaymentQuerySet(models.QuerySet):
|
|
130
132
|
"""
|
131
133
|
since = timezone.now() - timezone.timedelta(hours=hours)
|
132
134
|
return self.filter(created_at__gte=since)
|
133
|
-
|
135
|
+
|
134
136
|
def today(self):
|
135
137
|
"""Get payments created today."""
|
136
138
|
today = timezone.now().date()
|
137
139
|
return self.filter(created_at__date=today)
|
138
|
-
|
140
|
+
|
139
141
|
def this_week(self):
|
140
142
|
"""Get payments from this week."""
|
141
143
|
week_start = timezone.now().date() - timezone.timedelta(days=timezone.now().weekday())
|
142
144
|
return self.filter(created_at__date__gte=week_start)
|
143
|
-
|
145
|
+
|
144
146
|
def this_month(self):
|
145
147
|
"""Get payments from this month."""
|
146
148
|
month_start = timezone.now().replace(day=1).date()
|
147
149
|
return self.filter(created_at__date__gte=month_start)
|
148
|
-
|
150
|
+
|
149
151
|
def expired(self):
|
150
152
|
"""Get expired payments."""
|
151
153
|
now = timezone.now()
|
@@ -153,7 +155,7 @@ class PaymentQuerySet(models.QuerySet):
|
|
153
155
|
expires_at__lte=now,
|
154
156
|
status__in=['pending', 'confirming']
|
155
157
|
)
|
156
|
-
|
158
|
+
|
157
159
|
def expiring_soon(self, hours=2):
|
158
160
|
"""
|
159
161
|
Get payments expiring in the next N hours.
|
@@ -167,59 +169,59 @@ class PaymentQuerySet(models.QuerySet):
|
|
167
169
|
expires_at__gt=timezone.now(),
|
168
170
|
status__in=['pending', 'confirming']
|
169
171
|
)
|
170
|
-
|
172
|
+
|
171
173
|
# Provider-specific filters
|
172
174
|
def nowpayments(self):
|
173
175
|
"""Get NowPayments payments."""
|
174
176
|
return self.filter(provider='nowpayments')
|
175
|
-
|
177
|
+
|
176
178
|
def crypto_payments(self):
|
177
179
|
"""Get cryptocurrency payments."""
|
178
180
|
return self.filter(currency__currency_type='crypto')
|
179
|
-
|
181
|
+
|
180
182
|
def fiat_payments(self):
|
181
183
|
"""Get fiat currency payments."""
|
182
184
|
return self.filter(currency__currency_type='fiat')
|
183
|
-
|
185
|
+
|
184
186
|
# Aggregation methods
|
185
187
|
def total_amount(self):
|
186
188
|
"""Get total USD amount for queryset."""
|
187
189
|
result = self.aggregate(total=models.Sum('amount_usd'))
|
188
190
|
return result['total'] or 0.0
|
189
|
-
|
191
|
+
|
190
192
|
def average_amount(self):
|
191
193
|
"""Get average USD amount for queryset."""
|
192
194
|
result = self.aggregate(avg=models.Avg('amount_usd'))
|
193
195
|
return result['avg'] or 0.0
|
194
|
-
|
196
|
+
|
195
197
|
def count_by_status(self):
|
196
198
|
"""Get count of payments grouped by status."""
|
197
199
|
return self.values('status').annotate(count=models.Count('id')).order_by('status')
|
198
|
-
|
200
|
+
|
199
201
|
def count_by_provider(self):
|
200
202
|
"""Get count of payments grouped by provider."""
|
201
203
|
return self.values('provider').annotate(count=models.Count('id')).order_by('provider')
|
202
|
-
|
204
|
+
|
203
205
|
def count_by_currency(self):
|
204
206
|
"""Get count of payments grouped by currency."""
|
205
207
|
return self.values('currency__code').annotate(count=models.Count('id')).order_by('currency__code')
|
206
|
-
|
208
|
+
|
207
209
|
# Advanced queries
|
208
210
|
def with_transactions(self):
|
209
211
|
"""Include related transaction data."""
|
210
212
|
return self.prefetch_related('user__payment_transactions')
|
211
|
-
|
213
|
+
|
212
214
|
def with_balance_info(self):
|
213
215
|
"""Include user balance information."""
|
214
216
|
return self.select_related('user__payment_balance')
|
215
|
-
|
217
|
+
|
216
218
|
def requiring_confirmation(self):
|
217
219
|
"""Get payments that need blockchain confirmation."""
|
218
220
|
return self.filter(
|
219
221
|
status__in=['confirming', 'confirmed'],
|
220
222
|
transaction_hash__isnull=False
|
221
223
|
)
|
222
|
-
|
224
|
+
|
223
225
|
def large_amounts(self, threshold=1000.0):
|
224
226
|
"""
|
225
227
|
Get payments above threshold amount.
|
@@ -228,7 +230,7 @@ class PaymentQuerySet(models.QuerySet):
|
|
228
230
|
threshold: USD amount threshold (default: $1000)
|
229
231
|
"""
|
230
232
|
return self.filter(amount_usd__gte=threshold)
|
231
|
-
|
233
|
+
|
232
234
|
def small_amounts(self, threshold=10.0):
|
233
235
|
"""
|
234
236
|
Get payments below threshold amount.
|
@@ -245,80 +247,80 @@ class PaymentManager(models.Manager):
|
|
245
247
|
|
246
248
|
Provides high-level methods for common payment operations.
|
247
249
|
"""
|
248
|
-
|
250
|
+
|
249
251
|
def get_queryset(self):
|
250
252
|
"""Return optimized queryset by default."""
|
251
253
|
return PaymentQuerySet(self.model, using=self._db)
|
252
|
-
|
254
|
+
|
253
255
|
def optimized(self):
|
254
256
|
"""Get optimized queryset for admin/API use."""
|
255
257
|
return self.get_queryset().optimized()
|
256
|
-
|
258
|
+
|
257
259
|
# Status-based methods
|
258
260
|
def by_status(self, status):
|
259
261
|
"""Get payments by status."""
|
260
262
|
return self.get_queryset().by_status(status)
|
261
|
-
|
263
|
+
|
262
264
|
def completed(self):
|
263
265
|
"""Get completed payments."""
|
264
266
|
return self.get_queryset().completed()
|
265
|
-
|
267
|
+
|
266
268
|
def pending(self):
|
267
269
|
"""Get pending payments."""
|
268
270
|
return self.get_queryset().pending()
|
269
|
-
|
271
|
+
|
270
272
|
def failed(self):
|
271
273
|
"""Get failed payments."""
|
272
274
|
return self.get_queryset().failed()
|
273
|
-
|
275
|
+
|
274
276
|
def active(self):
|
275
277
|
"""Get active payments."""
|
276
278
|
return self.get_queryset().active()
|
277
|
-
|
279
|
+
|
278
280
|
# User-based methods
|
279
281
|
def by_user(self, user):
|
280
282
|
"""Get payments by user."""
|
281
283
|
return self.get_queryset().by_user(user)
|
282
|
-
|
284
|
+
|
283
285
|
# Provider-based methods
|
284
286
|
def by_provider(self, provider):
|
285
287
|
"""Get payments by provider."""
|
286
288
|
return self.get_queryset().by_provider(provider)
|
287
|
-
|
289
|
+
|
288
290
|
def nowpayments(self):
|
289
291
|
"""Get NowPayments payments."""
|
290
292
|
return self.get_queryset().nowpayments()
|
291
|
-
|
293
|
+
|
292
294
|
# Time-based methods
|
293
295
|
def recent(self, hours=24):
|
294
296
|
"""Get recent payments."""
|
295
297
|
return self.get_queryset().recent(hours)
|
296
|
-
|
298
|
+
|
297
299
|
def today(self):
|
298
300
|
"""Get today's payments."""
|
299
301
|
return self.get_queryset().today()
|
300
|
-
|
302
|
+
|
301
303
|
def this_week(self):
|
302
304
|
"""Get this week's payments."""
|
303
305
|
return self.get_queryset().this_week()
|
304
|
-
|
306
|
+
|
305
307
|
def this_month(self):
|
306
308
|
"""Get this month's payments."""
|
307
309
|
return self.get_queryset().this_month()
|
308
|
-
|
310
|
+
|
309
311
|
# Maintenance methods
|
310
312
|
def expired(self):
|
311
313
|
"""Get expired payments."""
|
312
314
|
return self.get_queryset().expired()
|
313
|
-
|
315
|
+
|
314
316
|
def expiring_soon(self, hours=2):
|
315
317
|
"""Get payments expiring soon."""
|
316
318
|
return self.get_queryset().expiring_soon(hours)
|
317
|
-
|
319
|
+
|
318
320
|
def requiring_confirmation(self):
|
319
321
|
"""Get payments needing confirmation."""
|
320
322
|
return self.get_queryset().requiring_confirmation()
|
321
|
-
|
323
|
+
|
322
324
|
# Statistics methods
|
323
325
|
def get_stats(self, days=30):
|
324
326
|
"""
|
@@ -332,7 +334,7 @@ class PaymentManager(models.Manager):
|
|
332
334
|
"""
|
333
335
|
since = timezone.now() - timezone.timedelta(days=days)
|
334
336
|
queryset = self.filter(created_at__gte=since)
|
335
|
-
|
337
|
+
|
336
338
|
stats = {
|
337
339
|
'total_payments': queryset.count(),
|
338
340
|
'total_amount_usd': queryset.total_amount(),
|
@@ -344,15 +346,15 @@ class PaymentManager(models.Manager):
|
|
344
346
|
'by_provider': list(queryset.count_by_provider()),
|
345
347
|
'by_currency': list(queryset.count_by_currency()),
|
346
348
|
}
|
347
|
-
|
349
|
+
|
348
350
|
logger.info(f"Generated payment stats for {days} days", extra={
|
349
351
|
'days': days,
|
350
352
|
'total_payments': stats['total_payments'],
|
351
353
|
'total_amount': stats['total_amount_usd']
|
352
354
|
})
|
353
|
-
|
355
|
+
|
354
356
|
return stats
|
355
|
-
|
357
|
+
|
356
358
|
def cleanup_expired(self, dry_run=True):
|
357
359
|
"""
|
358
360
|
Mark expired payments as failed.
|
@@ -365,13 +367,13 @@ class PaymentManager(models.Manager):
|
|
365
367
|
"""
|
366
368
|
expired_payments = self.expired()
|
367
369
|
count = expired_payments.count()
|
368
|
-
|
370
|
+
|
369
371
|
if not dry_run and count > 0:
|
370
372
|
expired_payments.update(status='expired')
|
371
373
|
logger.info(f"Marked {count} payments as expired")
|
372
|
-
|
374
|
+
|
373
375
|
return count
|
374
|
-
|
376
|
+
|
375
377
|
def get_user_payment_summary(self, user):
|
376
378
|
"""
|
377
379
|
Get payment summary for a specific user.
|
@@ -383,7 +385,7 @@ class PaymentManager(models.Manager):
|
|
383
385
|
dict: User payment summary
|
384
386
|
"""
|
385
387
|
user_payments = self.filter(user=user)
|
386
|
-
|
388
|
+
|
387
389
|
summary = {
|
388
390
|
'total_payments': user_payments.count(),
|
389
391
|
'total_amount_usd': user_payments.total_amount(),
|
@@ -393,9 +395,9 @@ class PaymentManager(models.Manager):
|
|
393
395
|
'last_payment_at': user_payments.first().created_at if user_payments.exists() else None,
|
394
396
|
'average_amount_usd': user_payments.average_amount(),
|
395
397
|
}
|
396
|
-
|
398
|
+
|
397
399
|
return summary
|
398
|
-
|
400
|
+
|
399
401
|
# Business logic methods
|
400
402
|
def mark_payment_completed(self, payment_id, actual_amount_usd=None, transaction_hash=None):
|
401
403
|
"""
|
@@ -414,41 +416,41 @@ class PaymentManager(models.Manager):
|
|
414
416
|
payment = self.get(id=payment_id)
|
415
417
|
else:
|
416
418
|
payment = payment_id
|
417
|
-
|
419
|
+
|
418
420
|
# Validate payment can be completed
|
419
|
-
if
|
421
|
+
if payment.status not in ['pending', 'confirming', 'confirmed']:
|
420
422
|
logger.warning(f"Cannot complete payment in status {payment.status}", extra={
|
421
423
|
'payment_id': str(payment.id),
|
422
424
|
'current_status': payment.status
|
423
425
|
})
|
424
426
|
return False
|
425
|
-
|
427
|
+
|
426
428
|
# Update payment using centralized status update method
|
427
429
|
extra_fields = PaymentStatusUpdateFields(
|
428
430
|
actual_amount_usd=actual_amount_usd,
|
429
431
|
transaction_hash=transaction_hash
|
430
432
|
)
|
431
|
-
|
433
|
+
|
432
434
|
success = self.update_payment_status(payment, 'completed', extra_fields)
|
433
435
|
if not success:
|
434
436
|
return False
|
435
|
-
|
436
|
-
logger.info(
|
437
|
+
|
438
|
+
logger.info("Payment marked as completed", extra={
|
437
439
|
'payment_id': str(payment.id),
|
438
440
|
'user_id': payment.user.id,
|
439
441
|
'amount_usd': payment.amount_usd,
|
440
442
|
'actual_amount_usd': actual_amount_usd,
|
441
443
|
'transaction_hash': transaction_hash
|
442
444
|
})
|
443
|
-
|
445
|
+
|
444
446
|
return True
|
445
|
-
|
447
|
+
|
446
448
|
except Exception as e:
|
447
449
|
logger.error(f"Failed to mark payment as completed: {e}", extra={
|
448
450
|
'payment_id': str(payment_id) if hasattr(payment_id, 'id') else payment_id
|
449
451
|
})
|
450
452
|
return False
|
451
|
-
|
453
|
+
|
452
454
|
def mark_payment_failed(self, payment_id, reason=None, error_code=None):
|
453
455
|
"""
|
454
456
|
Mark payment as failed (business logic in manager).
|
@@ -466,7 +468,7 @@ class PaymentManager(models.Manager):
|
|
466
468
|
payment = self.get(id=payment_id)
|
467
469
|
else:
|
468
470
|
payment = payment_id
|
469
|
-
|
471
|
+
|
470
472
|
# Prepare error info
|
471
473
|
provider_data = payment.provider_data.copy() if payment.provider_data else {}
|
472
474
|
if reason or error_code:
|
@@ -477,31 +479,31 @@ class PaymentManager(models.Manager):
|
|
477
479
|
if error_code:
|
478
480
|
provider_data['error_info']['code'] = error_code
|
479
481
|
provider_data['error_info']['failed_at'] = timezone.now().isoformat()
|
480
|
-
|
482
|
+
|
481
483
|
# Update payment using centralized status update method
|
482
484
|
extra_fields = PaymentStatusUpdateFields(
|
483
485
|
provider_data=provider_data if provider_data != payment.provider_data else None
|
484
486
|
)
|
485
|
-
|
487
|
+
|
486
488
|
success = self.update_payment_status(payment, 'failed', extra_fields)
|
487
489
|
if not success:
|
488
490
|
return False
|
489
|
-
|
490
|
-
logger.warning(
|
491
|
+
|
492
|
+
logger.warning("Payment marked as failed", extra={
|
491
493
|
'payment_id': str(payment.id),
|
492
494
|
'user_id': payment.user.id,
|
493
495
|
'reason': reason,
|
494
496
|
'error_code': error_code
|
495
497
|
})
|
496
|
-
|
498
|
+
|
497
499
|
return True
|
498
|
-
|
500
|
+
|
499
501
|
except Exception as e:
|
500
502
|
logger.error(f"Failed to mark payment as failed: {e}", extra={
|
501
503
|
'payment_id': str(payment_id) if hasattr(payment_id, 'id') else payment_id
|
502
504
|
})
|
503
505
|
return False
|
504
|
-
|
506
|
+
|
505
507
|
def cancel_payment(self, payment_id, reason=None):
|
506
508
|
"""
|
507
509
|
Cancel payment (business logic in manager).
|
@@ -518,15 +520,15 @@ class PaymentManager(models.Manager):
|
|
518
520
|
payment = self.get(id=payment_id)
|
519
521
|
else:
|
520
522
|
payment = payment_id
|
521
|
-
|
523
|
+
|
522
524
|
# Validate payment can be cancelled
|
523
|
-
if
|
525
|
+
if payment.status not in ['pending', 'confirming']:
|
524
526
|
logger.warning(f"Cannot cancel payment in status {payment.status}", extra={
|
525
527
|
'payment_id': str(payment.id),
|
526
528
|
'current_status': payment.status
|
527
529
|
})
|
528
530
|
return False
|
529
|
-
|
531
|
+
|
530
532
|
# Prepare cancellation info
|
531
533
|
provider_data = payment.provider_data.copy() if payment.provider_data else {}
|
532
534
|
if reason:
|
@@ -534,34 +536,34 @@ class PaymentManager(models.Manager):
|
|
534
536
|
provider_data['cancellation_info'] = {}
|
535
537
|
provider_data['cancellation_info']['reason'] = reason
|
536
538
|
provider_data['cancellation_info']['cancelled_at'] = timezone.now().isoformat()
|
537
|
-
|
539
|
+
|
538
540
|
# Update payment using centralized status update method
|
539
541
|
extra_fields = PaymentStatusUpdateFields(
|
540
542
|
provider_data=provider_data if provider_data != payment.provider_data else None
|
541
543
|
)
|
542
|
-
|
544
|
+
|
543
545
|
success = self.update_payment_status(payment, 'cancelled', extra_fields)
|
544
546
|
if not success:
|
545
547
|
return False
|
546
|
-
|
547
|
-
logger.info(
|
548
|
+
|
549
|
+
logger.info("Payment cancelled", extra={
|
548
550
|
'payment_id': str(payment.id),
|
549
551
|
'user_id': payment.user.id,
|
550
552
|
'reason': reason
|
551
553
|
})
|
552
|
-
|
554
|
+
|
553
555
|
return True
|
554
|
-
|
556
|
+
|
555
557
|
except Exception as e:
|
556
558
|
logger.error(f"Failed to cancel payment: {e}", extra={
|
557
559
|
'payment_id': str(payment_id) if hasattr(payment_id, 'id') else payment_id
|
558
560
|
})
|
559
561
|
return False
|
560
|
-
|
562
|
+
|
561
563
|
def update_payment_status(
|
562
|
-
self,
|
563
|
-
payment,
|
564
|
-
new_status: str,
|
564
|
+
self,
|
565
|
+
payment,
|
566
|
+
new_status: str,
|
565
567
|
extra_fields: Optional[PaymentStatusUpdateFields] = None
|
566
568
|
) -> bool:
|
567
569
|
"""
|
@@ -577,25 +579,25 @@ class PaymentManager(models.Manager):
|
|
577
579
|
"""
|
578
580
|
try:
|
579
581
|
old_status = payment.status
|
580
|
-
|
582
|
+
|
581
583
|
# Only update if status actually changed
|
582
584
|
if old_status != new_status:
|
583
585
|
payment.status = new_status
|
584
586
|
payment.status_changed_at = timezone.now()
|
585
|
-
|
587
|
+
|
586
588
|
# Set completed_at if status changed to completed
|
587
589
|
if new_status == 'completed' and not payment.completed_at:
|
588
590
|
payment.completed_at = timezone.now()
|
589
|
-
|
591
|
+
|
590
592
|
# Update fields list for save()
|
591
593
|
update_fields = ['status', 'status_changed_at', 'updated_at']
|
592
|
-
|
594
|
+
|
593
595
|
# Apply extra fields if provided
|
594
596
|
if extra_fields:
|
595
597
|
# Validate extra fields
|
596
598
|
if isinstance(extra_fields, dict):
|
597
599
|
extra_fields = PaymentStatusUpdateFields(**extra_fields)
|
598
|
-
|
600
|
+
|
599
601
|
# Apply non-None fields
|
600
602
|
for field_name, field_value in extra_fields.model_dump(exclude_none=True).items():
|
601
603
|
if hasattr(payment, field_name):
|
@@ -606,28 +608,28 @@ class PaymentManager(models.Manager):
|
|
606
608
|
'payment_id': str(payment.id),
|
607
609
|
'field_name': field_name
|
608
610
|
})
|
609
|
-
|
611
|
+
|
610
612
|
payment.save(update_fields=update_fields)
|
611
|
-
|
612
|
-
logger.info(
|
613
|
+
|
614
|
+
logger.info("Payment status updated", extra={
|
613
615
|
'payment_id': str(payment.id),
|
614
616
|
'old_status': old_status,
|
615
617
|
'new_status': new_status,
|
616
618
|
'updated_fields': update_fields
|
617
619
|
})
|
618
|
-
|
620
|
+
|
619
621
|
return True
|
620
622
|
else:
|
621
|
-
logger.debug(
|
623
|
+
logger.debug("Payment status unchanged", extra={
|
622
624
|
'payment_id': str(payment.id),
|
623
625
|
'status': new_status
|
624
626
|
})
|
625
627
|
return False
|
626
|
-
|
628
|
+
|
627
629
|
except Exception as e:
|
628
630
|
logger.error(f"Failed to update payment status: {e}", extra={
|
629
631
|
'payment_id': str(payment.id),
|
630
632
|
'old_status': old_status if 'old_status' in locals() else 'unknown',
|
631
633
|
'new_status': new_status
|
632
634
|
})
|
633
|
-
return False
|
635
|
+
return False
|