billing and paymetn methods
This commit is contained in:
@@ -40,8 +40,6 @@ class Igny8AdminSite(admin.AdminSite):
|
||||
('billing', 'Invoice'),
|
||||
('billing', 'Payment'),
|
||||
('billing', 'CreditPackage'),
|
||||
('billing', 'PaymentMethodConfig'),
|
||||
('billing', 'AccountPaymentMethod'),
|
||||
('billing', 'CreditCostConfig'),
|
||||
],
|
||||
},
|
||||
@@ -107,6 +105,12 @@ class Igny8AdminSite(admin.AdminSite):
|
||||
('automation', 'AutomationRun'),
|
||||
],
|
||||
},
|
||||
'Payments': {
|
||||
'models': [
|
||||
('billing', 'PaymentMethodConfig'),
|
||||
('billing', 'AccountPaymentMethod'),
|
||||
],
|
||||
},
|
||||
'Integrations & Sync': {
|
||||
'models': [
|
||||
('integration', 'SiteIntegration'),
|
||||
@@ -170,6 +174,7 @@ class Igny8AdminSite(admin.AdminSite):
|
||||
'Writer Module',
|
||||
'Thinker Module',
|
||||
'System Configuration',
|
||||
'Payments',
|
||||
'Integrations & Sync',
|
||||
'Publishing',
|
||||
'Optimization',
|
||||
|
||||
@@ -545,6 +545,179 @@ class AdminBillingViewSet(viewsets.ViewSet):
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
@action(detail=False, methods=['get', 'post'])
|
||||
def payment_method_configs(self, request):
|
||||
"""List/create payment method configs (country-level)"""
|
||||
error = self._require_admin(request)
|
||||
if error:
|
||||
return error
|
||||
|
||||
class PMConfigSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = PaymentMethodConfig
|
||||
fields = [
|
||||
'id',
|
||||
'country_code',
|
||||
'payment_method',
|
||||
'display_name',
|
||||
'is_enabled',
|
||||
'instructions',
|
||||
'sort_order',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
]
|
||||
read_only_fields = ['id', 'created_at', 'updated_at']
|
||||
|
||||
if request.method.lower() == 'post':
|
||||
serializer = PMConfigSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
obj = serializer.save()
|
||||
return Response(PMConfigSerializer(obj).data, status=status.HTTP_201_CREATED)
|
||||
|
||||
qs = PaymentMethodConfig.objects.all().order_by('country_code', 'sort_order', 'payment_method')
|
||||
country = request.query_params.get('country_code')
|
||||
method = request.query_params.get('payment_method')
|
||||
if country:
|
||||
qs = qs.filter(country_code=country)
|
||||
if method:
|
||||
qs = qs.filter(payment_method=method)
|
||||
data = PMConfigSerializer(qs, many=True).data
|
||||
return Response({'results': data, 'count': len(data)})
|
||||
|
||||
@action(detail=True, methods=['get', 'patch', 'put', 'delete'], url_path='payment_method_config')
|
||||
@extend_schema(tags=['Admin Billing'])
|
||||
def payment_method_config(self, request, pk=None):
|
||||
"""Retrieve/update/delete a payment method config"""
|
||||
error = self._require_admin(request)
|
||||
if error:
|
||||
return error
|
||||
|
||||
obj = get_object_or_404(PaymentMethodConfig, id=pk)
|
||||
|
||||
class PMConfigSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = PaymentMethodConfig
|
||||
fields = [
|
||||
'id',
|
||||
'country_code',
|
||||
'payment_method',
|
||||
'display_name',
|
||||
'is_enabled',
|
||||
'instructions',
|
||||
'sort_order',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
]
|
||||
read_only_fields = ['id', 'created_at', 'updated_at']
|
||||
|
||||
if request.method.lower() == 'get':
|
||||
return Response(PMConfigSerializer(obj).data)
|
||||
if request.method.lower() in ['patch', 'put']:
|
||||
partial = request.method.lower() == 'patch'
|
||||
serializer = PMConfigSerializer(obj, data=request.data, partial=partial)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
obj = serializer.save()
|
||||
return Response(PMConfigSerializer(obj).data)
|
||||
# delete
|
||||
obj.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@action(detail=False, methods=['get', 'post'])
|
||||
@extend_schema(tags=['Admin Billing'])
|
||||
def account_payment_methods(self, request):
|
||||
"""List/create account payment methods (admin)"""
|
||||
error = self._require_admin(request)
|
||||
if error:
|
||||
return error
|
||||
|
||||
class AccountPMSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = AccountPaymentMethod
|
||||
fields = [
|
||||
'id',
|
||||
'account',
|
||||
'type',
|
||||
'display_name',
|
||||
'is_default',
|
||||
'is_enabled',
|
||||
'is_verified',
|
||||
'country_code',
|
||||
'instructions',
|
||||
'metadata',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
]
|
||||
read_only_fields = ['id', 'is_verified', 'created_at', 'updated_at']
|
||||
|
||||
if request.method.lower() == 'post':
|
||||
serializer = AccountPMSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
obj = serializer.save()
|
||||
return Response(AccountPMSerializer(obj).data, status=status.HTTP_201_CREATED)
|
||||
|
||||
qs = AccountPaymentMethod.objects.select_related('account').order_by('account_id', '-is_default', 'display_name')
|
||||
account_id = request.query_params.get('account_id')
|
||||
if account_id:
|
||||
qs = qs.filter(account_id=account_id)
|
||||
data = AccountPMSerializer(qs, many=True).data
|
||||
return Response({'results': data, 'count': len(data)})
|
||||
|
||||
@action(detail=True, methods=['get', 'patch', 'put', 'delete'], url_path='account_payment_method')
|
||||
@extend_schema(tags=['Admin Billing'])
|
||||
def account_payment_method(self, request, pk=None):
|
||||
"""Retrieve/update/delete an account payment method (admin)"""
|
||||
error = self._require_admin(request)
|
||||
if error:
|
||||
return error
|
||||
|
||||
obj = get_object_or_404(AccountPaymentMethod, id=pk)
|
||||
|
||||
class AccountPMSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = AccountPaymentMethod
|
||||
fields = [
|
||||
'id',
|
||||
'account',
|
||||
'type',
|
||||
'display_name',
|
||||
'is_default',
|
||||
'is_enabled',
|
||||
'is_verified',
|
||||
'country_code',
|
||||
'instructions',
|
||||
'metadata',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
]
|
||||
read_only_fields = ['id', 'is_verified', 'created_at', 'updated_at']
|
||||
|
||||
if request.method.lower() == 'get':
|
||||
return Response(AccountPMSerializer(obj).data)
|
||||
if request.method.lower() in ['patch', 'put']:
|
||||
partial = request.method.lower() == 'patch'
|
||||
serializer = AccountPMSerializer(obj, data=request.data, partial=partial)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
obj = serializer.save()
|
||||
if serializer.validated_data.get('is_default'):
|
||||
AccountPaymentMethod.objects.filter(account=obj.account).exclude(id=obj.id).update(is_default=False)
|
||||
return Response(AccountPMSerializer(obj).data)
|
||||
obj.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@action(detail=True, methods=['post'], url_path='account_payment_method/set_default')
|
||||
@extend_schema(tags=['Admin Billing'])
|
||||
def set_default_account_payment_method(self, request, pk=None):
|
||||
"""Set default account payment method (admin)"""
|
||||
error = self._require_admin(request)
|
||||
if error:
|
||||
return error
|
||||
|
||||
obj = get_object_or_404(AccountPaymentMethod, id=pk)
|
||||
AccountPaymentMethod.objects.filter(account=obj.account).update(is_default=False)
|
||||
obj.is_default = True
|
||||
obj.save(update_fields=['is_default'])
|
||||
return Response({'message': 'Default payment method updated', 'id': obj.id})
|
||||
|
||||
@action(detail=False, methods=['get'])
|
||||
def stats(self, request):
|
||||
"""System billing stats"""
|
||||
|
||||
@@ -94,9 +94,10 @@ class CreditPackageAdmin(admin.ModelAdmin):
|
||||
|
||||
@admin.register(PaymentMethodConfig)
|
||||
class PaymentMethodConfigAdmin(admin.ModelAdmin):
|
||||
list_display = ['country_code', 'payment_method', 'is_enabled', 'display_name', 'sort_order']
|
||||
list_display = ['country_code', 'payment_method', 'display_name', 'is_enabled', 'sort_order', 'updated_at']
|
||||
list_filter = ['payment_method', 'is_enabled', 'country_code']
|
||||
search_fields = ['country_code', 'display_name', 'payment_method']
|
||||
list_editable = ['is_enabled', 'sort_order']
|
||||
readonly_fields = ['created_at', 'updated_at']
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,21 @@ urlpatterns = [
|
||||
path('billing/pending_payments/', BillingAdminViewSet.as_view({'get': 'pending_payments'}), name='admin-billing-pending-payments'),
|
||||
path('billing/<int:pk>/approve_payment/', BillingAdminViewSet.as_view({'post': 'approve_payment'}), name='admin-billing-approve-payment'),
|
||||
path('billing/<int:pk>/reject_payment/', BillingAdminViewSet.as_view({'post': 'reject_payment'}), name='admin-billing-reject-payment'),
|
||||
path('billing/payment-method-configs/', BillingAdminViewSet.as_view({'get': 'payment_method_configs', 'post': 'payment_method_configs'}), name='admin-billing-payment-method-configs'),
|
||||
path('billing/payment-method-configs/<int:pk>/', BillingAdminViewSet.as_view({
|
||||
'get': 'payment_method_config',
|
||||
'patch': 'payment_method_config',
|
||||
'put': 'payment_method_config',
|
||||
'delete': 'payment_method_config',
|
||||
}), name='admin-billing-payment-method-config'),
|
||||
path('billing/account-payment-methods/', BillingAdminViewSet.as_view({'get': 'account_payment_methods', 'post': 'account_payment_methods'}), name='admin-billing-account-payment-methods'),
|
||||
path('billing/account-payment-methods/<int:pk>/', BillingAdminViewSet.as_view({
|
||||
'get': 'account_payment_method',
|
||||
'patch': 'account_payment_method',
|
||||
'put': 'account_payment_method',
|
||||
'delete': 'account_payment_method',
|
||||
}), name='admin-billing-account-payment-method'),
|
||||
path('billing/account-payment-methods/<int:pk>/set_default/', BillingAdminViewSet.as_view({'post': 'set_default_account_payment_method'}), name='admin-billing-account-payment-method-set-default'),
|
||||
]
|
||||
|
||||
urlpatterns += router.urls
|
||||
|
||||
Reference in New Issue
Block a user