diff --git a/hc/payments/migrations/0005_subscription_plan_name.py b/hc/payments/migrations/0005_subscription_plan_name.py new file mode 100644 index 00000000..a2f8a339 --- /dev/null +++ b/hc/payments/migrations/0005_subscription_plan_name.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2018-03-04 17:28 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('payments', '0004_subscription_send_invoices'), + ] + + operations = [ + migrations.AddField( + model_name='subscription', + name='plan_name', + field=models.CharField(blank=True, max_length=50), + ), + ] diff --git a/hc/payments/models.py b/hc/payments/models.py index 3a077d6e..356a1502 100644 --- a/hc/payments/models.py +++ b/hc/payments/models.py @@ -42,35 +42,12 @@ class Subscription(models.Model): payment_method_token = models.CharField(max_length=35, blank=True) subscription_id = models.CharField(max_length=10, blank=True) plan_id = models.CharField(max_length=10, blank=True) + plan_name = models.CharField(max_length=50, blank=True) address_id = models.CharField(max_length=2, blank=True) send_invoices = models.BooleanField(default=True) objects = SubscriptionManager() - def price(self): - if self.plan_id == "P5": - return 5 - elif self.plan_id == "P50": - return 50 - elif self.plan_id == "Y48": - return 48 - elif self.plan_id == "Y480": - return 480 - elif self.plan_id == "T144": - return 144 - - return 0 - - def period(self): - if self.plan_id.startswith("P"): - return "month" - elif self.plan_id.startswith("Y"): - return "year" - elif self.plan_id.startswith("T"): - return "3 years" - - raise NotImplementedError("Unexpected plan: %s" % self.plan_id) - @property def payment_method(self): if not self.payment_method_token: @@ -160,6 +137,15 @@ class Subscription(models.Model): if result.is_success: self.subscription_id = result.subscription.id self.plan_id = plan_id + if plan_id == "P20": + self.plan_name = "Standard ($20 / month)" + elif plan_id == "Y192": + self.plan_name = "Standard ($192 / year)" + elif plan_id == "P80": + self.plan_name = "Plus ($80 / month)" + elif plan_id == "Y768": + self.plan_name = "Plus ($768 / year)" + self.save() return result diff --git a/hc/payments/tests/test_pricing.py b/hc/payments/tests/test_pricing.py index 30578bf6..1290565e 100644 --- a/hc/payments/tests/test_pricing.py +++ b/hc/payments/tests/test_pricing.py @@ -8,7 +8,7 @@ class PricingTestCase(BaseTestCase): def test_anonymous(self): r = self.client.get("/pricing/") - self.assertContains(r, "Unlimited Checks", status_code=200) + self.assertContains(r, "Unlimited Team Members", status_code=200) # A subscription object should have NOT been created assert Subscription.objects.count() == 0 @@ -17,7 +17,7 @@ class PricingTestCase(BaseTestCase): self.client.login(username="alice@example.org", password="password") r = self.client.get("/pricing/") - self.assertContains(r, "Unlimited Checks", status_code=200) + self.assertContains(r, "Unlimited Team Members", status_code=200) # A subscription object still should have NOT been created assert Subscription.objects.count() == 0 @@ -39,10 +39,11 @@ class PricingTestCase(BaseTestCase): def test_it_shows_active_plan(self): self.sub = Subscription(user=self.alice) self.sub.subscription_id = "test-id" - self.sub.plan_id = "P5" + self.sub.plan_id = "P20" + self.sub.plan_name = "Standard ($20 / month)" self.sub.save() self.client.login(username="alice@example.org", password="password") r = self.client.get("/pricing/") - self.assertContains(r, "Standard (monthly)", status_code=200) + self.assertContains(r, "Standard ($20 / month)", status_code=200) diff --git a/hc/payments/tests/test_set_plan.py b/hc/payments/tests/test_set_plan.py index 4bdb0967..e13e13fe 100644 --- a/hc/payments/tests/test_set_plan.py +++ b/hc/payments/tests/test_set_plan.py @@ -12,7 +12,7 @@ class SetPlanTestCase(BaseTestCase): mock.Subscription.create.return_value.is_success = True mock.Subscription.create.return_value.subscription.id = "t-sub-id" - def run_set_plan(self, plan_id="P5"): + def run_set_plan(self, plan_id="P20"): form = {"plan_id": plan_id} self.client.login(username="alice@example.org", password="password") return self.client.post("/pricing/set_plan/", form, follow=True) @@ -31,12 +31,13 @@ class SetPlanTestCase(BaseTestCase): # 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, "P5") + self.assertEqual(sub.plan_id, "P20") + self.assertEqual(sub.plan_name, "Standard ($20 / month)") # User's profile should have a higher limits self.profile.refresh_from_db() self.assertEqual(self.profile.ping_log_limit, 1000) - self.assertEqual(self.profile.check_limit, 500) + self.assertEqual(self.profile.check_limit, 50) self.assertEqual(self.profile.team_limit, 9) self.assertEqual(self.profile.sms_limit, 50) self.assertEqual(self.profile.sms_sent, 0) @@ -52,18 +53,19 @@ class SetPlanTestCase(BaseTestCase): self.profile.sms_sent = 1 self.profile.save() - r = self.run_set_plan("Y48") + r = self.run_set_plan("Y192") 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, "Y48") + self.assertEqual(sub.plan_id, "Y192") + self.assertEqual(sub.plan_name, "Standard ($192 / year)") # User's profile should have a higher limits self.profile.refresh_from_db() self.assertEqual(self.profile.ping_log_limit, 1000) - self.assertEqual(self.profile.check_limit, 500) + self.assertEqual(self.profile.check_limit, 50) self.assertEqual(self.profile.team_limit, 9) self.assertEqual(self.profile.sms_limit, 50) self.assertEqual(self.profile.sms_sent, 0) @@ -71,13 +73,41 @@ class SetPlanTestCase(BaseTestCase): # braintree.Subscription.cancel should have not been called assert not mock.Subscription.cancel.called + @patch("hc.payments.models.braintree") + def test_plus_works(self, mock): + self._setup_mock(mock) + + self.profile.sms_limit = 0 + self.profile.sms_sent = 1 + self.profile.save() + + r = self.run_set_plan("P80") + 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, "P80") + self.assertEqual(sub.plan_name, "Plus ($80 / month)") + + # User's profile should have a higher limits + self.profile.refresh_from_db() + self.assertEqual(self.profile.ping_log_limit, 1000) + self.assertEqual(self.profile.check_limit, 500) + self.assertEqual(self.profile.team_limit, 500) + self.assertEqual(self.profile.sms_limit, 500) + 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_it_cancels(self, mock): self._setup_mock(mock) self.sub = Subscription(user=self.alice) self.sub.subscription_id = "test-id" - self.sub.plan_id = "P5" + self.sub.plan_id = "P20" self.sub.save() self.profile.sms_limit = 1 diff --git a/hc/payments/views.py b/hc/payments/views.py index 408463ad..041b838d 100644 --- a/hc/payments/views.py +++ b/hc/payments/views.py @@ -93,7 +93,7 @@ def log_and_bail(request, result): @require_POST def set_plan(request): plan_id = request.POST["plan_id"] - if plan_id not in ("", "P5", "P50", "Y48", "Y480", "T144"): + if plan_id not in ("", "P20", "P80", "Y192", "Y768"): return HttpResponseBadRequest() sub = Subscription.objects.for_user(request.user) @@ -117,14 +117,14 @@ def set_plan(request): # Update user's profile profile = request.user.profile - if plan_id in ("P5", "Y48", "T144"): + if plan_id in ("P20", "Y192"): profile.ping_log_limit = 1000 - profile.check_limit = 500 + profile.check_limit = 50 profile.team_limit = 9 profile.sms_limit = 50 profile.sms_sent = 0 profile.save() - elif plan_id in ("P50", "Y480"): + elif plan_id in ("P80", "Y768"): profile.ping_log_limit = 1000 profile.check_limit = 500 profile.team_limit = 500 diff --git a/static/css/profile.css b/static/css/profile.css index bfdbc61a..3252afc6 100644 --- a/static/css/profile.css +++ b/static/css/profile.css @@ -36,4 +36,13 @@ span.loading { .billing-empty { color: #888; +} + +.at-limit span { + display: inline-block; + background-color: #FFD54F; + font-weight: bold; + font-size: 12px; + border-radius: 2px; + padding: 2px 6px; } \ No newline at end of file diff --git a/static/js/pricing.js b/static/js/pricing.js index c56aadd3..8fb5a53d 100644 --- a/static/js/pricing.js +++ b/static/js/pricing.js @@ -1,13 +1,13 @@ $(function () { $("#period-controls :input").change(function() { if (this.value == "monthly") { - $("#s-price").text("$5"); - $("#p-price").text("$50"); + $("#s-price").text("$20"); + $("#p-price").text("$80"); } if (this.value == "annual") { - $("#s-price").text("$4"); - $("#p-price").text("$40"); + $("#s-price").text("$16"); + $("#p-price").text("$64"); } }); }); \ No newline at end of file diff --git a/templates/accounts/billing.html b/templates/accounts/billing.html index 5bbaf33d..22440be2 100644 --- a/templates/accounts/billing.html +++ b/templates/accounts/billing.html @@ -46,13 +46,7 @@ {% if sub is None or sub.plan_id == "" %} Free {% else %} - {% if sub.plan_id == "P5" or sub.plan_id == "Y48" or sub.plan_id == "T144" %} - Standard - {% elif sub.plan_id == "P50" or sub.plan_id == "Y480" %} - Plus - {% endif %} - - (${{ sub.price }} per {{ sub.period }}) + {{ sub.plan_name }} {% endif %} @@ -66,24 +60,21 @@ {% endif %} Checks Used - - {{ num_checks }} of - {% if sub.plan_id %} - unlimited - {% else %} - {{ profile.check_limit }} - {% endif %} + = profile.check_limit %} class="at-limit" {% endif %}> + {{ num_checks }} of {{ profile.check_limit }} Team Size - + = profile.team_limit %} class="at-limit" {% endif %}> + {{ team_size }} of {% if profile.team_limit == 500 %} unlimited {% else %} {{ team_max }} {% endif %} + @@ -219,57 +210,46 @@ Enjoy free service. -

