Repository URL to install this package:
|
Version:
0.3.16 ▾
|
"""
Note: Code to make this work with Django 1.5+ customer user models
was inspired by work by Andrew Brown (@almostabc).
"""
from django.contrib import admin
from django.db.models.fields import FieldDoesNotExist
from .models import Event, EventProcessingException, Transfer, Charge, Plan
from .models import Invoice, InvoiceItem, Subscription, Customer
from .settings import DJSTRIPE_RELATED_MODEL_BILLING_EMAIL_FIELD
from .settings import DJSTRIPE_RELATED_MODEL_NAME_FIELD
from .settings import User
from .settings import CUSTOMER_RELATED_NAME
if hasattr(User, 'USERNAME_FIELD'):
# Using a Django 1.5 User model
related_model_search_fields = [
"customer__related_model__{0}".format(User.USERNAME_FIELD)
]
related_model_search_fields_for_customer = [
"related_model__{0}".format(User.USERNAME_FIELD)
]
try:
# get_field_by_name throws FieldDoesNotExist if the field is not present on the model
User._meta.get_field_by_name('email')
related_model_search_fields + ["customer__related_model__email"]
related_model_search_fields_for_customer + ["related_model__email"]
except FieldDoesNotExist:
pass
else:
# Using a pre-Django 1.5 User model or a custom related model
related_model_search_fields = [
"customer__related_model__{0}".format(DJSTRIPE_RELATED_MODEL_BILLING_EMAIL_FIELD),
"customer__related_model__{0}".format(DJSTRIPE_RELATED_MODEL_NAME_FIELD)
]
related_model_search_fields_for_customer = [
"related_model__{0}".format(DJSTRIPE_RELATED_MODEL_BILLING_EMAIL_FIELD),
"related_model__{0}".format(DJSTRIPE_RELATED_MODEL_NAME_FIELD)
]
class CustomerHasCardListFilter(admin.SimpleListFilter):
title = "card presence"
parameter_name = "has_card"
def lookups(self, request, model_admin):
return [
["yes", "Has Card"],
["no", "Does Not Have a Card"]
]
def queryset(self, request, queryset):
if self.value() == "yes":
return queryset.exclude(card_fingerprint="")
if self.value() == "no":
return queryset.filter(card_fingerprint="")
class InvoiceCustomerHasCardListFilter(admin.SimpleListFilter):
title = "card presence"
parameter_name = "has_card"
def lookups(self, request, model_admin):
return [
["yes", "Has Card"],
["no", "Does Not Have a Card"]
]
def queryset(self, request, queryset):
filter_args = {
"{related_name}__card_fingerprint".format(related_name=CUSTOMER_RELATED_NAME): ""
}
if self.value() == "yes":
return queryset.exclude(**filter_args)
if self.value() == "no":
return queryset.filter(**filter_args)
class CustomerSubscriptionStatusListFilter(admin.SimpleListFilter):
title = "subscription status"
parameter_name = "sub_status"
def lookups(self, request, model_admin):
statuses = [
[x, x.replace("_", " ").title()]
for x in Subscription.objects.all().values_list(
"status",
flat=True
).distinct()
]
statuses.append(["none", "No Subscription"])
return statuses
def queryset(self, request, queryset):
if self.value() is None:
return queryset.all()
else:
return queryset.filter(subscriptions__status=self.value()).distinct()
def send_charge_receipt(modeladmin, request, queryset):
"""
Function for sending receipts from the admin if a receipt is not sent for
a specific charge.
"""
for charge in queryset:
charge.send_receipt()
admin.site.register(
Charge,
readonly_fields=('created',),
list_display=[
"stripe_id",
"customer",
"amount",
"description",
"paid",
"disputed",
"refunded",
"fee",
"receipt_sent",
"created"
],
search_fields=[
"stripe_id",
"customer__stripe_id",
"card_last_4",
"invoice__stripe_id"
] + related_model_search_fields,
list_filter=[
"paid",
"disputed",
"refunded",
"card_kind",
"created"
],
raw_id_fields=[
"customer",
"invoice"
],
actions=(send_charge_receipt,),
)
admin.site.register(
EventProcessingException,
readonly_fields=('created',),
list_display=[
"message",
"event",
"created"
],
search_fields=[
"message",
"traceback",
"data"
],
)
admin.site.register(
Event,
raw_id_fields=["customer"],
readonly_fields=('created',),
list_display=[
"stripe_id",
"kind",
"livemode",
"valid",
"processed",
"created"
],
list_filter=[
"kind",
"created",
"valid",
"processed"
],
search_fields=[
"stripe_id",
"customer__stripe_id",
"validated_message"
] + related_model_search_fields,
)
class SubscriptionInline(admin.TabularInline):
model = Subscription
extra = 0
def subscription_status(obj):
return ", ".join([sub.plan + ": " + sub.status for sub in obj.subscriptions.all()])
subscription_status.short_description = "Subscription Status"
admin.site.register(
Customer,
raw_id_fields=["related_model"],
readonly_fields=('created',),
list_display=[
"stripe_id",
"related_model",
"card_kind",
"card_last_4",
subscription_status,
"created"
],
list_filter=[
"card_kind",
CustomerHasCardListFilter,
CustomerSubscriptionStatusListFilter
],
search_fields=[
"stripe_id"
] + related_model_search_fields_for_customer,
inlines=[SubscriptionInline]
)
class InvoiceItemInline(admin.TabularInline):
model = InvoiceItem
def customer_has_card(obj):
return obj.customer.card_fingerprint != ""
customer_has_card.short_description = "Customer Has Card"
customer_has_card.short_description = "Customer"
def customer_related_model_list_display(obj):
if hasattr(obj, 'USERNAME_FIELD'):
# Using a Django 1.5 User model
username = getattr(obj.customer.related_model, User.USERNAME_FIELD)
else:
# Using a pre-Django 1.5 User model
username = getattr(obj.customer.related_model, DJSTRIPE_RELATED_MODEL_NAME_FIELD)
# In Django 1.5+ a User is not guaranteed to have an email field
email = getattr(obj.customer.related_model, DJSTRIPE_RELATED_MODEL_BILLING_EMAIL_FIELD, '')
return "{0} <{1}>".format(
username,
email
)
admin.site.register(
Invoice,
raw_id_fields=["customer"],
readonly_fields=('created',),
list_display=[
"stripe_id",
"paid",
"closed",
customer_related_model_list_display,
customer_has_card,
"period_start",
"period_end",
"subtotal",
"total",
"created"
],
search_fields=[
"stripe_id",
"customer__stripe_id",
] + related_model_search_fields,
list_filter=[
InvoiceCustomerHasCardListFilter,
"paid",
"closed",
"attempted",
"attempts",
"created",
"date",
"period_end",
"total"
],
inlines=[InvoiceItemInline]
)
admin.site.register(
Transfer,
raw_id_fields=["event"],
readonly_fields=('created',),
list_display=[
"stripe_id",
"amount",
"status",
"date",
"description",
"created"
],
search_fields=[
"stripe_id",
"event__stripe_id"
]
)
class PlanAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
"""Update or create objects using our custom methods that
sync with Stripe."""
if change:
obj.update_name()
else:
Plan.get_or_create(**form.cleaned_data)
def get_readonly_fields(self, request, obj=None):
readonly_fields = list(self.readonly_fields)
if obj:
readonly_fields.extend([
'stripe_id',
'amount',
'currency',
'interval',
'interval_count',
'trial_period_days'])
return readonly_fields
admin.site.register(Plan, PlanAdmin)