Merge branch 'master' of github.com:Gluejar/regluit

pull/1/head
Andromeda Yelton 2011-12-21 13:48:45 -05:00
commit 614b36d15c
6 changed files with 188 additions and 8 deletions

40
campaigntest.py Normal file
View File

@ -0,0 +1,40 @@
from regluit.core import models
from regluit.payment.models import Transaction
from regluit.payment.manager import PaymentManager
from regluit.payment.paypal import IPN_PAY_STATUS_ACTIVE, IPN_PAY_STATUS_INCOMPLETE, IPN_PAY_STATUS_COMPLETED
pm = PaymentManager()
def campaign_display():
campaigns_with_active_transactions = models.Campaign.objects.filter(transaction__status=IPN_PAY_STATUS_ACTIVE)
campaigns_with_incomplete_transactions = models.Campaign.objects.filter(transaction__status=IPN_PAY_STATUS_INCOMPLETE)
campaigns_with_completed_transactions = models.Campaign.objects.filter(transaction__status=IPN_PAY_STATUS_COMPLETED)
print "campaigns with active transactions", campaigns_with_active_transactions
print "campaigns with incomplete transactions", campaigns_with_incomplete_transactions
print "campaigns with completed transactions", campaigns_with_completed_transactions
def campaigns_active():
return models.Campaign.objects.filter(transaction__status=IPN_PAY_STATUS_ACTIVE)
def campaigns_incomplete():
return models.Campaign.objects.filter(transaction__status=IPN_PAY_STATUS_INCOMPLETE)
def campaigns_completed():
return models.Campaign.objects.filter(transaction__status=IPN_PAY_STATUS_COMPLETED)
def execute_campaigns(clist):
return [pm.execute_campaign(c) for c in clist]
def finish_campaigns(clist):
return [pm.finish_campaign(c) for c in clist]
# by the time we've executed a campaign, we should have r.status = 'COMPLETED' for primary but None for secondary
# [[[r.status for r in t.receiver_set.all()] for t in c.transaction_set.all()] for c in campaigns_incomplete()]
# [[[r.status for r in t.receiver_set.all()] for t in c.transaction_set.all()] for c in campaigns_completed()]
# res = [pm.finish_campaign(c) for c in campaigns_incomplete()]

View File

@ -189,3 +189,6 @@ class GoodreadsShelfLoadingForm(forms.Form):
class LibraryThingForm(forms.Form):
lt_username = forms.CharField(max_length=30, required=True)
class CampaignAdminForm(forms.Form):
pass

View File

@ -0,0 +1,68 @@
{% extends "basedocumentation.html" %}
{% block base_js %}{% endblock %}
{% block extra_extra_head %}
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/themes/ui-lightness/jquery-ui.css" type="text/css" media="screen">
{{ form.media.css }}
<script type="text/javascript" src="/static/js/jquery-1.6.3.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
{{ form.media.js }}
{% endblock %}
{% block doccontent %}
<h2>Campaign Admin</h2>
<form method="post" action="#">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="campaign_checkstatus" value="Update Transaction Statuses" id="submit">
</form>
{% if check_status_results %}
<p>Campaign checkstatus output:</p>
<textarea id="id" cols="45" rows="15">
{% autoescape on %}
{{check_status_results}}
{% endautoescape %}
</textarea>
{% endif %}
<!-- Active transactions -->
<p style="font-weight:bold">Campaigns with active transactions</p>
{% if campaigns_with_active_transactions %}
<ul>
{% for campaign in campaigns_with_active_transactions %}
<li>{{campaign.id}} | {{campaign.name}} </li>
{% endfor %}
</ul>
{% else %}
<p>No campaigns with active transactions</p>
{% endif %}
<!-- incomplete transactions -->
<p style="font-weight:bold">Campaigns with incomplete transactions</p>
{% if campaigns_with_incomplete_transactions %}
<ul>
{% for campaign in campaigns_with_incomplete_transactions %}
<li>{{campaign.id}} | {{campaign.name}} </li>
{% endfor %}
</ul>
{% else %}
<p>No campaigns with incomplete transactions</p>
{% endif %}
<!-- completed transactions -->
<p style="font-weight:bold">Campaigns with completed transactions</p>
{% if campaigns_with_completed_transactions %}
<ul>
{% for campaign in campaigns_with_completed_transactions %}
<li>{{campaign.id}} | {{campaign.name}} </li>
{% endfor %}
</ul>
{% else %}
<p>No campaigns with completed transactions</p>
{% endif %}
{% endblock %}

View File

