tasks.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. from django.conf import settings
  2. from django.db.models import Count, Q, Subquery, OuterRef
  3. from celery import shared_task
  4. from projects.models import Project
  5. from .models import Organization
  6. from .email import send_email_met_quota
  7. def get_free_tier_organizations_with_event_count():
  8. queryset = Organization.objects.filter(
  9. djstripe_customers__subscriptions__plan__amount=0,
  10. djstripe_customers__subscriptions__status="active",
  11. )
  12. projects = Project.objects.filter(organization=OuterRef("pk")).values(
  13. "organization"
  14. )
  15. total_issue_events = projects.annotate(
  16. total=Count(
  17. "issue__event",
  18. filter=Q(
  19. issue__event__created__gte=OuterRef(
  20. "djstripe_customers__subscriptions__current_period_start"
  21. )
  22. ),
  23. )
  24. ).values("total")
  25. total_transaction_events = projects.annotate(
  26. total=Count(
  27. "transactionevent",
  28. filter=Q(
  29. transactionevent__created__gte=OuterRef(
  30. "djstripe_customers__subscriptions__current_period_start"
  31. )
  32. ),
  33. )
  34. ).values("total")
  35. return queryset.annotate(
  36. event_count=Subquery(total_issue_events) + Subquery(total_transaction_events)
  37. )
  38. @shared_task
  39. def set_organization_throttle():
  40. """ Determine if organization should be throttled """
  41. # Currently throttling only happens if billing is enabled and user has free plan.
  42. if settings.BILLING_ENABLED:
  43. events_max = settings.BILLING_FREE_TIER_EVENTS
  44. free_tier_organizations = get_free_tier_organizations_with_event_count()
  45. orgs_over_quota = free_tier_organizations.filter(
  46. is_accepting_events=True, event_count__gt=events_max
  47. ).select_related("owner__organization_user")
  48. for org in orgs_over_quota:
  49. send_email_met_quota(org)
  50. orgs_over_quota.update(is_accepting_events=False)
  51. free_tier_organizations.filter(
  52. is_accepting_events=False, event_count__lte=events_max
  53. ).update(is_accepting_events=True)
  54. # paid accounts should always be active at this time
  55. Organization.objects.filter(
  56. is_accepting_events=False,
  57. djstripe_customers__subscriptions__plan__amount__gt=0,
  58. djstripe_customers__subscriptions__status="active",
  59. ).update(is_accepting_events=True)