123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- from django.conf import settings
- from django.db.models import Count, Q, F, Subquery, OuterRef, IntegerField
- from django.db.models.functions import Cast
- from django.db.models.fields.json import KeyTextTransform
- from celery import shared_task
- from organizations_ext.models import Organization
- from projects.models import Project
- from .models import SubscriptionQuotaWarning
- from .email import WarnQuotaEmail
- @shared_task
- def warn_organization_throttle():
- """ Warn user about approaching 80% of allotted events """
- if not settings.BILLING_ENABLED:
- return
- queryset = Organization.objects.filter(
- djstripe_customers__subscriptions__status="active",
- ).filter(
- Q(djstripe_customers__subscriptions__subscriptionquotawarning=None)
- | Q(
- djstripe_customers__subscriptions__subscriptionquotawarning__notice_last_sent__lt=F(
- "djstripe_customers__subscriptions__current_period_start"
- ),
- )
- )
- projects = Project.objects.filter(organization=OuterRef("pk")).values(
- "organization"
- )
- total_issue_events = projects.annotate(
- total=Count(
- "issue__event",
- filter=Q(
- issue__event__created__gte=OuterRef(
- "djstripe_customers__subscriptions__current_period_start"
- )
- ),
- )
- ).values("total")
- total_transaction_events = projects.annotate(
- total=Count(
- "transactionevent",
- filter=Q(
- transactionevent__created__gte=OuterRef(
- "djstripe_customers__subscriptions__current_period_start"
- )
- ),
- )
- ).values("total")
- queryset = queryset.annotate(
- event_count=Subquery(total_issue_events) + Subquery(total_transaction_events),
- plan_event_count=Cast(
- KeyTextTransform(
- "events", "djstripe_customers__subscriptions__plan__product__metadata"
- ),
- output_field=IntegerField(),
- ),
- )
- # 80% to 100% of event quota
- queryset = queryset.filter(
- event_count__gte=F("plan_event_count") * 0.80,
- event_count__lte=F("plan_event_count"),
- )
- for org in queryset:
- subscription = org.djstripe_customers.first().subscription
- send_email_warn_quota.delay(subscription.pk, org.event_count)
- warning, created = SubscriptionQuotaWarning.objects.get_or_create(
- subscription=subscription
- )
- if not created:
- warning.save()
- @shared_task
- def send_email_warn_quota(subscription_id: int, event_count: int):
- WarnQuotaEmail(pk=subscription_id, event_count=event_count).send_email()
|