tasks.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. from celery import shared_task
  2. from django.conf import settings
  3. from django.db.models import F, IntegerField, Q
  4. from django.db.models.fields.json import KeyTextTransform
  5. from django.db.models.functions import Cast
  6. from apps.organizations_ext.models import Organization
  7. from .email import WarnQuotaEmail
  8. from .models import SubscriptionQuotaWarning
  9. @shared_task
  10. def warn_organization_throttle():
  11. """Warn user about approaching 80% of allotted events"""
  12. if not settings.BILLING_ENABLED:
  13. return
  14. queryset = (
  15. Organization.objects.with_event_counts()
  16. .filter(
  17. djstripe_customers__subscriptions__status="active",
  18. )
  19. .filter(
  20. Q(djstripe_customers__subscriptions__subscriptionquotawarning=None)
  21. | Q(
  22. djstripe_customers__subscriptions__subscriptionquotawarning__notice_last_sent__lt=F(
  23. "djstripe_customers__subscriptions__current_period_start"
  24. ),
  25. )
  26. )
  27. )
  28. queryset = queryset.annotate(
  29. plan_event_count=Cast(
  30. KeyTextTransform(
  31. "events", "djstripe_customers__subscriptions__plan__product__metadata"
  32. ),
  33. output_field=IntegerField(),
  34. ),
  35. )
  36. # 80% to 100% of event quota
  37. queryset = queryset.filter(
  38. total_event_count__gte=F("plan_event_count") * 0.80,
  39. total_event_count__lte=F("plan_event_count"),
  40. )
  41. for org in queryset:
  42. subscription = org.djstripe_customers.first().subscription
  43. send_email_warn_quota.delay(subscription.pk, org.total_event_count)
  44. warning, created = SubscriptionQuotaWarning.objects.get_or_create(
  45. subscription=subscription
  46. )
  47. if not created:
  48. warning.save()
  49. @shared_task
  50. def send_email_warn_quota(subscription_id: int, event_count: int):
  51. WarnQuotaEmail(pk=subscription_id, event_count=event_count).send_email()