@ -22,6 +22,7 @@ urlpatterns = patterns(
url(r"^rightsholders/campaign/(?P<id>\d+)/$", "manage_campaign", name="manage_campaign"),
url(r"^rightsholders/claim/$", "claim", name="claim"),
url(r"^rh_admin/$", "rh_admin", name="rh_admin"),
url(r"^campaign_admin/$", "campaign_admin", name="campaign_admin"),
url(r"^faq/$", TemplateView.as_view(template_name="faq.html"),
name="faq"),
url(r"^wishlist/$", "wishlist", name="wishlist"),

View File

@ -36,9 +36,10 @@ from regluit.core.search import gluejar_search
from regluit.core.goodreads import GoodreadsClient
from regluit.frontend.forms import UserData, ProfileForm, CampaignPledgeForm, GoodreadsShelfLoadingForm
from regluit.frontend.forms import RightsHolderForm, UserClaimForm, LibraryThingForm, OpenCampaignForm
from regluit.frontend.forms import ManageCampaignForm, DonateForm
from regluit.frontend.forms import ManageCampaignForm, DonateForm, CampaignAdminForm
from regluit.payment.manager import PaymentManager
from regluit.payment.parameters import TARGET_TYPE_CAMPAIGN, TARGET_TYPE_DONATION
from regluit.payment.paypal import Preapproval, IPN_PAY_STATUS_ACTIVE, IPN_PAY_STATUS_INCOMPLETE, IPN_PAY_STATUS_COMPLETED
from regluit.core import goodreads
from tastypie.models import ApiKey
from regluit.payment.models import Transaction
@ -413,6 +414,51 @@ def rh_admin(request):
}
return render(request, "rights_holders.html", context)
def campaign_admin(request):
if not request.user.is_authenticated() :
return render(request, "admins_only.html")
if not request.user.is_staff :
return render(request, "admins_only.html")
context = {}
# first task: run PaymentManager.checkStatus() to update Campaign statuses
# does it return data to display?
form = CampaignAdminForm()
if request.method == 'GET':
check_status_results = None
elif request.method == 'POST':
try:
pm = PaymentManager()
check_status_results = pm.checkStatus()
except Exception, e:
check_status_results = e
# second task: pull out Campaigns with Transactions that are ACTIVE -- and hence can be executed
# Campaign.objects.filter(transaction__status='ACTIVE')
campaigns_with_active_transactions = models.Campaign.objects.filter(transaction__status=IPN_PAY_STATUS_ACTIVE)
# third task: pull out Campaigns with Transactions that are INCOMPLETE
campaigns_with_incomplete_transactions = models.Campaign.objects.filter(transaction__status=IPN_PAY_STATUS_INCOMPLETE)
# 4th task: show all Campaigns with Transactions that are COMPLETED
campaigns_with_completed_transactions = models.Campaign.objects.filter(transaction__status=IPN_PAY_STATUS_COMPLETED)
context.update({
'form': form,
'check_status_results':check_status_results,
'campaigns_with_active_transactions': campaigns_with_active_transactions,
'campaigns_with_incomplete_transactions': campaigns_with_incomplete_transactions,
'campaigns_with_completed_transactions': campaigns_with_completed_transactions
})
return render(request, "campaign_admin.html", context)
def supporter(request, supporter_username, template_name):
supporter = get_object_or_404(User, username=supporter_username)

View File

@ -2,7 +2,8 @@ from regluit.core.models import Campaign, Wishlist
from regluit.payment.models import Transaction, Receiver, PaymentResponse
from django.contrib.auth.models import User
from regluit.payment.parameters import *
from regluit.payment.paypal import Pay, Execute, IPN, IPN_TYPE_PAYMENT, IPN_TYPE_PREAPPROVAL, IPN_TYPE_ADJUSTMENT, Preapproval, IPN_PAY_STATUS_COMPLETED, CancelPreapproval, PaymentDetails, PreapprovalDetails, IPN_SENDER_STATUS_COMPLETED, IPN_TXN_STATUS_COMPLETED
from regluit.payment.paypal import Pay, Execute, IPN, IPN_TYPE_PAYMENT, IPN_TYPE_PREAPPROVAL, IPN_TYPE_ADJUSTMENT, IPN_PAY_STATUS_ACTIVE
from regluit.payment.paypal import Preapproval, IPN_PAY_STATUS_COMPLETED, CancelPreapproval, PaymentDetails, PreapprovalDetails, IPN_SENDER_STATUS_COMPLETED, IPN_TXN_STATUS_COMPLETED
import uuid
import traceback
from datetime import datetime
@ -82,7 +83,8 @@ class PaymentManager( object ):
# will not have a status code or txn id code
if receiver.status != r['status']:
append_element(doc, tran, "receiver_status_ours", receiver.status)
append_element(doc, tran, "receiver_status_theirs", r['status'])
append_element(doc, tran, "receiver_status_theirs",
r['status'] if r['status'] is not None else 'None')
receiver.status = r['status']
receiver.save()
@ -325,12 +327,10 @@ class PaymentManager( object ):
'''
# only allow active transactions to go through again, if there is an error, intervention is needed
transactions = Transaction.objects.filter(campaign=campaign, status="ACTIVE")
transactions = Transaction.objects.filter(campaign=campaign, status=IPN_PAY_STATUS_ACTIVE)
for t in transactions:
# BUGBUG: Fill this in with the correct info from the campaign object
# Campaign.paypal_receiver
receiver_list = [{'email':settings.PAYPAL_GLUEJAR_EMAIL, 'amount':t.amount},
{'email':campaign.paypal_receiver, 'amount':D(t.amount) * (D('1.00') - D(str(settings.GLUEJAR_COMMISSION)))}]
@ -338,6 +338,28 @@ class PaymentManager( object ):
return transactions
def finish_campaign(self, campaign):
'''
finish_campaign
attempts to execute all remaining payment to non-primary receivers
return value: returns a list of transactions with the status of each receiver/transaction updated
'''
# QUESTION: to figure out which transactions are in a state in which the payment to the primary recipient is done but not to secondary recipient
# Consider two possibilities: status=IPN_PAY_STATUS_INCOMPLETE or execution = EXECUTE_TYPE_CHAINED_DELAYED
# which one? Let's try the second one
# only allow incomplete transactions to go through again, if there is an error, intervention is needed
transactions = Transaction.objects.filter(campaign=campaign, execution=EXECUTE_TYPE_CHAINED_DELAYED)
for t in transactions:
result = self.finish_transaction(t)
return transactions
def finish_transaction(self, transaction):
'''