def test_anonymous(self): # Anonymous donation is anonymous donation = models.Donation( timereceived=timezone.now(), amount=Decimal(1.5), domain='PAYPAL', requestedvisibility='ANON', event=self.event, ) self.assertTrue(donation.anonymous()) # Donation from an anonymous donor with CURR is anonymous donation = models.Donation( timereceived=timezone.now(), amount=Decimal(1.5), domain='PAYPAL', requestedvisibility='CURR', donor=models.Donor(visibility='ANON'), event=self.event, ) self.assertTrue(donation.anonymous()) # Donation from a non-anonymous donor with CURR is not anonymous donation = models.Donation( timereceived=timezone.now(), amount=Decimal(1.5), domain='PAYPAL', requestedvisibility='CURR', donor=models.Donor(visibility='ALIAS'), event=self.event, ) self.assertFalse(donation.anonymous())
def test_anonymous_and_no_comment(self): alias_donor = models.Donor(visibility='ALIAS') anon_donor = models.Donor(visibility='ANON') # GOOD: Anonymous donation with no comment and any donor donation = models.Donation( timereceived=timezone.now(), amount=Decimal(1.5), domain='PAYPAL', requestedvisibility='ANON', donor=alias_donor, event=self.event, ) self.assertTrue(donation.anonymous_and_no_comment()) # GOOD: Donation with no comment, CURR visibility, and anonymous donor donation = models.Donation( timereceived=timezone.now(), amount=Decimal(1.5), domain='PAYPAL', requestedvisibility='CURR', donor=anon_donor, event=self.event, ) self.assertTrue(donation.anonymous_and_no_comment()) # BAD: Donation with no comment, but some non-anonymous visibility donation = models.Donation( timereceived=timezone.now(), amount=Decimal(1.5), domain='PAYPAL', requestedvisibility='ALIAS', donor=anon_donor, event=self.event, ) self.assertFalse(donation.anonymous_and_no_comment()) donation.approve_if_anonymous_and_no_comment() self.assertEqual(donation.readstate, 'PENDING') # BAD: Donation with a comment donation = models.Donation( timereceived=timezone.now(), amount=Decimal(1.5), comment='Hello', domain='PAYPAL', requestedvisibility='ANON', donor=anon_donor, event=self.event, ) self.assertEqual(donation.readstate, 'PENDING')
def donate_orig(request, event): event = viewutil.get_event(event) if event.locked: raise Http404 bidsFormPrefix = "bidsform" prizeFormPrefix = "prizeForm" if request.method == 'POST': commentform = forms.DonationEntryForm(event=event, data=request.POST) if commentform.is_valid(): prizesform = forms.PrizeTicketFormSet( amount=commentform.cleaned_data['amount'], data=request.POST, prefix=prizeFormPrefix) bidsform = forms.DonationBidFormSet( amount=commentform.cleaned_data['amount'], data=request.POST, prefix=bidsFormPrefix) if bidsform.is_valid() and prizesform.is_valid(): with transaction.atomic(): donation = models.Donation( amount=commentform.cleaned_data['amount'], timereceived=pytz.utc.localize( datetime.datetime.utcnow()), domain='PAYPAL', domainId=str(random.getrandbits(128)), event=event, testdonation=event.usepaypalsandbox) if commentform.cleaned_data['comment']: donation.comment = commentform.cleaned_data['comment'] donation.commentstate = "PENDING" donation.requestedvisibility = commentform.cleaned_data[ 'requestedvisibility'] donation.requestedalias = commentform.cleaned_data[ 'requestedalias'] donation.requestedemail = commentform.cleaned_data[ 'requestedemail'] donation.requestedsolicitemail = commentform.cleaned_data[ 'requestedsolicitemail'] donation.currency = event.paypalcurrency donation.save() for bidform in bidsform: if 'bid' in bidform.cleaned_data and bidform.cleaned_data[ 'bid']: bid = bidform.cleaned_data['bid'] if bid.allowuseroptions: # unfortunately, you can't use get_or_create when using a non-atomic transaction # this does technically introduce a race condition, I'm just going to hope that two people don't # suggest the same option at the exact same time # also, I want to do case-insensitive comparison on the name try: bid = models.Bid.objects.get( event=bid.event, speedrun=bid.speedrun, name__iexact=bidform. cleaned_data['customoptionname'], parent=bid) except models.Bid.DoesNotExist: bid = models.Bid.objects.create( event=bid.event, speedrun=bid.speedrun, name=bidform. cleaned_data['customoptionname'], parent=bid, state='PENDING', istarget=True) donation.bids.add(models.DonationBid( bid=bid, amount=Decimal( bidform.cleaned_data['amount'])), bulk=False) for prizeform in prizesform: if 'prize' in prizeform.cleaned_data and prizeform.cleaned_data[ 'prize']: prize = prizeform.cleaned_data['prize'] donation.tickets.add( models.PrizeTicket( prize=prize, amount=Decimal( prizeform.cleaned_data['amount']))) donation.full_clean() donation.save() paypal_dict = { "amount": str(donation.amount), "cmd": "_donations", "business": donation.event.paypalemail, "item_name": donation.event.receivername, "notify_url": request.build_absolute_uri(reverse('tracker:ipn')), "return_url": request.build_absolute_uri( reverse('tracker:paypal_return')), "cancel_return": request.build_absolute_uri( reverse('tracker:paypal_cancel')), "custom": str(donation.id) + ":" + donation.domainId, "currency_code": donation.event.paypalcurrency, "no_shipping": 0, } # Create the form instance form = forms.PayPalDonationsForm( button_type="donate", sandbox=donation.event.usepaypalsandbox, initial=paypal_dict) context = {"event": donation.event, "form": form} return views_common.tracker_response( request, "tracker/paypal_redirect.html", context) else: bidsform = forms.DonationBidFormSet(amount=Decimal('0.00'), data=request.POST, prefix=bidsFormPrefix) prizesform = forms.PrizeTicketFormSet(amount=Decimal('0.00'), data=request.POST, prefix=prizeFormPrefix) else: commentform = forms.DonationEntryForm(event=event) bidsform = forms.DonationBidFormSet(amount=Decimal('0.00'), prefix=bidsFormPrefix) prizesform = forms.PrizeTicketFormSet(amount=Decimal('0.00'), prefix=prizeFormPrefix) def bid_parent_info(bid): if bid != None: return { 'name': bid.name, 'description': bid.description, 'parent': bid_parent_info(bid.parent) } else: return None def bid_info(bid): result = { 'id': bid.id, 'name': bid.name, 'description': bid.description, 'label': bid.full_label(not bid.allowuseroptions), 'count': bid.count, 'amount': bid.total, 'goal': Decimal(bid.goal or '0.00'), 'parent': bid_parent_info(bid.parent) } if bid.speedrun: result['runname'] = bid.speedrun.name if bid.suggestions.exists(): result['suggested'] = list([x.name for x in bid.suggestions.all()]) if bid.allowuseroptions: result['custom'] = ['custom'] result[ 'label'] += ' (select and add a name next to "New Option Name")' return result bids = filters.run_model_query( 'bidtarget', { 'state': 'OPENED', 'event': event.id }, user=request.user).distinct().select_related( 'parent').prefetch_related('suggestions') allPrizes = filters.run_model_query('prize', { 'feed': 'current', 'event': event.id }) prizes = allPrizes.filter(ticketdraw=False) dumpArray = [bid_info(o) for o in bids] bidsJson = json.dumps(dumpArray, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder) ticketPrizes = allPrizes.filter(ticketdraw=True, auto_tickets=False) def prize_info(prize): result = { 'id': prize.id, 'name': prize.name, 'description': prize.description, 'minimumbid': prize.minimumbid, 'maximumbid': prize.maximumbid, 'sumdonations': prize.sumdonations } return result dumpArray = [prize_info(o) for o in ticketPrizes.all()] ticketPrizesJson = json.dumps(dumpArray, ensure_ascii=False, cls=serializers.json.DjangoJSONEncoder) return views_common.tracker_response( request, "tracker/donate.html", { 'event': event, 'bidsform': bidsform, 'prizesform': prizesform, 'commentform': commentform, 'hasBids': bids.count() > 0, 'bidsJson': bidsJson, 'hasTicketPrizes': ticketPrizes.count() > 0, 'ticketPrizesJson': ticketPrizesJson, 'prizes': prizes, 'site_name': settings.SITE_NAME, })
def post(self, request, *args, **kwargs): context = self.get_context_data(**kwargs) comment_form = context['commentform'] bids_form = context['bidsform'] if comment_form.is_valid() and bids_form.is_valid(): with transaction.atomic(): # Make the new donation records. donation = models.Donation( amount=comment_form.cleaned_data['amount'], timereceived=pytz.utc.localize(datetime.datetime.utcnow()), domain='PAYPAL', domainId=str(random.getrandbits(128)), event=context['event'], testdonation=context['event'].usepaypalsandbox) if comment_form.cleaned_data['comment']: donation.comment = comment_form.cleaned_data['comment'] donation.commentstate = "PENDING" # Use "alias only" visibility if alias is provided, otherwise use current value (default anonymous). donation.requestedvisibility = "ALIAS" if comment_form.cleaned_data[ 'requestedalias'] else "CURR" donation.requestedalias = comment_form.cleaned_data[ 'requestedalias'] donation.requestedemail = comment_form.cleaned_data[ 'requestedemail'] donation.requestedsolicitemail = "CURR" donation.currency = context['event'].paypalcurrency donation.save() # Make bid records for the donation. for bid in context['bids']: amt_field = 'bid_amt_{}'.format(bid.id) # Check if the user is adding a new option for a bid war. if bid.allowuseroptions: opt_field = 'bid_new_option_name_{}'.format(bid.id) if bids_form.cleaned_data.get( amt_field) and bids_form.cleaned_data.get( opt_field): try: option = models.Bid.objects.get( event=bid.event, speedrun=bid.speedrun, name__iexact=bids_form. cleaned_data[opt_field], parent=bid) except models.Bid.DoesNotExist: option = models.Bid.objects.create( event=bid.event, speedrun=bid.speedrun, name=bids_form.cleaned_data[opt_field], parent=bid, state='PENDING', istarget=True) donation.bids.add(models.DonationBid( bid=option, amount=Decimal( bids_form.cleaned_data[amt_field])), bulk=False) # Otherwise, check if this bid is a target. elif bid.istarget: if bids_form.cleaned_data.get(amt_field): donation.bids.add(models.DonationBid( bid=bid, amount=Decimal( bids_form.cleaned_data[amt_field])), bulk=False) # Check any of its children if they are targets. for option in bid.options.all(): opt_amt_field = 'bid_amt_{}'.format(option.id) if option.istarget and bids_form.cleaned_data.get( opt_amt_field): donation.bids.add(models.DonationBid( bid=option, amount=Decimal( bids_form.cleaned_data[opt_amt_field])), bulk=False) donation.full_clean() donation.save() # Do the PayPal thing. paypal_dict = { "amount": str(donation.amount), "cmd": "_donations", "business": donation.event.paypalemail, "item_name": donation.event.receivername, "notify_url": request.build_absolute_uri(reverse('tracker:ipn')), "return_url": request.build_absolute_uri(reverse('tracker:paypal_return')), "cancel_return": request.build_absolute_uri( reverse('tracker:donate', args=[context['event'].short])), "custom": str(donation.id) + ":" + donation.domainId, "currency_code": donation.event.paypalcurrency, "no_shipping": 0, } # Create the form instance form = forms.PayPalDonationsForm( button_type="donate", sandbox=donation.event.usepaypalsandbox, initial=paypal_dict) context = {"event": donation.event, "form": form} return views_common.tracker_response( request, "tracker/paypal_redirect.html", context) return self.render_to_response(context)
def process_form(request, event): bidsFormPrefix = "bidsform" prizeFormPrefix = "prizeForm" if request.method == 'POST': commentform = forms.DonationEntryForm(event=event, data=request.POST) if commentform.is_valid(): prizesform = forms.PrizeTicketFormSet(amount=commentform.cleaned_data['amount'], data=request.POST, prefix=prizeFormPrefix) bidsform = forms.DonationBidFormSet(amount=commentform.cleaned_data['amount'], data=request.POST, prefix=bidsFormPrefix) if bidsform.is_valid() and prizesform.is_valid(): with transaction.atomic(): donation = models.Donation(amount=commentform.cleaned_data['amount'], timereceived=pytz.utc.localize(datetime.datetime.utcnow()), domain='PAYPAL', domainId=str(random.getrandbits(128)), event=event, testdonation=event.usepaypalsandbox) if commentform.cleaned_data['comment']: donation.comment = commentform.cleaned_data['comment'] donation.commentstate = "PENDING" donation.requestedvisibility = commentform.cleaned_data['requestedvisibility'] donation.requestedalias = commentform.cleaned_data['requestedalias'] donation.requestedemail = commentform.cleaned_data['requestedemail'] donation.requestedsolicitemail = commentform.cleaned_data['requestedsolicitemail'] donation.currency = event.paypalcurrency donation.save() for bidform in bidsform: if 'bid' in bidform.cleaned_data and bidform.cleaned_data['bid']: bid = bidform.cleaned_data['bid'] if bid.allowuseroptions: # unfortunately, you can't use get_or_create when using a non-atomic transaction # this does technically introduce a race condition, I'm just going to hope that two people don't # suggest the same option at the exact same time # also, I want to do case-insensitive comparison on the name try: bid = models.Bid.objects.get(event=bid.event, speedrun=bid.speedrun, name__iexact=bidform.cleaned_data['customoptionname'], parent=bid) except models.Bid.DoesNotExist: bid = models.Bid.objects.create(event=bid.event, speedrun=bid.speedrun, name=bidform.cleaned_data['customoptionname'], parent=bid, state='PENDING', istarget=True) donation.bids.add(models.DonationBid(bid=bid, amount=Decimal( bidform.cleaned_data['amount'])), bulk=False) for prizeform in prizesform: if 'prize' in prizeform.cleaned_data and prizeform.cleaned_data['prize']: prize = prizeform.cleaned_data['prize'] donation.tickets.add(models.PrizeTicket( prize=prize, amount=Decimal(prizeform.cleaned_data['amount']))) donation.full_clean() donation.save() paypal_dict = { "amount": str(donation.amount), "cmd": "_donations", "business": donation.event.paypalemail, "item_name": donation.event.receivername, "notify_url": request.build_absolute_uri(reverse('tracker:ipn')), "return": request.build_absolute_uri(reverse('tracker:paypal_return')), "cancel_return": request.build_absolute_uri(reverse('tracker:paypal_cancel')), "custom": str(donation.id) + ":" + donation.domainId, "currency_code": donation.event.paypalcurrency, "no_shipping": 0, } # Create the form instance form = PayPalPaymentsForm( button_type="donate", sandbox=donation.event.usepaypalsandbox, initial=paypal_dict) context = {"event": donation.event, "form": form} return views_common.tracker_response(request, "tracker/paypal_redirect.html", context), None, None else: bidsform = forms.DonationBidFormSet(amount=Decimal( '0.00'), data=request.POST, prefix=bidsFormPrefix) bidsform.is_valid() prizesform = forms.PrizeTicketFormSet(amount=Decimal( '0.00'), data=request.POST, prefix=prizeFormPrefix) prizesform.is_valid() else: commentform = forms.DonationEntryForm(event=event) bidsform = forms.DonationBidFormSet( amount=Decimal('0.00'), prefix=bidsFormPrefix) prizesform = forms.PrizeTicketFormSet( amount=Decimal('0.00'), prefix=prizeFormPrefix) return commentform, bidsform, prizesform
def test_approve_if_anonymous_and_no_comment(self): alias_donor = models.Donor(visibility='ALIAS') anon_donor = models.Donor(visibility='ANON') # If the comment was already read (or anything not pending), don't act donation = models.Donation( timereceived=timezone.now(), readstate='READ', amount=Decimal(1.5), domain='PAYPAL', requestedvisibility='ANON', donor=alias_donor, event=self.event, ) donation.approve_if_anonymous_and_no_comment() self.assertEqual(donation.readstate, 'READ') # With no threshold given, just ignore donation = models.Donation( timereceived=timezone.now(), amount=Decimal(1.5), domain='PAYPAL', requestedvisibility='ANON', donor=alias_donor, event=self.event, ) donation.approve_if_anonymous_and_no_comment() self.assertEqual(donation.readstate, 'IGNORED') # With a threshold and a donation above it, send to reader donation = models.Donation( timereceived=timezone.now(), amount=Decimal(1.5), domain='PAYPAL', requestedvisibility='CURR', donor=anon_donor, event=self.event, ) donation.approve_if_anonymous_and_no_comment(1) self.assertEqual(donation.readstate, 'READY') # With a threshold and a donation below it, ignore donation = models.Donation( timereceived=timezone.now(), amount=Decimal(1.5), domain='PAYPAL', requestedvisibility='ANON', donor=anon_donor, event=self.event, ) donation.approve_if_anonymous_and_no_comment(5) self.assertEqual(donation.readstate, 'IGNORED') # Donation with a comment should not be approved donation = models.Donation( timereceived=timezone.now(), amount=Decimal(1.5), comment='Hello', domain='PAYPAL', requestedvisibility='ANON', donor=anon_donor, event=self.event, ) donation.approve_if_anonymous_and_no_comment(100) self.assertEqual(donation.readstate, 'PENDING')
def process_form(request, event): bidsFormPrefix = 'bidsform' if request.method == 'POST': commentform = forms.DonationEntryForm(event=event, data=request.POST) if commentform.is_valid(): bidsform = forms.DonationBidFormSet( amount=commentform.cleaned_data['amount'], data=request.POST, prefix=bidsFormPrefix, ) if bidsform.is_valid(): with transaction.atomic(): donation = models.Donation( amount=commentform.cleaned_data['amount'], timereceived=pytz.utc.localize( datetime.datetime.utcnow()), domain='PAYPAL', domainId=str(random.getrandbits(128)), event=event, ) if commentform.cleaned_data['comment']: donation.comment = commentform.cleaned_data['comment'] donation.commentstate = 'PENDING' donation.requestedvisibility = commentform.cleaned_data[ 'requestedvisibility'] donation.requestedalias = commentform.cleaned_data[ 'requestedalias'] donation.requestedemail = commentform.cleaned_data[ 'requestedemail'] donation.requestedsolicitemail = commentform.cleaned_data[ 'requestedsolicitemail'] donation.currency = event.paypalcurrency if request.session.get('uid'): donation.steamid = request.session.get('uid') donation.save() for bidform in bidsform: if ('bid' in bidform.cleaned_data and bidform.cleaned_data['bid']): bid = bidform.cleaned_data['bid'] if bid.allowuseroptions: # unfortunately, you can't use get_or_create when using a non-atomic transaction # this does technically introduce a race condition, I'm just going to hope that two people don't # suggest the same option at the exact same time # also, I want to do case-insensitive comparison on the name try: bid = models.Bid.objects.get( event=bid.event, speedrun=bid.speedrun, name__iexact=bidform. cleaned_data['customoptionname'], parent=bid, ) except models.Bid.DoesNotExist: bid = models.Bid.objects.create( event=bid.event, speedrun=bid.speedrun, name=bidform. cleaned_data['customoptionname'], parent=bid, state='PENDING', istarget=True, ) donation.bids.add( models.DonationBid( bid=bid, amount=Decimal( bidform.cleaned_data['amount']), ), bulk=False, ) donation.full_clean() donation.save() paypal_dict = { 'amount': str(donation.amount), 'cmd': '_donations', 'business': donation.event.paypalemail, 'image_url': donation.event.paypalimgurl, 'item_name': donation.event.receivername, 'notify_url': request.build_absolute_uri(reverse('tracker:ipn')), 'return': request.build_absolute_uri( reverse('tracker:paypal_return')), 'cancel_return': request.build_absolute_uri( reverse('tracker:paypal_cancel')), 'custom': str(donation.id) + ':' + donation.domainId, 'currency_code': donation.event.paypalcurrency, 'no_shipping': 0, } # Create the form instance form = PayPalPaymentsForm(button_type='donate', initial=paypal_dict) context = {'event': donation.event, 'form': form} return ( views_common.tracker_response( request, 'tracker/paypal_redirect.html', context), None, ) else: bidsform = forms.DonationBidFormSet(amount=Decimal('0.00'), data=request.POST, prefix=bidsFormPrefix) bidsform.is_valid() else: steamid = request.session.get('uid', None) donation_total = sum( models.Donation.objects.filter( steamid=steamid, transactionstate='COMPLETED', event=event).values_list('amount', flat=True)) if steamid else None request.session['steam_donation_total'] = str(donation_total) commentform = forms.DonationEntryForm(event=event) bidsform = forms.DonationBidFormSet(amount=Decimal('0.00'), prefix=bidsFormPrefix) return commentform, bidsform