def make_check_donation(request): """A page for admins to use to input check donations manually.""" if request.method == "POST": data = request.POST.copy() data.update({ "payment_provider": PROVIDERS.CHECK, "amount": "other", }) donation_form = DonationForm(data) # Get the user, if we can. Else, set up the form to create a new user. try: email = request.POST.get("email").strip() user = User.objects.get(email__iexact=email) except User.DoesNotExist: user = None user_form = UserForm(request.POST) profile_form = ProfileForm(request.POST) else: user_form = UserForm(request.POST, instance=user) profile_form = ProfileForm(request.POST, instance=user.profile) if all([ donation_form.is_valid(), user_form.is_valid(), profile_form.is_valid(), ]): cd_user_form = user_form.cleaned_data cd_profile_form = profile_form.cleaned_data if user is not None: user = user_form.save() profile_form.save() else: user, profile = create_stub_account(cd_user_form, cd_profile_form) user.save() profile.save() d = donation_form.save(commit=False) d.status = Donation.PROCESSED d.donor = user d.save() if user.email: send_thank_you_email(d, PAYMENT_TYPES.DONATION) return HttpResponseRedirect(reverse("donate_complete")) else: donation_form = DonationForm() user_form = UserForm() profile_form = ProfileForm() return render( request, "check_donation.html", { "donation_form": donation_form, "profile_form": profile_form, "user_form": user_form, "private": True, }, )
def make_check_donation(request): """A page for admins to use to input check donations manually.""" if request.method == 'POST': data = request.POST.copy() data.update({ 'payment_provider': PROVIDERS.CHECK, 'amount': 'other', }) donation_form = DonationForm(data) # Get the user, if we can. Else, set up the form to create a new user. try: email = request.POST.get('email').strip() user = User.objects.get(email__iexact=email) except User.DoesNotExist: user = None user_form = UserForm(request.POST) profile_form = ProfileForm(request.POST) else: user_form = UserForm(request.POST, instance=user) profile_form = ProfileForm(request.POST, instance=user.profile) if all([ donation_form.is_valid(), user_form.is_valid(), profile_form.is_valid() ]): cd_user_form = user_form.cleaned_data cd_profile_form = profile_form.cleaned_data if user is not None: user = user_form.save() profile_form.save() else: user, profile = create_stub_account(cd_user_form, cd_profile_form) user.save() profile.save() d = donation_form.save(commit=False) d.status = Donation.PROCESSED d.donor = user d.save() if user.email: send_thank_you_email(d) return HttpResponseRedirect(reverse('check_complete')) else: donation_form = DonationForm() user_form = UserForm() profile_form = ProfileForm() return render( request, 'check_donation.html', { 'donation_form': donation_form, 'profile_form': profile_form, 'user_form': user_form, 'private': True, })
def donate(request): """Load the donate page or process a submitted donation. This page has several branches. The logic is as follows: if GET: --> Load the page elif POST: if user is anonymous: if email address on record as a stub account: --> Use it. elif new email address or a non-stub account: --> We cannot allow anonymous people to update real accounts, or this is a new email address, so create a new stub account. elif user is logged in: --> associate with account. We now have an account. Process the payment and associate it. """ message = None if request.method == 'POST': donation_form = DonationForm(request.POST) if request.user.is_anonymous(): # Either this is a new account, a stubbed one, or a user that's # simply not logged into their account try: stub_account = User.objects.filter( profile__stub_account=True).get( email__iexact=request.POST.get('email')) except User.DoesNotExist: # Either a regular account or an email address we've never # seen before. Create a new user from the POST data. stub_account = False user_form = UserForm(request.POST) profile_form = ProfileForm(request.POST) else: # We use the stub account and anonymous users even are allowed # to update it. This is OK, because we don't care too much # about the accuracy of this data. Later if/when this becomes # a real account, anonymous users won't be able to update this # information -- that's what matters. user_form = UserForm(request.POST, instance=stub_account) profile_form = ProfileForm(request.POST, instance=stub_account.profile) else: user_form = UserForm(request.POST, instance=request.user) profile_form = ProfileForm(request.POST, instance=request.user.profile) if all([ donation_form.is_valid(), user_form.is_valid(), profile_form.is_valid() ]): # Process the data in form.cleaned_data cd_donation_form = donation_form.cleaned_data cd_user_form = user_form.cleaned_data cd_profile_form = profile_form.cleaned_data stripe_token = request.POST.get('stripeToken') frequency = request.POST.get('frequency') # Route the payment to a payment provider try: if frequency == 'once': response = route_and_process_donation( cd_donation_form, cd_user_form, {'card': stripe_token}) elif frequency == 'monthly': customer = create_stripe_customer(stripe_token, cd_user_form['email']) response = route_and_process_donation( cd_donation_form, cd_user_form, { 'customer': customer.id, 'metadata': { 'recurring': True } }, ) except PaymentFailureException as e: logger.critical("Payment failed. Message was: %s", e.message) message = e.message response = {'status': 'Failed'} else: logger.info("Payment routed with response: %s", response) if response['status'] == Donation.AWAITING_PAYMENT: if request.user.is_anonymous() and not stub_account: # Create a stub account with an unusable password user, profile = create_stub_account( cd_user_form, cd_profile_form) user.save() profile.save() else: # Logged in user or an existing stub account. user = user_form.save() profile_form.save() donation = donation_form.save(commit=False) donation.status = response['status'] donation.payment_id = response['payment_id'] # Will only work for Paypal: donation.transaction_id = response.get('transaction_id') donation.donor = user donation.save() if frequency == 'monthly': add_monthly_donations(cd_donation_form, user, customer) return HttpResponseRedirect(response['redirect']) else: # Loading the page... try: donation_form = DonationForm( initial={'referrer': request.GET.get('referrer')}) user_form = UserForm( initial={ 'first_name': request.user.first_name, 'last_name': request.user.last_name, 'email': request.user.email, }) up = request.user.profile profile_form = ProfileForm( initial={ 'address1': up.address1, 'address2': up.address2, 'city': up.city, 'state': up.state, 'zip_code': up.zip_code, 'wants_newsletter': up.wants_newsletter }) except AttributeError: # for anonymous users, who lack profile info user_form = UserForm() profile_form = ProfileForm() return render( request, 'donate.html', { 'donation_form': donation_form, 'user_form': user_form, 'profile_form': profile_form, 'private': False, 'message': message, 'stripe_public_key': settings.STRIPE_PUBLIC_KEY })
def make_payment_page_context(request: HttpRequest, ) -> PaymentContext: """Load the donate page or process a submitted donation. This page has several branches. The logic is as follows: if GET: --> Load the page elif POST: if user is anonymous: if email address on record as a stub account: --> Use it. elif new email address or a non-stub account: --> We cannot allow anonymous people to update real accounts, or this is a new email address, so create a new stub account. elif user is logged in: --> associate with account. We now have an account. Process the payment and associate it. """ stub_account = False if request.method == "POST": donation_form = DonationForm(request.POST) if request.user.is_anonymous: # Either this is a new account, a stubbed one, or a user that's # simply not logged into their account try: stub_account = User.objects.filter( profile__stub_account=True).get( email__iexact=request.POST.get("email")) except User.DoesNotExist: # Either a regular account or an email address we've never # seen before. Create a new user from the POST data. user_form = UserForm(request.POST) profile_form = ProfileForm(request.POST) else: # We use the stub account and anonymous users even are allowed # to update it. This is OK, because we don't care too much # about the accuracy of this data. Later if/when this becomes # a real account, anonymous users won't be able to update this # information -- that's what matters. user_form = UserForm(request.POST, instance=stub_account) profile_form = ProfileForm(request.POST, instance=stub_account.profile) else: user_form = UserForm(request.POST, instance=request.user) profile_form = ProfileForm(request.POST, instance=request.user.profile) else: # Loading the page... donation_form = DonationForm( initial={ "referrer": request.GET.get("referrer"), "reference": request.GET.get("reference"), "amount": request.GET.get("amount"), "amount_other": request.GET.get("amount_other"), }) try: user_form = UserForm( initial={ "first_name": request.user.first_name, "last_name": request.user.last_name, "email": request.user.email, }) up = request.user.profile profile_form = ProfileForm( initial={ "address1": up.address1, "address2": up.address2, "city": up.city, "state": up.state, "zip_code": up.zip_code, "wants_newsletter": up.wants_newsletter, }) except AttributeError: # for anonymous users, who lack profile info user_form = UserForm() profile_form = ProfileForm() return { "donation_form": donation_form, "user_form": user_form, "profile_form": profile_form, "stripe_public_key": settings.STRIPE_PUBLIC_KEY, "stub_account": stub_account, }