admin.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. from django.conf import settings
  2. from django.contrib import admin
  3. from django.db.models import F, PositiveIntegerField
  4. from django.db.models.fields.json import KeyTextTransform
  5. from django.db.models.functions import Cast
  6. from django.utils.html import format_html
  7. from import_export.admin import ImportExportModelAdmin
  8. from organizations.base_admin import (
  9. BaseOrganizationAdmin,
  10. BaseOrganizationUserAdmin,
  11. BaseOwnerInline,
  12. )
  13. from .models import Organization, OrganizationOwner, OrganizationUser
  14. from .resources import OrganizationResource, OrganizationUserResource
  15. ORGANIZATION_LIST_FILTER = (
  16. "is_active",
  17. "is_accepting_events",
  18. )
  19. if settings.BILLING_ENABLED:
  20. ORGANIZATION_LIST_FILTER += ("djstripe_customers__subscriptions__plan__product",)
  21. class OwnerInline(BaseOwnerInline):
  22. model = OrganizationOwner
  23. class OrganizationUserInline(admin.StackedInline):
  24. raw_id_fields = ("user",)
  25. model = OrganizationUser
  26. extra = 0
  27. class GlitchTipBaseOrganizationAdmin(BaseOrganizationAdmin):
  28. readonly_fields = ("customers", "created")
  29. list_filter = ORGANIZATION_LIST_FILTER
  30. inlines = [OrganizationUserInline, OwnerInline]
  31. show_full_result_count = False
  32. def issue_events(self, obj):
  33. return obj.issue_event_count
  34. def customers(self, obj):
  35. return format_html(
  36. " ".join(
  37. [
  38. f'<a href="{customer.get_stripe_dashboard_url()}" target="_blank">{customer.id}</a>'
  39. for customer in obj.djstripe_customers.all()
  40. ]
  41. )
  42. )
  43. def transaction_events(self, obj):
  44. return obj.transaction_count
  45. def uptime_check_events(self, obj):
  46. return obj.uptime_check_event_count
  47. def file_size(self, obj):
  48. return obj.file_size
  49. def total_events(self, obj):
  50. return obj.total_event_count
  51. class OrganizationAdmin(GlitchTipBaseOrganizationAdmin, ImportExportModelAdmin):
  52. list_display = [
  53. "name",
  54. "is_active",
  55. "is_accepting_events",
  56. "issue_events",
  57. "transaction_events",
  58. "uptime_check_events",
  59. "file_size",
  60. "total_events",
  61. ]
  62. resource_class = OrganizationResource
  63. def get_queryset(self, request):
  64. qs = self.model.objects.with_event_counts()
  65. # From super
  66. ordering = self.ordering or ()
  67. if ordering:
  68. qs = qs.order_by(*ordering)
  69. return qs
  70. class OrganizationSubscription(Organization):
  71. class Meta:
  72. proxy = True
  73. class IsOverListFilter(admin.SimpleListFilter):
  74. title = "Is over plan limit"
  75. parameter_name = "is_over"
  76. def lookups(self, request, model_admin):
  77. return (
  78. (True, "Yes"),
  79. (False, "No"),
  80. )
  81. def queryset(self, request, queryset):
  82. if self.value() is not None:
  83. queryset = queryset.filter(max_events__isnull=False)
  84. if self.value() is False:
  85. return queryset.filter(total_event_count__lte=F("max_events"))
  86. if self.value() is True:
  87. return queryset.filter(total_event_count__gt=F("max_events"))
  88. return queryset
  89. class OrganizationSubscriptionAdmin(GlitchTipBaseOrganizationAdmin):
  90. list_display = [
  91. "name",
  92. "is_active",
  93. "is_accepting_events",
  94. "issue_events",
  95. "transaction_events",
  96. "uptime_check_events",
  97. "file_size",
  98. "total_events",
  99. "max_events",
  100. "current_period_end",
  101. ]
  102. def max_events(self, obj):
  103. return obj.max_events
  104. def current_period_end(self, obj):
  105. return obj.current_period_end
  106. def get_queryset(self, request):
  107. qs = Organization.objects.with_event_counts().annotate(
  108. max_events=Cast(
  109. KeyTextTransform(
  110. "events",
  111. "djstripe_customers__subscriptions__plan__product__metadata",
  112. ),
  113. output_field=PositiveIntegerField(),
  114. ),
  115. current_period_end=F(
  116. "djstripe_customers__subscriptions__current_period_end"
  117. ),
  118. )
  119. # From super
  120. ordering = self.ordering or ()
  121. if ordering:
  122. qs = qs.order_by(*ordering)
  123. return qs
  124. list_filter = GlitchTipBaseOrganizationAdmin.list_filter + (IsOverListFilter,)
  125. class OrganizationUserAdmin(BaseOrganizationUserAdmin, ImportExportModelAdmin):
  126. list_display = ["user", "organization", "role", "email"]
  127. search_fields = ("email", "user__email", "organization__name")
  128. list_filter = ("role",)
  129. resource_class = OrganizationUserResource
  130. admin.site.register(Organization, OrganizationAdmin)
  131. if settings.BILLING_ENABLED:
  132. admin.site.register(OrganizationSubscription, OrganizationSubscriptionAdmin)
  133. admin.site.register(OrganizationUser, OrganizationUserAdmin)