tasks.py 2.8 KB

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