forked from GithubBackups/healthchecks
Added "Supporter" billing plan.
This commit is contained in:
parent
733c589e47
commit
f1880657fd
@ -130,6 +130,10 @@ class Subscription(models.Model):
|
||||
self.plan_name = "Business Plus ($80 / month)"
|
||||
elif plan_id == "Y768":
|
||||
self.plan_name = "Business Plus ($768 / year)"
|
||||
elif plan_id == "S5":
|
||||
self.plan_name = "Supporter ($5 / month)"
|
||||
elif plan_id == "S48":
|
||||
self.plan_name = "Supporter ($48 / year)"
|
||||
|
||||
self.save()
|
||||
|
||||
|
||||
@ -48,6 +48,34 @@ class UpdateSubscriptionTestCase(BaseTestCase):
|
||||
|
||||
self.assertTrue(mock.Subscription.create.called)
|
||||
|
||||
@patch("hc.payments.models.braintree")
|
||||
def test_supporter_works(self, mock):
|
||||
self._setup_mock(mock)
|
||||
|
||||
self.profile.sms_limit = 0
|
||||
self.profile.sms_sent = 1
|
||||
self.profile.save()
|
||||
|
||||
r = self.run_update("S5")
|
||||
self.assertRedirects(r, "/accounts/profile/billing/")
|
||||
|
||||
# Subscription should be filled out:
|
||||
sub = Subscription.objects.get(user=self.alice)
|
||||
self.assertEqual(sub.subscription_id, "t-sub-id")
|
||||
self.assertEqual(sub.plan_id, "S5")
|
||||
self.assertEqual(sub.plan_name, "Supporter ($5 / month)")
|
||||
|
||||
# User's profile should have adjusted limits
|
||||
self.profile.refresh_from_db()
|
||||
self.assertEqual(self.profile.ping_log_limit, 1000)
|
||||
self.assertEqual(self.profile.check_limit, 20)
|
||||
self.assertEqual(self.profile.team_limit, 2)
|
||||
self.assertEqual(self.profile.sms_limit, 5)
|
||||
self.assertEqual(self.profile.sms_sent, 0)
|
||||
|
||||
# braintree.Subscription.cancel should have not been called
|
||||
assert not mock.Subscription.cancel.called
|
||||
|
||||
@patch("hc.payments.models.braintree")
|
||||
def test_yearly_works(self, mock):
|
||||
self._setup_mock(mock)
|
||||
@ -133,7 +161,7 @@ class UpdateSubscriptionTestCase(BaseTestCase):
|
||||
self.assertEqual(self.profile.ping_log_limit, 100)
|
||||
self.assertEqual(self.profile.check_limit, 20)
|
||||
self.assertEqual(self.profile.team_limit, 2)
|
||||
self.assertEqual(self.profile.sms_limit, 0)
|
||||
self.assertEqual(self.profile.sms_limit, 5)
|
||||
|
||||
self.assertTrue(mock.Subscription.cancel.called)
|
||||
|
||||
|
||||
@ -110,7 +110,7 @@ def update(request):
|
||||
request.session["payment_method_status"] = "success"
|
||||
return redirect("hc-billing")
|
||||
|
||||
if plan_id not in ("", "P20", "P80", "Y192", "Y768"):
|
||||
if plan_id not in ("", "P20", "P80", "Y192", "Y768", "S5", "S48"):
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
# Cancel the previous plan and reset limits:
|
||||
@ -120,7 +120,7 @@ def update(request):
|
||||
profile.ping_log_limit = 100
|
||||
profile.check_limit = 20
|
||||
profile.team_limit = 2
|
||||
profile.sms_limit = 0
|
||||
profile.sms_limit = 5
|
||||
profile.save()
|
||||
|
||||
if plan_id == "":
|
||||
@ -133,17 +133,24 @@ def update(request):
|
||||
|
||||
# Update user's profile
|
||||
profile = request.user.profile
|
||||
if plan_id in ("P20", "Y192"):
|
||||
if plan_id in ("S5", "S48"):
|
||||
profile.check_limit = 20
|
||||
profile.team_limit = 2
|
||||
profile.ping_log_limit = 1000
|
||||
profile.sms_limit = 5
|
||||
profile.sms_sent = 0
|
||||
profile.save()
|
||||
elif plan_id in ("P20", "Y192"):
|
||||
profile.check_limit = 100
|
||||
profile.team_limit = 9
|
||||
profile.ping_log_limit = 1000
|
||||
profile.sms_limit = 50
|
||||
profile.sms_sent = 0
|
||||
profile.save()
|
||||
elif plan_id in ("P80", "Y768"):
|
||||
profile.ping_log_limit = 1000
|
||||
profile.check_limit = 1000
|
||||
profile.team_limit = 500
|
||||
profile.ping_log_limit = 1000
|
||||
profile.sms_limit = 500
|
||||
profile.sms_sent = 0
|
||||
profile.save()
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
@media (min-width: 992px) {
|
||||
#change-billing-plan-modal .modal-dialog, #payment-method-modal .modal-dialog, #please-wait-modal .modal-dialog {
|
||||
width: 850px;
|
||||
width: 900px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@
|
||||
|
||||
#change-billing-plan-modal .plan li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding: 1px 0;
|
||||
}
|
||||
|
||||
#change-billing-plan-modal .text-warning {
|
||||
@ -89,5 +89,5 @@
|
||||
#please-wait-modal .modal-body {
|
||||
text-align: center;
|
||||
padding: 100px;
|
||||
font-size: 18px;
|
||||
}
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
@ -1,26 +1,66 @@
|
||||
.panel-pricing .list-group-item {
|
||||
color: #777777;
|
||||
}
|
||||
.panel-pricing .list-group-item:last-child {
|
||||
border-bottom-right-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
}
|
||||
.panel-pricing .list-group-item:first-child {
|
||||
border-top-right-radius: 0px;
|
||||
border-top-left-radius: 0px;
|
||||
}
|
||||
.panel-pricing .panel-body {
|
||||
font-size: 40px;
|
||||
color: #777777;
|
||||
padding: 20px;
|
||||
margin: 0px;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
#subscription-status form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#pricing-table {
|
||||
}
|
||||
|
||||
|
||||
.panel.plan h1 {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
|
||||
display: inline-block;
|
||||
line-height: 0.9;
|
||||
text-shadow: 0px 1px white, -1px 1px white, 1px 1px white, -1px 0px white;
|
||||
}
|
||||
|
||||
.hobbyist h1 {
|
||||
color: #0a220c;
|
||||
border-bottom: 3px solid #A5D6A7;
|
||||
}
|
||||
|
||||
.supporter h1 {
|
||||
color: #1d190f;
|
||||
border-bottom: 3px solid #FFE082;
|
||||
}
|
||||
|
||||
.business h1 {
|
||||
color: #141c22;
|
||||
border-bottom: 3px solid #90CAF9;
|
||||
}
|
||||
|
||||
.business-plus h1 {
|
||||
color: #221f1e;
|
||||
border-bottom: 3px solid #BCAAA4;
|
||||
}
|
||||
|
||||
.mo {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.plan .btn {
|
||||
font-weight: bold;
|
||||
color: #1ea65a;
|
||||
border-color: #1ea65a;
|
||||
background: #FFF;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
border-radius: 5px;
|
||||
padding: 8px 20px;
|
||||
}
|
||||
|
||||
.plan .btn:hover {
|
||||
color: #fff;
|
||||
background: #22bc66;
|
||||
border-color: #22bc66;
|
||||
}
|
||||
|
||||
.plan .list-group-item:last-child {
|
||||
border-bottom: 0;
|
||||
|
||||
}
|
||||
|
||||
#payment-method-modal .modal-header {
|
||||
border-bottom: 0;
|
||||
}
|
||||
@ -42,10 +82,6 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.mo {
|
||||
font-size: 18px;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
#period-controls {
|
||||
text-align: center;
|
||||
|
||||
@ -32,9 +32,9 @@ $(function () {
|
||||
}
|
||||
|
||||
$("#payment-form-submit").prop("disabled", true);
|
||||
$("#payment-method-modal").modal("show");
|
||||
$("#payment-method-modal").modal("show");
|
||||
|
||||
getToken(function(token) {
|
||||
getToken(function(token) {
|
||||
braintree.dropin.create({
|
||||
authorization: token,
|
||||
container: "#dropin",
|
||||
@ -48,7 +48,7 @@ $(function () {
|
||||
instance.requestPaymentMethod(function (err, payload) {
|
||||
$("#payment-method-modal").modal("hide");
|
||||
$("#please-wait-modal").modal("show");
|
||||
|
||||
|
||||
$("#nonce").val(payload.nonce);
|
||||
$("#update-subscription-form").submit();
|
||||
});
|
||||
@ -76,7 +76,7 @@ $(function () {
|
||||
});
|
||||
|
||||
$("#update-payment-method").click(function() {
|
||||
showPaymentMethodForm($("#old-plan-id").val());
|
||||
showPaymentMethodForm($("#old-plan-id").val());
|
||||
});
|
||||
|
||||
$("#billing-history").load("/accounts/profile/billing/history/");
|
||||
@ -98,6 +98,12 @@ $(function () {
|
||||
updateChangePlanForm();
|
||||
});
|
||||
|
||||
$("#plan-supporter").click(function() {
|
||||
$(".plan").removeClass("selected");
|
||||
$("#plan-supporter").addClass("selected");
|
||||
updateChangePlanForm();
|
||||
});
|
||||
|
||||
$("#plan-business").click(function() {
|
||||
$(".plan").removeClass("selected");
|
||||
$("#plan-business").addClass("selected");
|
||||
@ -116,6 +122,7 @@ $(function () {
|
||||
// "Monthly" is selected: dispplay monthly prices
|
||||
if ($("#billing-monthly").is(":checked")) {
|
||||
var period = "monthly";
|
||||
$("#supporter-price").text("$5");
|
||||
$("#business-price").text("$20");
|
||||
$("#business-plus-price").text("$80");
|
||||
}
|
||||
@ -123,6 +130,7 @@ $(function () {
|
||||
// "Annual" is selected: dispplay annual prices
|
||||
if ($("#billing-annual").is(":checked")) {
|
||||
var period = "annual";
|
||||
$("#supporter-price").text("$4");
|
||||
$("#business-price").text("$16");
|
||||
$("#business-plus-price").text("$64");
|
||||
}
|
||||
@ -132,6 +140,11 @@ $(function () {
|
||||
planId = "";
|
||||
}
|
||||
|
||||
// "Supporter" is selected, set planId
|
||||
if ($("#plan-supporter").hasClass("selected")) {
|
||||
planId = period == "monthly" ? "S5" : "S48";
|
||||
}
|
||||
|
||||
// "Business" is selected, set planId
|
||||
if ($("#plan-business").hasClass("selected")) {
|
||||
planId = period == "monthly" ? "P20" : "Y192";
|
||||
@ -141,7 +154,7 @@ $(function () {
|
||||
if ($("#plan-business-plus").hasClass("selected")) {
|
||||
planId = period == "monthly" ? "P80" : "Y768";
|
||||
}
|
||||
|
||||
|
||||
if (planId == $("#old-plan-id").val()) {
|
||||
$("#change-plan-btn")
|
||||
.attr("disabled", "disabled")
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
$(function () {
|
||||
$("#period-controls :input").change(function() {
|
||||
if (this.value == "monthly") {
|
||||
$("#s-price").text("$20");
|
||||
$("#p-price").text("$80");
|
||||
$("#supporter-price").text("$5");
|
||||
$("#business-price").text("$20");
|
||||
$("#business-plus-price").text("$80");
|
||||
}
|
||||
|
||||
if (this.value == "annual") {
|
||||
$("#s-price").text("$16");
|
||||
$("#p-price").text("$64");
|
||||
$("#supporter-price").text("$4");
|
||||
$("#business-price").text("$16");
|
||||
$("#business-plus-price").text("$64");
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -176,27 +176,43 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div id="plan-hobbyist" class="panel plan {% if sub.plan_id == "" %}selected{% endif %}">
|
||||
<div class="marker">Selected Plan</div>
|
||||
|
||||
<h2>Hobbyist</h2>
|
||||
<ul>
|
||||
<li>Checks: 20</li>
|
||||
<li>Team members: 3</li>
|
||||
<li>Team size: 3</li>
|
||||
<li>Log entries: 100</li>
|
||||
</ul>
|
||||
<h3>Free</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div id="plan-supporter" class="panel plan {% if sub.plan_id == "S5" or sub.plan_id == "S48" %}selected{% endif %}">
|
||||
<div class="marker">Selected Plan</div>
|
||||
|
||||
<h2>Supporter</h2>
|
||||
<ul>
|
||||
<li>Checks: 20</li>
|
||||
<li>Team size: 3</li>
|
||||
<li>Log entries: 1000</li>
|
||||
</ul>
|
||||
<h3>
|
||||
<span id="supporter-price"></span>
|
||||
<small>/ month</small>
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div id="plan-business" class="panel plan {% if sub.plan_id == "P20" or sub.plan_id == "Y192" %}selected{% endif %}">
|
||||
<div class="marker">Selected Plan</div>
|
||||
|
||||
<h2>Business</h2>
|
||||
<ul>
|
||||
<li>Checks: 100</li>
|
||||
<li>Team members: 10</li>
|
||||
<li>Team size: 10</li>
|
||||
<li>Log entries: 1000</li>
|
||||
</ul>
|
||||
<h3>
|
||||
@ -205,14 +221,14 @@
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div id="plan-business-plus" class="panel plan {% if sub.plan_id == "P80" or sub.plan_id == "Y768" %}selected{% endif %}">
|
||||
<div class="marker">Selected Plan</div>
|
||||
|
||||
<h2>Business Plus</h2>
|
||||
<ul>
|
||||
<li>Checks: 1000</li>
|
||||
<li>Team members: Unlimited</li>
|
||||
<li>Team size: Unlim.</li>
|
||||
<li>Log entries: 1000</li>
|
||||
</ul>
|
||||
<h3>
|
||||
@ -508,7 +524,7 @@
|
||||
</div>
|
||||
|
||||
<form id="update-subscription-form" method="post" action="{% url 'hc-update-subscription' %}">
|
||||
{% csrf_token %}
|
||||
{% csrf_token %}
|
||||
<input id="nonce" type="hidden" name="nonce" />
|
||||
<input type="hidden" id="old-plan-id" value="{{ sub.plan_id }}">
|
||||
<input id="plan-id" type="hidden" name="plan_id" />
|
||||
|
||||
@ -69,90 +69,120 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Free -->
|
||||
<div class="col-sm-4 text-center">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body text-center free">
|
||||
<!-- Hobbyist -->
|
||||
<div class="col-sm-3 text-center">
|
||||
<div class="panel panel-default plan hobbyist">
|
||||
<div class="panel-body text-center">
|
||||
<h1>Hobbyist</h1>
|
||||
<h2>$0<span class="mo">/mo</span></h2>
|
||||
<h2>$0 <span class="mo">/ month</span></h2>
|
||||
</div>
|
||||
<ul class="list-group text-center">
|
||||
<li class="list-group-item"><i class="fa fa-check"></i> 20 Checks</li>
|
||||
<li class="list-group-item">3 Team Members</li>
|
||||
<li class="list-group-item">100 Log Entries per Check</li>
|
||||
<li class="list-group-item">API Access</li>
|
||||
<li class="list-group-item">5 SMS {% if enable_whatsapp %}& WhatsApp{% endif %} Alerts per Month</li>
|
||||
<li class="list-group-item"><i class="fa fa-check"></i> 20 checks</li>
|
||||
<li class="list-group-item">3 team members</li>
|
||||
<li class="list-group-item">100 log entries per check</li>
|
||||
<li class="list-group-item">API access</li>
|
||||
<li class="list-group-item">5 SMS {% if enable_whatsapp %}& WhatsApp{% endif %} credits</li>
|
||||
<li class="list-group-item"> </li>
|
||||
</ul>
|
||||
|
||||
{% if not request.user.is_authenticated %}
|
||||
<div class="panel-footer">
|
||||
<a href="#" data-toggle="modal" data-target="#signup-modal" class="btn btn-lg btn-success">Get Started</a>
|
||||
<a href="#" data-toggle="modal" data-target="#signup-modal" class="btn">Sign Up</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- /item -->
|
||||
|
||||
<!-- P5 -->
|
||||
<div class="col-sm-4 text-center">
|
||||
<div class="panel panel-default">
|
||||
<!-- Supporter -->
|
||||
<div class="col-sm-3 text-center">
|
||||
<div class="panel panel-default plan supporter">
|
||||
<div class="panel-body text-center free">
|
||||
<h1>Supporter</h1>
|
||||
<h2>
|
||||
<span id="supporter-price">$5</span>
|
||||
<span class="mo">/ month</span>
|
||||
</h2>
|
||||
</div>
|
||||
<ul class="list-group text-center">
|
||||
<li class="list-group-item"><i class="fa fa-check"></i> 20 checks</li>
|
||||
<li class="list-group-item">3 team members</li>
|
||||
<li class="list-group-item">1000 log entries per check</li>
|
||||
<li class="list-group-item">API access</li>
|
||||
<li class="list-group-item">5 SMS {% if enable_whatsapp %}& WhatsApp{% endif %} credits</li>
|
||||
<li class="list-group-item">Email support</li>
|
||||
</ul>
|
||||
|
||||
{% if not request.user.is_authenticated %}
|
||||
<div class="panel-footer">
|
||||
<a href="#" data-toggle="modal" data-target="#signup-modal" class="btn">
|
||||
Sign Up
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Business -->
|
||||
<div class="col-sm-3 text-center">
|
||||
<div class="panel panel-default plan business">
|
||||
<div class="panel-body text-center">
|
||||
<h1>Business</h1>
|
||||
<h2>
|
||||
<span id="s-price">$20</span><span class="mo">/mo</span>
|
||||
<span id="business-price">$20</span>
|
||||
<span class="mo">/ month</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<ul class="list-group text-center">
|
||||
<li class="list-group-item">100 Checks</li>
|
||||
<li class="list-group-item">10 Team Members</li>
|
||||
<li class="list-group-item">1000 Log Entries per Check</li>
|
||||
<li class="list-group-item">API Access</li>
|
||||
<li class="list-group-item">50 SMS {% if enable_whatsapp %}& WhatsApp{% endif %} Alerts per Month</li>
|
||||
<li class="list-group-item">Email Support</li>
|
||||
<li class="list-group-item">100 checks</li>
|
||||
<li class="list-group-item">10 team members</li>
|
||||
<li class="list-group-item">1000 log entries per check</li>
|
||||
<li class="list-group-item">API access</li>
|
||||
<li class="list-group-item">50 SMS {% if enable_whatsapp %}& WhatsApp{% endif %} credits</li>
|
||||
<li class="list-group-item">Email support</li>
|
||||
</ul>
|
||||
|
||||
{% if not request.user.is_authenticated %}
|
||||
<div class="panel-footer">
|
||||
<a href="#" data-toggle="modal" data-target="#signup-modal" class="btn btn-lg btn-primary">
|
||||
Get Started
|
||||
<a href="#" data-toggle="modal" data-target="#signup-modal" class="btn">
|
||||
Sign Up
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- /item -->
|
||||
|
||||
<!-- P50 -->
|
||||
<div class="col-sm-4 text-center">
|
||||
<div class="panel panel-default">
|
||||
<!-- Business Plus -->
|
||||
<div class="col-sm-3 text-center">
|
||||
<div class="panel panel-default plan business-plus">
|
||||
<div class="panel-body text-center">
|
||||
<h1>Business Plus</h1>
|
||||
<h2>
|
||||
<span id="p-price">$80</span><span class="mo">/mo</span>
|
||||
<span id="business-plus-price">$80</span>
|
||||
<span class="mo">/ month</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<ul class="list-group text-center">
|
||||
<li class="list-group-item">1000 Checks</li>
|
||||
<li class="list-group-item">Unlimited Team Members</li>
|
||||
<li class="list-group-item">1000 Log Entries per Check</li>
|
||||
<li class="list-group-item">API Access</li>
|
||||
<li class="list-group-item">500 SMS {% if enable_whatsapp %}& WhatsApp{% endif %} Alerts per Month</li>
|
||||
<li class="list-group-item">Priority Email Support</li>
|
||||
<li class="list-group-item">1000 checks</li>
|
||||
<li class="list-group-item">Unlimited team members</li>
|
||||
<li class="list-group-item">1000 log entries per check</li>
|
||||
<li class="list-group-item">API access</li>
|
||||
<li class="list-group-item">500 SMS {% if enable_whatsapp %}& WhatsApp{% endif %} credits</li>
|
||||
<li class="list-group-item">Priority email support</li>
|
||||
</ul>
|
||||
|
||||
{% if not request.user.is_authenticated %}
|
||||
<div class="panel-footer">
|
||||
<a href="#" data-toggle="modal" data-target="#signup-modal" class="btn btn-lg btn-primary">
|
||||
Get Started
|
||||
<a href="#" data-toggle="modal" data-target="#signup-modal" class="btn">
|
||||
Sign Up
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- /item -->
|
||||
</div>
|
||||
</section>
|
||||
<!-- /Plans -->
|
||||
|
||||
<section id="faq">
|
||||
<div class="container">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user