from django.utils import timezone from statuslog.signals import status_changed from .models import Subscription def activate_subscription(subscription_id: int): """ بعد از تایید پرداخت (payment webhook) صدا زده می‌شه؛ اشتراک رو active می‌کنه و expires_at رو بر اساس Plan.duration_days محاسبه می‌کنه. (قبلاً چون Plan فیلد duration‌ای نداشت، این مقدار با یک قاعده‌ی stub بر اساس متن title حدس زده می‌شد؛ الان duration_days مستقیماً از مدل Plan خونده می‌شه.) """ try: subscription = Subscription.objects.get(pk=subscription_id) except Subscription.DoesNotExist: return None old_status = subscription.status duration_days = subscription.plan.duration_days if subscription.plan else 30 subscription.status = 'active' subscription.expires_at = timezone.now() + timezone.timedelta(days=duration_days) subscription.save(update_fields=['status', 'expires_at']) status_changed.send( sender='subscription.Subscription', object_id=subscription.id, old_status=old_status, new_status='active', event='payment_confirmed', user_id=subscription.user_id, ) return subscription def grant_free_subscription(user_id: int, *, duration_days: int | None = None, event: str = 'offer_applied'): """ فعال‌سازی اشتراک بدون هیچ Order/پرداختی — برای Offer (آفر رایگان محدود/کامل). duration_days=None یعنی نامحدود (free_full)؛ عدد یعنی trial با همون تعداد روز. از discount/services.py (apply_offer) صدا زده می‌شه؛ مثل بقیه‌ی ارتباطات بین‌اپیِ این پروژه، یک import مستقیم به تابع سرویس، نه FK واقعی و نه HTTP call به خودمون. """ subscription, _ = Subscription.objects.get_or_create(user_id=user_id) old_status = subscription.status subscription.status = 'active' subscription.expires_at = ( timezone.now() + timezone.timedelta(days=duration_days) if duration_days else None ) subscription.save(update_fields=['status', 'expires_at']) status_changed.send( sender='subscription.Subscription', object_id=subscription.id, old_status=old_status, new_status='active', event=event, user_id=user_id, ) return subscription