Standard Unlimited checks, 20 team members

+

Standard 50 checks, 10 team members

+

Plus 500 checks, unlimited team members

- - -

Plus Unlimited checks, unlimited team members

-
diff --git a/templates/front/my_checks.html b/templates/front/my_checks.html index ba0eff16..0a6039ad 100644 --- a/templates/front/my_checks.html +++ b/templates/front/my_checks.html @@ -45,7 +45,7 @@
Check limit reached. To add more checks, please - upgrade your account! + upgrade your account!
{% endif %}
diff --git a/templates/payments/pricing.html b/templates/payments/pricing.html index 1a86a11d..9d4d04cb 100644 --- a/templates/payments/pricing.html +++ b/templates/payments/pricing.html @@ -13,29 +13,21 @@

- Your account is currently on the - {% if sub.plan_id == "P5" %} - Standard (monthly) - {% elif sub.plan_id == "Y48" %} - Standard (annual) - {% elif sub.plan_id == "T144" %} - Standard (3 years) - {% elif sub.plan_id == "Y480" %} - Plus (annual) - {% elif sub.plan_id == "P50" %} - Plus (monthly) + {% if sub.plan_id %} + Your account is currently on the + {{ sub.plan_name }} + plan. Thank you for supporting {% site_name %}! {% else %} - Free + Your account is currently on the + Free plan. {% endif %} - plan. - - {% if sub.plan_id %} - You are paying - ${{ sub.price }} / {{ sub.period }}. - {% endif %}

+ {% if sub.plan_id %} Billing Details + {% else %} + Billing Details and Plan Upgrades + {% endif %}

@@ -100,12 +92,12 @@

Standard

- $5/mo + $20/mo