Work in progress
parent
4540263a6d
commit
94384fcb59
|
@ -18,7 +18,10 @@ import regluit.core.isbn
|
|||
from regluit.core.signals import successful_campaign, unsuccessful_campaign
|
||||
import binascii
|
||||
|
||||
from regluit.payment.parameters import TRANSACTION_STATUS_ACTIVE
|
||||
from regluit.payment.parameters import TRANSACTION_STATUS_ACTIVE, TRANSACTION_STATUS_COMPLETE, TRANSACTION_STATUS_CANCELED, TRANSACTION_STATUS_ERROR, TRANSACTION_STATUS_FAILED, TRANSACTION_STATUS_INCOMPLETE
|
||||
|
||||
from django.db.models import Q
|
||||
|
||||
|
||||
class UnglueitError(RuntimeError):
|
||||
pass
|
||||
|
@ -323,7 +326,26 @@ class Campaign(models.Model):
|
|||
def supporters_count(self):
|
||||
# avoid transmitting the whole list if you don't need to; let the db do the count.
|
||||
return self.transactions().filter(status=TRANSACTION_STATUS_ACTIVE).values_list('user', flat=True).distinct().count()
|
||||
|
||||
def transaction_to_recharge(self, user):
|
||||
"""given a user, return the transaction to be recharged if there is one -- None otherwise"""
|
||||
|
||||
# only if a campaign is SUCCESSFUL, we allow for recharged
|
||||
|
||||
if self.status == 'SUCCESSFUL':
|
||||
if self.transaction_set.filter(Q(user=user) & (Q(status=TRANSACTION_STATUS_COMPLETE) | Q(status=TRANSACTION_STATUS_ACTIVE))).count():
|
||||
# presence of an active or complete transaction means no transaction to recharge
|
||||
return None
|
||||
else:
|
||||
transactions = self.transaction_set.filter(Q(user=user) & (Q(status=TRANSACTION_STATUS_ERROR) | Q(status=TRANSACTION_STATUS_FAILED)))
|
||||
# assumption --that the first failed/errored transaction has the amount we need to recharge
|
||||
if transactions.count():
|
||||
return transactions[0]
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
|
||||
def ungluers(self):
|
||||
p = PaymentManager()
|
||||
ungluers={"all":[],"supporters":[], "patrons":[], "bibliophiles":[]}
|
||||
|
@ -805,19 +827,19 @@ class UserProfile(models.Model):
|
|||
goodreads_auth_secret = models.TextField(null=True, blank=True)
|
||||
goodreads_user_link = models.CharField(max_length=200, null=True, blank=True)
|
||||
|
||||
class CampaignSurveyResponse(models.Model):
|
||||
# generic
|
||||
campaign = models.ForeignKey("Campaign", related_name="surveyresponses", null=False)
|
||||
user = models.OneToOneField(User, related_name='wishlist')
|
||||
transaction = models.ForeignKey(Transaction, null=True)
|
||||
# for OLA only
|
||||
premium = models.ForeignKey(Premium, null=True)
|
||||
anonymous = models.BooleanField(null=False)
|
||||
# relevant to all campaigns since these arise from acknowledgement requirements from generic premiums
|
||||
name = models.CharField(max_length=140, blank=True)
|
||||
url = models.URLField(blank=True)
|
||||
tagline = models.CharField(max_length=140, blank=True)
|
||||
# do we need to collect address for Rupert or will he do that once he has emails?
|
||||
#class CampaignSurveyResponse(models.Model):
|
||||
# # generic
|
||||
# campaign = models.ForeignKey("Campaign", related_name="surveyresponse", null=False)
|
||||
# user = models.OneToOneField(User, related_name='surveyresponse')
|
||||
# transaction = models.ForeignKey("payment.Transaction", null=True)
|
||||
# # for OLA only
|
||||
# premium = models.ForeignKey("Premium", null=True)
|
||||
# anonymous = models.BooleanField(null=False)
|
||||
# # relevant to all campaigns since these arise from acknowledgement requirements from generic premiums
|
||||
# name = models.CharField(max_length=140, blank=True)
|
||||
# url = models.URLField(blank=True)
|
||||
# tagline = models.CharField(max_length=140, blank=True)
|
||||
# # do we need to collect address for Rupert or will he do that once he has emails?
|
||||
|
||||
# this was causing a circular import problem and we do not seem to be using
|
||||
# anything from regluit.core.signals after this line
|
||||
|
|
|
@ -805,12 +805,10 @@ class PledgeRechargeView(TemplateView):
|
|||
a view to allow for recharge of a transaction for failed transactions or ones with errors
|
||||
"""
|
||||
template_name="pledge_recharge.html"
|
||||
form_class = CampaignPledgeForm
|
||||
embedded = False
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
context = super(PledgeModifyView, self).get_context_data(**kwargs)
|
||||
context = super(PledgeRechargeView, self).get_context_data(**kwargs)
|
||||
|
||||
# the following should be true since PledgeModifyView.as_view is wrapped in login_required
|
||||
assert self.request.user.is_authenticated()
|
||||
|
@ -820,114 +818,37 @@ class PledgeRechargeView(TemplateView):
|
|||
|
||||
try:
|
||||
campaign = work.last_campaign()
|
||||
premiums = campaign.effective_premiums()
|
||||
|
||||
# which combination of campaign and transaction status required?
|
||||
# Campaign must be ACTIVE
|
||||
assert campaign.status == 'ACTIVE'
|
||||
# only if a campaign is SUCCESSFUL, we allow for recharged
|
||||
|
||||
# if there is a FAILED or ERROR transaction and no ACTIVE or COMPLETE transaction
|
||||
# instead of a PREAPPROVAL, let's go right for PAYMENT...if successful, we need to send notice...if not, fail it out
|
||||
|
||||
transactions = campaign.transactions().filter(user=user, status=TRANSACTION_STATUS_ACTIVE)
|
||||
if campaign.transaction_set.filter(Q(user=user) & (Q(status=TRANSACTION_STATUS_COMPLETE) | Q(status=TRANSACTION_STATUS_ACTIVE))).count():
|
||||
raise Http404
|
||||
|
||||
transactions = campaign.transaction_set.filter(Q(user=user) & (Q(status=TRANSACTION_STATUS_ERROR) | Q(status=TRANSACTION_STATUS_FAILED)))
|
||||
# there should be only 1
|
||||
assert transactions.count() == 1
|
||||
transaction = transactions[0]
|
||||
assert transaction.type == PAYMENT_TYPE_AUTHORIZATION and transaction.status == TRANSACTION_STATUS_ACTIVE
|
||||
|
||||
|
||||
except Exception, e:
|
||||
raise e
|
||||
|
||||
# what stuff do we need to pull out to populate form?
|
||||
# preapproval_amount, premium_id (which we don't have stored yet)
|
||||
if transaction.premium is not None:
|
||||
premium_id = transaction.premium.id
|
||||
premium_description = transaction.premium.description
|
||||
else:
|
||||
premium_id = None
|
||||
premium_description = None
|
||||
|
||||
# is there a Transaction for an ACTIVE campaign for this
|
||||
# should make sure Transaction is modifiable.
|
||||
# compute the amount that supporter had tried to charge
|
||||
|
||||
preapproval_amount = transaction.amount
|
||||
data = {'preapproval_amount':preapproval_amount, 'premium_id':premium_id}
|
||||
|
||||
# initialize form with the current state of the transaction if the current values empty
|
||||
form = kwargs['form']
|
||||
|
||||
if not(form.is_bound):
|
||||
form_class = self.get_form_class()
|
||||
form = form_class(initial=data)
|
||||
|
||||
data = {'preapproval_amount':preapproval_amount}
|
||||
|
||||
context.update({
|
||||
'work':work,
|
||||
'campaign':campaign,
|
||||
'premiums':premiums,
|
||||
'form':form,
|
||||
'preapproval_amount':preapproval_amount,
|
||||
'premium_id':premium_id,
|
||||
'premium_description': premium_description,
|
||||
'faqmenu': 'modify',
|
||||
'tid': transaction.id,
|
||||
'payment_processor':settings.PAYMENT_PROCESSOR,
|
||||
})
|
||||
return context
|
||||
|
||||
|
||||
def form_invalid(self, form):
|
||||
logger.info("form.non_field_errors: {0}".format(form.non_field_errors()))
|
||||
response = self.render_to_response(self.get_context_data(form=form))
|
||||
return response
|
||||
|
||||
def form_valid(self, form):
|
||||
|
||||
# What are the situations we need to deal with?
|
||||
# 2 main situations: if the new amount is less than max_amount, no need to go out to PayPal again
|
||||
# if new amount is greater than max_amount...need to go out and get new approval.
|
||||
# to start with, we can use the standard pledge_complete, pledge_cancel machinery
|
||||
# might have to modify the pledge_complete, pledge_cancel because the messages are going to be
|
||||
# different because we're modifying a pledge rather than a new one.
|
||||
|
||||
work_id = self.kwargs["work_id"]
|
||||
preapproval_amount = form.cleaned_data["preapproval_amount"]
|
||||
anonymous = form.cleaned_data["anonymous"]
|
||||
|
||||
assert self.request.user.is_authenticated()
|
||||
user = self.request.user
|
||||
|
||||
# right now, if there is a non-zero pledge amount, go with that. otherwise, do the pre_approval
|
||||
campaign = models.Work.objects.get(id=int(work_id)).last_campaign()
|
||||
assert campaign.status == 'ACTIVE'
|
||||
|
||||
premium_id = form.cleaned_data["premium_id"]
|
||||
# confirm that the premium_id is a valid one for the campaign in question
|
||||
try:
|
||||
premium = models.Premium.objects.get(id=premium_id)
|
||||
if not (premium.campaign is None or premium.campaign == campaign):
|
||||
premium = None
|
||||
except models.Premium.DoesNotExist, e:
|
||||
premium = None
|
||||
|
||||
transactions = campaign.transactions().filter(user=user, status=TRANSACTION_STATUS_ACTIVE)
|
||||
assert transactions.count() == 1
|
||||
transaction = transactions[0]
|
||||
assert transaction.type == PAYMENT_TYPE_AUTHORIZATION and transaction.status == TRANSACTION_STATUS_ACTIVE
|
||||
|
||||
p = PaymentManager(embedded=self.embedded)
|
||||
paymentReason = "Unglue.it Pledge for {0}".format(campaign.name)
|
||||
status, url = p.modify_transaction(transaction=transaction, amount=preapproval_amount, premium=premium,
|
||||
paymentReason=paymentReason)
|
||||
|
||||
logger.info("status: {0}, url:{1}".format(status, url))
|
||||
|
||||
if status and url is not None:
|
||||
logger.info("PledgeModifyView paypal: " + url)
|
||||
return HttpResponseRedirect(url)
|
||||
elif status and url is None:
|
||||
# let's use the pledge_complete template for now and maybe look into customizing it.
|
||||
return HttpResponseRedirect("{0}?tid={1}".format(reverse('pledge_complete'), transaction.id))
|
||||
else:
|
||||
return HttpResponse("No modification made")
|
||||
|
||||
|
||||
|
||||
|
||||
class PledgeCompleteView(TemplateView):
|
||||
"""A callback for PayPal to tell unglue.it that a payment transaction has completed successfully.
|
||||
|
|
Loading…
Reference in New Issue