bank trnasfer deteiasl udaptes and issues fixed
This commit is contained in:
@@ -642,34 +642,154 @@ class AdminBillingViewSet(viewsets.ViewSet):
|
||||
return Response({'results': data})
|
||||
|
||||
def approve_payment(self, request, pk):
|
||||
"""Approve a pending payment"""
|
||||
"""Approve a pending payment - activates account, subscription, and adds credits"""
|
||||
from django.db import transaction
|
||||
from igny8_core.business.billing.models import Payment
|
||||
from igny8_core.modules.billing.services import CreditService
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
payment = Payment.objects.get(pk=pk, status='pending_approval')
|
||||
payment.status = 'completed'
|
||||
payment.processed_at = timezone.now()
|
||||
payment.save()
|
||||
|
||||
# If payment has an invoice, mark it as paid
|
||||
if payment.invoice:
|
||||
payment.invoice.status = 'paid'
|
||||
payment.invoice.paid_at = timezone.now()
|
||||
payment.invoice.save()
|
||||
|
||||
return Response({'success': True, 'message': 'Payment approved'})
|
||||
with transaction.atomic():
|
||||
# Get payment with related objects
|
||||
payment = Payment.objects.select_related(
|
||||
'invoice',
|
||||
'invoice__subscription',
|
||||
'invoice__subscription__plan',
|
||||
'account',
|
||||
'account__subscription',
|
||||
'account__subscription__plan',
|
||||
'account__plan'
|
||||
).get(pk=pk, status='pending_approval')
|
||||
|
||||
admin_notes = request.data.get('notes', '')
|
||||
|
||||
# 1. Update Payment status
|
||||
payment.status = 'succeeded'
|
||||
payment.processed_at = timezone.now()
|
||||
payment.approved_by = request.user
|
||||
payment.approved_at = timezone.now()
|
||||
if admin_notes:
|
||||
payment.admin_notes = admin_notes
|
||||
payment.save()
|
||||
|
||||
invoice = payment.invoice
|
||||
account = payment.account
|
||||
|
||||
# 2. Mark invoice as paid
|
||||
if invoice:
|
||||
invoice.status = 'paid'
|
||||
invoice.paid_at = timezone.now()
|
||||
invoice.save()
|
||||
|
||||
# 3. Get and activate subscription
|
||||
subscription = None
|
||||
if invoice and hasattr(invoice, 'subscription') and invoice.subscription:
|
||||
subscription = invoice.subscription
|
||||
elif account and hasattr(account, 'subscription'):
|
||||
try:
|
||||
subscription = account.subscription
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if subscription:
|
||||
subscription.status = 'active'
|
||||
subscription.external_payment_id = payment.manual_reference
|
||||
subscription.save(update_fields=['status', 'external_payment_id'])
|
||||
|
||||
# 4. CRITICAL: Set account status to active
|
||||
account.status = 'active'
|
||||
account.save(update_fields=['status'])
|
||||
|
||||
# 5. Add credits if plan has included credits
|
||||
credits_added = 0
|
||||
try:
|
||||
plan = None
|
||||
if subscription and subscription.plan:
|
||||
plan = subscription.plan
|
||||
elif account and account.plan:
|
||||
plan = account.plan
|
||||
|
||||
if plan and plan.included_credits > 0:
|
||||
credits_added = plan.included_credits
|
||||
CreditService.add_credits(
|
||||
account=account,
|
||||
amount=credits_added,
|
||||
transaction_type='subscription',
|
||||
description=f'{plan.name} plan credits - Invoice {invoice.invoice_number if invoice else "N/A"}',
|
||||
metadata={
|
||||
'subscription_id': subscription.id if subscription else None,
|
||||
'invoice_id': invoice.id if invoice else None,
|
||||
'payment_id': payment.id,
|
||||
'plan_id': plan.id,
|
||||
'approved_by': request.user.email
|
||||
}
|
||||
)
|
||||
except Exception as credit_error:
|
||||
logger.error(f'Credit addition failed for payment {payment.id}: {credit_error}', exc_info=True)
|
||||
# Don't fail the approval if credits fail - account is still activated
|
||||
|
||||
logger.info(
|
||||
f'Payment approved: Payment {payment.id}, Account {account.id} set to active, '
|
||||
f'{credits_added} credits added'
|
||||
)
|
||||
|
||||
# 6. Send approval email
|
||||
try:
|
||||
from igny8_core.business.billing.services.email_service import BillingEmailService
|
||||
BillingEmailService.send_payment_approved_email(payment, account, subscription)
|
||||
except Exception as e:
|
||||
logger.error(f'Failed to send payment approved email: {str(e)}')
|
||||
|
||||
return Response({
|
||||
'success': True,
|
||||
'message': 'Payment approved. Account activated.',
|
||||
'payment': {
|
||||
'id': payment.id,
|
||||
'status': payment.status,
|
||||
'account_status': account.status,
|
||||
'credits_added': credits_added
|
||||
}
|
||||
})
|
||||
except Payment.DoesNotExist:
|
||||
return Response({'error': 'Payment not found or not pending'}, status=404)
|
||||
except Exception as e:
|
||||
logger.error(f'Error approving payment {pk}: {str(e)}', exc_info=True)
|
||||
return Response({'error': f'Failed to approve payment: {str(e)}'}, status=500)
|
||||
|
||||
def reject_payment(self, request, pk):
|
||||
"""Reject a pending payment"""
|
||||
from igny8_core.business.billing.models import Payment
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
payment = Payment.objects.get(pk=pk, status='pending_approval')
|
||||
payment = Payment.objects.select_related('account').get(pk=pk, status='pending_approval')
|
||||
rejection_reason = request.data.get('reason', 'Rejected by admin')
|
||||
|
||||
payment.status = 'failed'
|
||||
payment.failed_at = timezone.now()
|
||||
payment.failure_reason = request.data.get('reason', 'Rejected by admin')
|
||||
payment.failure_reason = rejection_reason
|
||||
payment.approved_by = request.user
|
||||
payment.approved_at = timezone.now()
|
||||
payment.admin_notes = rejection_reason
|
||||
payment.save()
|
||||
|
||||
# Update account status to allow retry (if not already active)
|
||||
account = payment.account
|
||||
if account and account.status != 'active':
|
||||
account.status = 'pending_payment'
|
||||
account.save(update_fields=['status'])
|
||||
|
||||
logger.info(f'Payment rejected: Payment {payment.id}, Reason: {rejection_reason}')
|
||||
|
||||
# Send rejection email
|
||||
try:
|
||||
from igny8_core.business.billing.services.email_service import BillingEmailService
|
||||
BillingEmailService.send_payment_rejected_email(payment, account, rejection_reason)
|
||||
except Exception as e:
|
||||
logger.error(f'Failed to send payment rejected email: {str(e)}')
|
||||
|
||||
return Response({'success': True, 'message': 'Payment rejected'})
|
||||
except Payment.DoesNotExist:
|
||||
return Response({'error': 'Payment not found or not pending'}, status=404)
|
||||
|
||||
Reference in New Issue
Block a user