confirmation emails to buyers
This commit is contained in:
@@ -2,6 +2,20 @@ import braintree
|
|||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
import django_rq
|
||||||
|
queue = django_rq.get_queue('default')
|
||||||
|
queuelow = django_rq.get_queue('low')
|
||||||
|
queuehigh = django_rq.get_queue('low')
|
||||||
|
|
||||||
|
from rowers.utils import myqueue
|
||||||
|
from rowers.tasks import (
|
||||||
|
handle_send_email_transaction,
|
||||||
|
handle_send_email_subscription_update,
|
||||||
|
handle_send_email_subscription_create,
|
||||||
|
handle_send_email_failed_cancel,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
from rowsandall_app.settings import (
|
from rowsandall_app.settings import (
|
||||||
BRAINTREE_MERCHANT_ID,BRAINTREE_PUBLIC_KEY,BRAINTREE_PRIVATE_KEY
|
BRAINTREE_MERCHANT_ID,BRAINTREE_PUBLIC_KEY,BRAINTREE_PRIVATE_KEY
|
||||||
)
|
)
|
||||||
@@ -68,7 +82,7 @@ def get_plans_costs():
|
|||||||
def make_payment(rower,data):
|
def make_payment(rower,data):
|
||||||
nonce_from_the_client = data['payment_method_nonce']
|
nonce_from_the_client = data['payment_method_nonce']
|
||||||
amount = data['amount']
|
amount = data['amount']
|
||||||
amount = str(amount)
|
amount = '{amount:.f2}'.format(amount=amount)
|
||||||
|
|
||||||
result = gateway.transaction.sale({
|
result = gateway.transaction.sale({
|
||||||
"amount": amount,
|
"amount": amount,
|
||||||
@@ -80,6 +94,14 @@ def make_payment(rower,data):
|
|||||||
if result.is_success:
|
if result.is_success:
|
||||||
transaction = result.transaction
|
transaction = result.transaction
|
||||||
amount = transaction.amount
|
amount = transaction.amount
|
||||||
|
name = '{f} {l}'.format(
|
||||||
|
f = rower.user.first_name,
|
||||||
|
l = rower.user.last_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
job = myqueue(queuehigh,handle_send_email_transaction,
|
||||||
|
name, rower.user.email, amount)
|
||||||
|
|
||||||
return amount
|
return amount
|
||||||
else:
|
else:
|
||||||
@@ -91,7 +113,6 @@ def update_subscription(rower,data):
|
|||||||
nonce_from_the_client = data['payment_method_nonce']
|
nonce_from_the_client = data['payment_method_nonce']
|
||||||
amount = data['amount']
|
amount = data['amount']
|
||||||
amount = '{amount:.2f}'.format(amount=amount)
|
amount = '{amount:.2f}'.format(amount=amount)
|
||||||
print amount,'aap'
|
|
||||||
|
|
||||||
gatewaydata = {
|
gatewaydata = {
|
||||||
"price": amount,
|
"price": amount,
|
||||||
@@ -122,6 +143,29 @@ def update_subscription(rower,data):
|
|||||||
rower.rowerplan = plan.shortname
|
rower.rowerplan = plan.shortname
|
||||||
rower.subscription_id = result.subscription.id
|
rower.subscription_id = result.subscription.id
|
||||||
rower.save()
|
rower.save()
|
||||||
|
name = '{f} {l}'.format(
|
||||||
|
f = rower.user.first_name,
|
||||||
|
l = rower.user.last_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
transactions = result.subscription.transactions
|
||||||
|
|
||||||
|
if transactions:
|
||||||
|
amount = transactions[0].amount
|
||||||
|
else:
|
||||||
|
amount = 0
|
||||||
|
|
||||||
|
|
||||||
|
job = myqueue(queuehigh,
|
||||||
|
handle_send_email_subscription_update,
|
||||||
|
name, rower.user.email,
|
||||||
|
plan.name,
|
||||||
|
plan.paymenttype == 'recurring',
|
||||||
|
plan.price,
|
||||||
|
amount,
|
||||||
|
result.subscription.billing_period_end_date.strftime('%Y-%m-%d'))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@@ -153,13 +197,31 @@ def create_subscription(rower,data):
|
|||||||
|
|
||||||
if result.is_success:
|
if result.is_success:
|
||||||
rower.paidplan = plan
|
rower.paidplan = plan
|
||||||
rower.planexpires = timezone.now()+datetime.timedelta(days=365)
|
rower.planexpires = result.subscription.billing_period_end_date
|
||||||
rower.teamplanexpires = timezone.now()+datetime.timedelta(days=365)
|
rower.teamplanexpires = result.subscription.billing_period_end_date
|
||||||
rower.clubsize = plan.clubsize
|
rower.clubsize = plan.clubsize
|
||||||
rower.paymenttype = plan.paymenttype
|
rower.paymenttype = plan.paymenttype
|
||||||
rower.rowerplan = plan.shortname
|
rower.rowerplan = plan.shortname
|
||||||
rower.subscription_id = result.subscription.id
|
rower.subscription_id = result.subscription.id
|
||||||
rower.save()
|
rower.save()
|
||||||
|
name = '{f} {l}'.format(
|
||||||
|
f = rower.user.first_name,
|
||||||
|
l = rower.user.last_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
recurring = plan.paymenttype == 'recurring',
|
||||||
|
|
||||||
|
job = myqueue(
|
||||||
|
queuehigh,
|
||||||
|
handle_send_email_subscription_create,
|
||||||
|
name, rower.user.email,
|
||||||
|
plan.name,
|
||||||
|
recurring,
|
||||||
|
plan.price,
|
||||||
|
plan.price,
|
||||||
|
result.subscription.billing_period_end_date.strftime('%Y-%m-%d')
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@@ -174,7 +236,15 @@ def cancel_subscription(rower,id):
|
|||||||
result = gateway.subscription.cancel(id)
|
result = gateway.subscription.cancel(id)
|
||||||
messages.append("Subscription canceled")
|
messages.append("Subscription canceled")
|
||||||
except:
|
except:
|
||||||
errormessages.append("We could not find the subscription record in our customer database")
|
errormessages.append("We could not find the subscription record in our customer database. We have notified the site owner, who will contact you.")
|
||||||
|
|
||||||
|
name = '{f} {l}'.format(f = rower.user.first_name, l = rower.user.last_name)
|
||||||
|
|
||||||
|
|
||||||
|
job = myqueue(queuehigh,
|
||||||
|
handle_send_email_failed_cancel,
|
||||||
|
name, rower.user.email,rower.user.username,id)
|
||||||
|
|
||||||
return False, themessages, errormessages
|
return False, themessages, errormessages
|
||||||
|
|
||||||
rower.paidplan = None
|
rower.paidplan = None
|
||||||
|
|||||||
@@ -732,7 +732,10 @@ class PlanSelectForm(forms.Form):
|
|||||||
"price","clubsize","shortname"
|
"price","clubsize","shortname"
|
||||||
)
|
)
|
||||||
if rower:
|
if rower:
|
||||||
amount = rower.paidplan.price
|
try:
|
||||||
|
amount = rower.paidplan.price
|
||||||
|
except AttributeError:
|
||||||
|
amount = 0
|
||||||
self.fields['plan'].queryset = PaidPlan.objects.filter(
|
self.fields['plan'].queryset = PaidPlan.objects.filter(
|
||||||
paymentprocessor=rower.paymentprocessor
|
paymentprocessor=rower.paymentprocessor
|
||||||
).exclude(
|
).exclude(
|
||||||
|
|||||||
117
rowers/tasks.py
117
rowers/tasks.py
@@ -739,7 +739,122 @@ def handle_updatedps(useremail, workoutids, debug=False,**kwargs):
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
# send email when a breakthrough workout is uploaded
|
@app.task
|
||||||
|
def handle_send_email_transaction(
|
||||||
|
username, useremail, amount, **kwargs):
|
||||||
|
|
||||||
|
if 'debug' in kwargs:
|
||||||
|
debug = kwargs['debug']
|
||||||
|
else:
|
||||||
|
debug = True
|
||||||
|
|
||||||
|
subject = "Rowsandall Payment Confirmation"
|
||||||
|
|
||||||
|
from_email = 'Rowsandall <admin@rowsandall.com>'
|
||||||
|
|
||||||
|
d = {
|
||||||
|
'name': username,
|
||||||
|
'siteurl': siteurl,
|
||||||
|
'amount': amount
|
||||||
|
}
|
||||||
|
|
||||||
|
res = send_template_email(from_email,[useremail],
|
||||||
|
subject,
|
||||||
|
'paymentconfirmationemail.html',
|
||||||
|
d, **kwargs)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
|
@app.task
|
||||||
|
def handle_send_email_failed_cancel(
|
||||||
|
name, email, username, id, **kwargs):
|
||||||
|
|
||||||
|
if 'debug' in kwargs:
|
||||||
|
debug = kwargs['debug']
|
||||||
|
else:
|
||||||
|
debug = True
|
||||||
|
|
||||||
|
subject = "Rowsandall Subscription Cancellation Error"
|
||||||
|
|
||||||
|
from_email = 'Rowsandall <admin@rowsandall.com>'
|
||||||
|
|
||||||
|
d = {
|
||||||
|
'name': name,
|
||||||
|
'siteurl': siteurl,
|
||||||
|
'email': email,
|
||||||
|
'username': username,
|
||||||
|
'id': id,
|
||||||
|
}
|
||||||
|
|
||||||
|
res = send_template_email(from_email,["support@rowsandall.com"],
|
||||||
|
subject,
|
||||||
|
'cancel_subscription_fail_email.html',
|
||||||
|
d, **kwargs)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
@app.task
|
||||||
|
def handle_send_email_subscription_update(
|
||||||
|
username, useremail, planname, recurring, price, amount,
|
||||||
|
end_of_billing_period, **kwargs):
|
||||||
|
|
||||||
|
if 'debug' in kwargs:
|
||||||
|
debug = kwargs['debug']
|
||||||
|
else:
|
||||||
|
debug = True
|
||||||
|
|
||||||
|
subject = "Rowsandall Payment Confirmation"
|
||||||
|
|
||||||
|
from_email = 'Rowsandall <admin@rowsandall.com>'
|
||||||
|
|
||||||
|
d = {
|
||||||
|
'name': username,
|
||||||
|
'siteurl': siteurl,
|
||||||
|
'amount': amount,
|
||||||
|
'price':price,
|
||||||
|
'planname': planname,
|
||||||
|
'recurring': recurring,
|
||||||
|
'end_of_billing_period': end_of_billing_period,
|
||||||
|
}
|
||||||
|
|
||||||
|
res = send_template_email(from_email,[useremail],
|
||||||
|
subject,
|
||||||
|
'subscription_update_email.html',
|
||||||
|
d, **kwargs)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
|
@app.task
|
||||||
|
def handle_send_email_subscription_create(
|
||||||
|
username, useremail, planname, recurring, price, amount,
|
||||||
|
end_of_billing_period, **kwargs):
|
||||||
|
|
||||||
|
if 'debug' in kwargs:
|
||||||
|
debug = kwargs['debug']
|
||||||
|
else:
|
||||||
|
debug = True
|
||||||
|
|
||||||
|
subject = "Rowsandall Payment Confirmation"
|
||||||
|
|
||||||
|
from_email = 'Rowsandall <admin@rowsandall.com>'
|
||||||
|
|
||||||
|
d = {
|
||||||
|
'name': username,
|
||||||
|
'siteurl': siteurl,
|
||||||
|
'amount': amount,
|
||||||
|
'price':price,
|
||||||
|
'planname': planname,
|
||||||
|
'end_of_billing_period': end_of_billing_period,
|
||||||
|
'recurring': recurring,
|
||||||
|
}
|
||||||
|
|
||||||
|
res = send_template_email(from_email,[useremail],
|
||||||
|
subject,
|
||||||
|
'subscription_create_email.html',
|
||||||
|
d, **kwargs)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
def handle_sendemail_raceregistration(
|
def handle_sendemail_raceregistration(
|
||||||
|
|||||||
21
rowers/templates/cancel_subscription_fail_email.html
Normal file
21
rowers/templates/cancel_subscription_fail_email.html
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>
|
||||||
|
User {{ name }} tried to cancel his subscription with id "{{ id }}" on {{ siteurl }} but failed.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
User name: {{ username }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
User email: {{ email }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
19
rowers/templates/paymentconfirmationemail.html
Normal file
19
rowers/templates/paymentconfirmationemail.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Thank you. We have received the payment of € {{ amount }} for Rowsandall related services.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please contact our customer service by replying to this email if you have any further
|
||||||
|
questions regarding the payment.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</table>
|
</table>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% if rower.rowerplan != 'coach' and rower.user == user %}
|
{% if rower.clubsize < 100 and rower.user == user %}
|
||||||
<p>
|
<p>
|
||||||
<a href="/rowers/paidplans">Upgrade</a>
|
<a href="/rowers/paidplans">Upgrade</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
60
rowers/templates/subscription_create_email.html
Normal file
60
rowers/templates/subscription_create_email.html
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Thank you. We have received the payment of € {{ amount }} for your new
|
||||||
|
subscription to the Rowsandall paid plan "{{ planname }}".
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% if recurring %}
|
||||||
|
<p>
|
||||||
|
Your next charge is due on {{ end_of_billing_period }}. We will charge your {{ paymentmethod }}
|
||||||
|
on that date.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The subscription will keep running until you change or stop it. At any point in time you
|
||||||
|
can change the automatically renewing subscription to a "one year only" subscription through
|
||||||
|
<a href="{{ siteurl}}/rowers/upgrade/">the upgrade page</a>. On this page, you can also
|
||||||
|
upgrade your subscription.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<p>
|
||||||
|
This one year subscription will automatically end on {{ end_of_billing_period }}. You can
|
||||||
|
renew your subscription after that.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
At any point in time, you can change your subscription to an automatically renewing subscription.
|
||||||
|
You can do this on <a href="{{ siteurl}}/rowers/upgrade/">the upgrade page</a>.
|
||||||
|
Here, you can also upgrade your subscription.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Upgrades in the middle of a billing cycle will be charged pro-rated. For the current billing
|
||||||
|
cycle, you will only be charged for the price difference for the remaining fraction of the
|
||||||
|
billing cycle. If you downgrade to a lower cost subscription, the pro-rated difference will be
|
||||||
|
used as a credit, lowering the amount charged on the next billing cycle.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You can stop the subscription through
|
||||||
|
<a href="{{ siteurl }}/rowers/me/cancelsubscriptions">the subscription management page</a>. The
|
||||||
|
subscription will be stopped immediately without a refund.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please contact our customer service by replying to this email if you have any further
|
||||||
|
questions regarding your subscription.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
63
rowers/templates/subscription_update_email.html
Normal file
63
rowers/templates/subscription_update_email.html
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
{% extends "emailbase.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>Dear <strong>{{ name }}</strong>,</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Thank you. We have received the payment of € {{ amount }} for
|
||||||
|
your updated Rowsandall subscription.
|
||||||
|
You are now on the Rowsandall paid plan "{{ planname }}".
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% if recurring %}
|
||||||
|
<p>
|
||||||
|
The subscription cost is €{{ price }} per year.
|
||||||
|
Your next charge is due on {{ end_of_billing_period }}. We will charge your {{ paymentmethod }}
|
||||||
|
on that date.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The subscription will keep running until you change or stop it. At any point in time you
|
||||||
|
can change the automatically renewing subscription to a "one year only" subscription through
|
||||||
|
<a href="{{ siteurl}}/rowers/upgrade/">the upgrade page</a>. On this page, you can also
|
||||||
|
upgrade your subscription.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<p>
|
||||||
|
The price of the subscription is €{{ price }}. You have paid €{{ amount }} as a
|
||||||
|
prorated cost of your upgrade.
|
||||||
|
This one year subscription will automatically end on {{ end_of_billing_period }}. You can
|
||||||
|
renew your subscription after that.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
At any point in time, you can change your subscription to an automatically renewing subscription.
|
||||||
|
You can do this on <a href="{{ siteurl}}/rowers/upgrade/">the upgrade page</a>.
|
||||||
|
Here, you can also upgrade your subscription.
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Upgrades in the middle of a billing cycle are charged pro-rated. For the current billing
|
||||||
|
cycle, you have only been charged for the price difference for the remaining fraction of the
|
||||||
|
billing cycle. If you downgraded to a lower cost subscription, the pro-rated difference will be
|
||||||
|
used as a credit, lowering the amount charged on the next billing cycle.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You can stop the subscription through
|
||||||
|
<a href="{{ siteurl }}/rowers/me/cancelsubscriptions">the subscription management page</a>. The
|
||||||
|
subscription will be stopped immediately without a refund.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please contact our customer service by replying to this email if you have any further
|
||||||
|
questions regarding your subscription.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Best Regards, the Rowsandall Team
|
||||||
|
</p>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<th>Payment Type</th><td>{{ plan.paymenttype }}</td>
|
<th>Payment Type</th><td>{{ plan.paymenttype }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Plan Duration</th><td>1 year starting today</td>
|
<th>Billing Cycle</th><td>1 year</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Total</th><td>€ {{ plan.price|currency }}
|
<th>Total</th><td>€ {{ plan.price|currency }}
|
||||||
|
|||||||
@@ -1113,6 +1113,10 @@ def billing_view(request):
|
|||||||
def upgrade_view(request):
|
def upgrade_view(request):
|
||||||
r = getrequestrower(request)
|
r = getrequestrower(request)
|
||||||
|
|
||||||
|
if r.subscription_id is None or r.subscription_id == '':
|
||||||
|
url = reverse(billing_view)
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
billingaddressform = RowerBillingAddressForm(request.POST)
|
billingaddressform = RowerBillingAddressForm(request.POST)
|
||||||
planselectform = PlanSelectForm(request.POST,paymentprocessor='braintree')
|
planselectform = PlanSelectForm(request.POST,paymentprocessor='braintree')
|
||||||
|
|||||||
Reference in New Issue
Block a user