[1] SubstanceAdmin.change_view()
def change_view(self, request, object_id, form_url='', extra_context=None):
"""
self = SubstanceAdmin
request = wsgi request object
object_id = substance
form_url = no idea!
extra_context = dict of apps, models, admin_urls and permissions
sm2mi stands for substance m2m ingredient. Ingredients are substances in
a many-to-many relationship with another substance (ie a mixture). The
through table is called Substance_Ingredients
"""
ingredients = Substance_Ingredients.objects.filter(substance_id=object_id)
subscription = None
for sm2mi in ingredients:
payable, fee_type = sm2mi.fee_payable() # eg., True, PAID_DATA
if payable:
subscription = billing_subscribe(sm2mi, fee_type)
if subscription: # we need to collect money for the owner
self.change_form_template = 'payment.html'
context = billing_collect_context(
sm2mi,
subscription,
)
# get everything into the payment_view context
if not extra_context:
extra_context = dict()
extra_context.update(self.admin_site.each_context(request))
extra_context.update(context)
self.admin_site.admin_view(
# now call the Stripe mechanism
billing_payment_view(
request,
sm2mi,
subscription,
context=extra_context,
)
)
# only one sm2mi at a time
break
return super(SubstanceAdmin, self).change_view(
request, object_id, form_url, extra_context
)
[2] billing_payment_view()
@ensure_csrf_cookie
def payment_view(request, sm2mi=None, subscription=None, context=None):
display_message = ''
display_insert = ''
email_message = ''
subscription_message = ''
subscription_insert = ''
charge = None
context = context or {}
templt = 'payment.html'
form = PaymentForm()
if request.method == "POST":
resp = dict(request.POST)
# data has been submitted to Stripe via Stripe js
# stripe submits the js form which comes back without identifying args
form = PaymentForm(request.POST)
if form.is_valid():
go_back = '/admin/substance/substance/'
try:
token = form.cleaned_data['stripeToken']
if token:
email = form.cleaned_data['stripeEmail']
sm2mi_id = form.cleaned_data['sm2mi_id']
if sm2mi_id and sm2mi is None:
sm2mi = Substance_Ingredients.objects.get(pk=int(sm2mi_id))
subscription_id = form.cleaned_data['subscription_id']
if subscription_id and subscription is None:
subscription = Subscription.objects.get(pk=int(subscription_id))
if sm2mi and subscription:
ingredient = sm2mi.ingredient
cents = subscription.get_cents()
fee_total = subscription.calc_fee(total=True) # gst in
charge = stripe.Charge.create(
amount=int(float(fee_total) * cents),
currency=subscription.fee_currency,
description='{0}'.format(subscription.ingredient.name),
source=token,
)
if charge:
go_back = '/admin/substance/substance/%s/' % sm2mi.substance.id
subscription.token = token # see above
try:
with transaction.atomic():
subscription.save()
except Exception:
raise
# transaction is done now make a receipt
amount_paid = charge['amount']
if cents > 1: # cents may be zero eg', JPY
amount_paid = round(charge['amount'] / cents, 2)
receipt = Receipt.objects.create(
licensee=sm2mi.substance.division.company,
ingredient=ingredient,
currency=subscription.fee_currency,
amount_paid=amount_paid,
charge=charge,
)
receipt.save() # defaults need all methods to execute
# make a received message for display and emailing
para = '<p>'
endpara = '</p>'
strong = '<strong>'
endstrong = '</strong>'
display_message = '<p>Thank you for your {0} {1}{2} '\
'payment to {3} for <strong>{4}</strong></p>'.format(
subscription.fee_currency,
subscription.fee_symbol,
amount_paid,
settings.BRANDING,
ingredient.name.capitalize(),
)
display_insert = '<p>A receipt will be emailed to you '\
'shortly</p>'
subscription_message = '<p>You are now '\
'subscribed to {0} until 30 September. You may include '\
'it in as many mixtures as desired.</p>'.format(
ingredient.name.capitalize(),
)
subscription_insert = '<p>If you have difficulty '\
'accessing <a href="{0}">{1}</a> or you have any '\
'questions please get in touch via {2}. Easy questions '\
'might have an answer on the <a href="https://{3}/user-'\
'docs/sharing/">sharing page</a>.</p>'.format(
ingredient.get_absolute_url(),
ingredient.name.capitalize(),
settings.MANAGERS[0][1],
settings.WEBSITE,
)
email_message = '{0}{1}{2}'.format(
display_message,
'\n',
subscription_message,
).replace(
para, ''
).replace(
endpara, '\n'
).replace(
strong, '*'
).replace(
endstrong, '*'
)
display_message = '{0}{1}{2}{3}'.format(
display_message,
display_insert,
subscription_message,
subscription_insert,
)
from_address = get_admin_email(full=True)
to_address = [charge['source']['name']]
subject = 'Subscription receipt for {0}'.format(
ingredient.name.capitalize()
)
try:
send_mail(
subject,
email_message,
from_address,
to_address,
fail_silently=False,
)
except Exception as err:
print('\n315 billing.views %s' % err)
pass
context['sm2mi'] = sm2mi
context['receipt'] = receipt
context['subscription'] = subscription
context['message'] = mark_safe(display_message)
#context['link'] = sm2mi.substance.get_substance_url()
context['link'] = go_back
return success_view(request, context)
else:
raise Exception('Gateway error')
except Exception as err:
err = '%s' % err
if 'cannot use a Stripe token' in err:
backto = ''
if sm2mi:
backto = '<p><a href="{0}">Back to {1}</a>'\
'</p>'.format(
go_back,
sm2mi.substance.name.capitalize()
)
display_message = '<p>Cannot process the same payment '\
'twice.</p><p>If an emailed receipt is not received at the '\
'address just specified in the payment popup please get in '\
'touch with <em>{0}</em> to ascertain whether payment was '\
'successful. Please copy and paste the token below as a '\
'reference.</p><p>{1}</p><p>{2}<p>'.format(
get_manager_email(),
token or 'No token at this point (375)',
backto
)
else:
display_message = '{0}. Please report this error message to '\
'{1}'.format(err, get_admin_email())
context['message'] = mark_safe(display_message)
# report failure to the card payer
form.add_error(None, '%s' % err)
return success_view(request, context)
context['form'] = form
return render(
request=request,
template_name=templt,
context=context
)
[3] PaymentForm
class PaymentForm(forms.Form):
sm2mi_id = forms.CharField(widget=forms.HiddenInput, required=False)
ingredient_id = forms.CharField(widget=forms.HiddenInput, required=False)
subscription_id = forms.CharField(widget=forms.HiddenInput, required=False)
stripeToken = forms.CharField(widget=forms.HiddenInput, required=False)
stripeEmail = forms.CharField(widget=forms.HiddenInput, required=False)
stripeBillingName = forms.CharField(widget=forms.HiddenInput, required=False)
stripeBillingAddressLine1 = forms.CharField(widget=forms.HiddenInput, required=False)
stripeBillingAddressZip = forms.CharField(widget=forms.HiddenInput, required=False)
stripeBillingAddressState = forms.CharField(widget=forms.HiddenInput, required=False)
stripeBillingAddressCity = forms.CharField(widget=forms.HiddenInput, required=False)
stripeBillingAddressCountry = forms.CharField(widget=forms.HiddenInput, required=False)
[4] payment.html
{% extends "admin/base_site.html" %}
{% load admin_urls %}
{% load i18n %}
{% load common_tags %}
{% block title %}{{ original }}{% endblock %}
{% block content %}
{% if subscription %}
<div class="payment">
<p>{{ prepay_message }}</p>
<p>Please proceed to payment.</p>
<blockquote><strong>
We do not store your payment detail here. Our PCI DSS compliant gateway
service provider interfaces your card directly with your bank. Links to
their terms and privacy policy will be visible when you click the <em>Pay
with Card</em> button. See also our own privacy policy (link above).
</strong> (PCI DSS = Payment Card Industry Data Security Standard)
</blockquote>
<p> </p>
<form action="payment" method="POST">
{% csrf_token %}
{% if form.errors or form.non_field_errors %}
{{ form.errors }}
{{ form.non_field_errors }}
{% endif %}
{% for field in form %}
{% if field.name == "sm2mi_id" %}
<input type="hidden" name="sm2mi_id" id="id_sm2mi_id" value="{{ sm2mi.id }}" />
{% elif field.name == "ingredient_id" %}
<input type="hidden" name="ingredient_id" id="id_ingredient_id" value="{{ ingredient.id }}" />
{% elif field.name == "subscription_id" %}
<input type="hidden" name="subscription_id" id="id_subscription_id" value="{{ subscription.id }}" />
{% else %}
{{ field }}
{% endif %}
{% endfor %}
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="{{ data_key }}"
data-amount="{{ data_amount }}"
data-name="{{ data_name }}"
data-description="{{ data_description }}"
data-image="{{ data_image }}"
data-locale="{{ data_locale }}"
data-currency="{{ data_currency | lower}}"
data-zip-code="true"
data-allow-remember-me="true"
data-panel-label="Pay">
</script>
</form>
</div>
{% endif %}
{{ block.super }}
{% endblock %}
[5] billing_success_view
def success_view(request, context=None):
""" launched after a Stripe token is received by PaymentForm
context is passed in by payment_view and has context['message']
"""
if context is None:
context = dict()
context['message'] = 'Sorry - payment details cannot be reproduced'
if 'Thank you for your' in context['message']:
pass
return render(
request=request,
template_name='success.html',
context=context,
)
[6] success.html
{% extends "admin/base_site.html" %}
{% load admin_urls %}
{% load i18n %}
{% load common_tags %}
{% block title %}{{ original }}{% endblock %}
{% block content %}
<div id="container">
<div id="content" class="colM">
{% if message %}{{ message }}{% endif %}
{% if link %}
<p>Please do not refresh this page but rather click the 'Home' link above or
<a href="{{ link }}">go back to {{ sm2mi.substance.name }}</a></p>
{% endif %}
</div>
</div>
{{ block.super }}
{% endblock %}
Python 3.6, Django 1.11.20, dev
server on Windows 10.
Haven't been *able* to get it
working yet on Ubuntu 16.04 with Python 2.7 and haven't tried
it yet on Python 2.7 on the dev server.
Getting Python 3.x running with
Apache2 on Ubuntu is non-trivial due to co-existence with Trac
(2.7 only) which also requires my SVN to cohabit on the same
machine.
Django Admin is customizable to an extent, but at a certain point those customizations can cost you more time than they save, and it makes more sense to build your business logic in a standard app/view. Without digging into your code, my spidey sense tells me your app is at that point - stop trying to do it in the admin and you'll have all the control you need or want../s
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/4cf8ad94-da46-35e1-ba5a-d168de645561%40dewhirst.com.au.
For more options, visit https://groups.google.com/d/optout.