First pass at regluit.payment.models.Account.status

pull/1/head
Raymond Yee 2013-01-14 16:18:19 -08:00
parent a63dd43e2b
commit c3f922e9ba
2 changed files with 200 additions and 7 deletions

View File

@ -27,6 +27,14 @@
"metadata": {},
"outputs": []
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"expiring, expired, soon to expire cards"
]
},
{
"cell_type": "code",
"collapsed": false,
@ -34,7 +42,9 @@
"from regluit.payment.models import Account\n",
"from django.db.models import Q\n",
"\n",
"month = 7\n",
"# set the month/year for comparison\n",
"\n",
"month = 1\n",
"year = 2013\n",
"\n",
"# look only at active accounts\n",
@ -52,10 +62,43 @@
"\n",
"accounts_expiring_later = active_accounts.filter((Q(card_exp_year__gt=year) | Q(card_exp_year=year, card_exp_month__gt = month)))\n",
"\n",
"print active_accounts.count()\n",
"print accounts_expired.count(), accounts_expiring.count(), accounts_expiring_later.count()\n",
"print \"number of active accounts\", active_accounts.count()\n",
"print \"expired: {0} expiring: {1} expire later: {2}\".format(accounts_expired.count(), accounts_expiring.count(), accounts_expiring_later.count())\n",
"\n",
"[(account.card_exp_month, account.card_exp_year) for account in accounts_expired]"
"# expiring soon\n",
"print \"expiring soon\"\n",
"print [(account.user, account.card_exp_month, account.card_exp_year) for account in accounts_expiring]\n",
"\n",
"# expired\n",
"print \"expired\"\n",
"print [(account.user, account.card_exp_month, account.card_exp_year) for account in accounts_expired]"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"accounts with problem transactions"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# easy to figure out the card used for a specific problem transaction?\n",
"# want to figure out problem status for a given Account\n",
"\n",
"from regluit.payment.models import Transaction\n",
"\n",
"# Account has fingerprint\n",
"# transaction doesn't have fingerprint -- will have to calculate fingerprint of card associated with transaction\n",
"# w/ error if we store pay_key -- any problem?\n",
"\n",
"Transaction.objects.filter(host='stripelib', status='Error', approved=True).count()"
],
"language": "python",
"metadata": {},
@ -65,7 +108,121 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# validity of accounts"
"I am hoping that we can use the API to ask for a list of charge.failed --> but I don't see a way to query charges based upon on the status of the charges -- what you have to iterate through all of the charges and filter based on status. ( maybe I should confirm this fact with people at stripe) -- ok let's do that for now"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from regluit.payment.stripelib import StripeClient\n",
"from regluit.payment.models import Transaction\n",
"\n",
"import json\n",
"from itertools import islice\n",
"\n",
"sc = StripeClient()\n",
"charges = islice(sc._all_objs('Charge'), None)\n",
"\n",
"failed_charges = [(c.amount, c.id, c.failure_message, json.loads(c.description)['t.id']) for c in charges if c.failure_message is not None]\n",
"print failed_charges\n",
"\n",
"# look up corresponding Transactions and flag the ones that have not been properly charged\n",
"\n",
"print [t.status for t in Transaction.objects.filter(id__in = [fc[3] for fc in failed_charges])]\n"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Given the specific account I would like to cut the status... need to handle expiration as well as declined charges\n",
"\n",
"from regluit.payment.models import Transaction\n",
"from regluit.payment.models import Account\n",
"from regluit.utils.localdatetime import now, date_today\n",
"\n",
"from itertools import islice\n",
"\n",
"def account_status(account):\n",
"\n",
"# is it deactivated?\n",
"\n",
" today = date_today()\n",
" transactions_w_error_status_older_account = Transaction.objects.filter(host='stripelib', \n",
" status='Error', approved=True, user=account.user)\n",
" \n",
" if account.date_deactivated is not None:\n",
" return 'DEACTIVATED'\n",
"\n",
"# is it expired?\n",
"\n",
" elif account.card_exp_year < today.year or (account.card_exp_year == today.year and account.card_exp_month < today.month):\n",
" return 'EXPIRED'\n",
" \n",
"# about to expire? do I want to distinguish from 'ACTIVE'?\n",
"\n",
" elif (account.card_exp_year == today.year and account.card_exp_month == today.month):\n",
" return 'EXPIRING' \n",
"\n",
"# any transactions w/ errors after the account date?\n",
"# Transaction.objects.filter(host='stripelib', status='Error', approved=True).count()\n",
"\n",
" elif Transaction.objects.filter(host='stripelib', \n",
" status='Error', approved=True, user=account.user).filter(date_payment__gt=account.date_created):\n",
" return 'ERROR'\n",
" else:\n",
" return 'ACTIVE'\n",
" \n",
"# test out with tghe account that is currently erroring out\n",
"\n",
"acc_with_error = Transaction.objects.get(id=773).user.profile.account\n",
"print account_status(acc_with_error)\n",
"print\n",
"\n",
"for account in islice(Account.objects.all(),10):\n",
" print account_status(account)\n"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"acc_with_error.status"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"acc_with_error = Transaction.objects.get(id=773).user.profile.account\n",
"acc_with_error.user\n",
"\n",
"trans = Transaction.objects.filter(host='stripelib', \n",
" status='Error', approved=True, user=acc_with_error.user)\n",
"\n",
"acc_with_error.date_created, [t.date_payment for t in trans] \n",
"\n",
"print trans.filter(date_payment__gt=acc_with_error.date_created)"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# validity of accounts -- need to use real stripe keys if we want to look at production data"
]
},
{

View File

@ -5,7 +5,7 @@ from django.db.models import Q
from regluit.payment.parameters import *
from regluit.payment.signals import credit_balance_added, pledge_created
from regluit.utils.localdatetime import now
from regluit.utils.localdatetime import now, date_today
from django.db.models.signals import post_save, post_delete
@ -335,7 +335,43 @@ class Account(models.Model):
def deactivate(self):
"""Don't allow more than one active Account of given host to be associated with a given user"""
self.date_deactivated = now()
self.save()
self.save()
@property
def status(self):
"""returns ACTIVE, DEACTIVATED, EXPIRED, EXPIRING, or ERROR"""
# TO DO: integrate this method in to see whether we are using the right range of values
# also, cache this status by having a value in the db in the future.
# is it deactivated?
today = date_today()
transactions_w_error_status_older_account = Transaction.objects.filter(host='stripelib',
status='Error', approved=True, user=self.user)
if self.date_deactivated is not None:
return 'DEACTIVATED'
# is it expired?
elif self.card_exp_year < today.year or (self.card_exp_year == today.year and self.card_exp_month < today.month):
return 'EXPIRED'
# about to expire? do I want to distinguish from 'ACTIVE'?
elif (self.card_exp_year == today.year and self.card_exp_month == today.month):
return 'EXPIRING'
# any transactions w/ errors after the account date?
# Transaction.objects.filter(host='stripelib', status='Error', approved=True).count()
elif Transaction.objects.filter(host='stripelib',
status='Error', approved=True, user=self.user).filter(date_payment__gt=self.date_created):
return 'ERROR'
else:
return 'ACTIVE'
# handle any save, updates to a payment.Transaction