Merge branch 'master' of github.com:Gluejar/regluit
commit
614b36d15c
|
@ -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()]
|
||||||
|
|
|
@ -189,3 +189,6 @@ class GoodreadsShelfLoadingForm(forms.Form):
|
||||||
|
|
||||||
class LibraryThingForm(forms.Form):
|
class LibraryThingForm(forms.Form):
|
||||||
lt_username = forms.CharField(max_length=30, required=True)
|
lt_username = forms.CharField(max_length=30, required=True)
|
||||||
|
|
||||||
|
class CampaignAdminForm(forms.Form):
|
||||||
|
pass
|
||||||
|
|
|
@ -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 %}
|
|
@ -22,6 +22,7 @@ urlpatterns = patterns(
|
||||||
url(r"^rightsholders/campaign/(?P<id>\d+)/$", "manage_campaign", name="manage_campaign"),
|
url(r"^rightsholders/campaign/(?P<id>\d+)/$", "manage_campaign", name="manage_campaign"),
|
||||||
url(r"^rightsholders/claim/$", "claim", name="claim"),
|
url(r"^rightsholders/claim/$", "claim", name="claim"),
|
||||||
url(r"^rh_admin/$", "rh_admin", name="rh_admin"),
|
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"),
|
url(r"^faq/$", TemplateView.as_view(template_name="faq.html"),
|
||||||
name="faq"),
|
name="faq"),
|
||||||
url(r"^wishlist/$", "wishlist", name="wishlist"),
|
url(r"^wishlist/$", "wishlist", name="wishlist"),
|
||||||
|
|
|
@ -36,9 +36,10 @@ from regluit.core.search import gluejar_search
|
||||||
from regluit.core.goodreads import GoodreadsClient
|
from regluit.core.goodreads import GoodreadsClient
|
||||||
from regluit.frontend.forms import UserData, ProfileForm, CampaignPledgeForm, GoodreadsShelfLoadingForm
|
from regluit.frontend.forms import UserData, ProfileForm, CampaignPledgeForm, GoodreadsShelfLoadingForm
|
||||||
from regluit.frontend.forms import RightsHolderForm, UserClaimForm, LibraryThingForm, OpenCampaignForm
|
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.manager import PaymentManager
|
||||||
from regluit.payment.parameters import TARGET_TYPE_CAMPAIGN, TARGET_TYPE_DONATION
|
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 regluit.core import goodreads
|
||||||
from tastypie.models import ApiKey
|
from tastypie.models import ApiKey
|
||||||
from regluit.payment.models import Transaction
|
from regluit.payment.models import Transaction
|
||||||
|
@ -413,6 +414,51 @@ def rh_admin(request):
|
||||||
}
|
}
|
||||||
return render(request, "rights_holders.html", context)
|
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):
|
def supporter(request, supporter_username, template_name):
|
||||||
supporter = get_object_or_404(User, username=supporter_username)
|
supporter = get_object_or_404(User, username=supporter_username)
|
||||||
|
|
|
@ -2,7 +2,8 @@ from regluit.core.models import Campaign, Wishlist
|
||||||
from regluit.payment.models import Transaction, Receiver, PaymentResponse
|
from regluit.payment.models import Transaction, Receiver, PaymentResponse
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from regluit.payment.parameters import *
|
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 uuid
|
||||||
import traceback
|
import traceback
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
@ -82,7 +83,8 @@ class PaymentManager( object ):
|
||||||
# will not have a status code or txn id code
|
# will not have a status code or txn id code
|
||||||
if receiver.status != r['status']:
|
if receiver.status != r['status']:
|
||||||
append_element(doc, tran, "receiver_status_ours", receiver.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.status = r['status']
|
||||||
receiver.save()
|
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
|
# 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:
|
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},
|
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)))}]
|
{'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
|
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):
|
def finish_transaction(self, transaction):
|
||||||
'''
|
'''
|
||||||
|
|
Loading…
Reference in New Issue