diff --git a/rowers/braintreestuff.py b/rowers/braintreestuff.py index fda05793..f03bc2e1 100644 --- a/rowers/braintreestuff.py +++ b/rowers/braintreestuff.py @@ -217,17 +217,22 @@ def create_subscription(rower,data): "payment_method_nonce": nonce_from_the_client }) + print 'aap' + if result.is_success: payment_method_token = result.payment_method.token else: return False,0 + print 'noot' + result = gateway.subscription.create({ "payment_method_token": payment_method_token, "plan_id": plan.external_id }) if result.is_success: + print 'mies' rower.paidplan = plan rower.planexpires = result.subscription.billing_period_end_date rower.teamplanexpires = result.subscription.billing_period_end_date diff --git a/rowers/templates/instroke.html b/rowers/templates/instroke.html index 531962e9..9e8c6bcd 100644 --- a/rowers/templates/instroke.html +++ b/rowers/templates/instroke.html @@ -12,7 +12,7 @@

This is a preview of the page with advanced functionality for Pro users. - See the About page for more information + See the About page for more information and to sign up for Pro Membership

{% endif %} @@ -30,7 +30,7 @@ Public link to this workout - https://rowsandall.com/rowers/workout/{{ workout.id }} + https://rowsandall.com/rowers/workout/{{ workout.id }} @@ -42,7 +42,7 @@ {% if instrokemetrics %} {% for metric in instrokemetrics %}

- {{ metric }} + {{ metric }}

{% endfor %} {% else %} diff --git a/rowers/templates/otwinteractive.html b/rowers/templates/otwinteractive.html index 33898af5..099cdaf4 100644 --- a/rowers/templates/otwinteractive.html +++ b/rowers/templates/otwinteractive.html @@ -35,7 +35,7 @@ While the wind and stream correction is fairly reliable, the OTW to OTE conversion sometimes throws errors. Those data points are omitted and replaced by interpolated values. We are sorry if this messed up some of your plots.
  • - Read more details about the way we calculate things here. + Read more details about the way we calculate things here.
  • diff --git a/rowers/tests/mocks.py b/rowers/tests/mocks.py index ed8022f7..5a7c8ba7 100644 --- a/rowers/tests/mocks.py +++ b/rowers/tests/mocks.py @@ -172,7 +172,127 @@ class MockStravalibClient(): def update_activity(*args, **kwargs): return StravaActivity() +class gatewayresult(): + def __init__(self,*args,**kwargs): + self.is_success = kwargs.pop('is_success',True) + self.customer_id = 1 + self.transaction = vtransaction() + self.payment_method = payment_method() + self.subscription = vsubscription() +class credit_card(): + def __init__(self, *args, **kwargs): + self.subscriptions = [vsubscription()] + self.country_of_issuance = 'US' + +class paypal_account(): + def __init__(self, *args, **kwargs): + self.subscriptions = [vsubscription(),vsubscription()] + +class customer(): + def find(*arg, **kwargs): + return self + + def create(*args, **kwargs): + return gatewayresult(is_success=True) + + def __init__(self, *args, **kwargs): + self.credit_cards = [credit_card(),credit_card()] + self.paypal_accounts = [paypal_account()] + +class client_token(): + def generate(*args, **kwargs): + return 'aapnooit' + +class plan(): + def all(*args, **kwargs): + return [] + + + +class transaction(): + def sale(*args, **kwargs): + return gatewayresult(is_success=True) + + def search(*args, **kwargs): + return [gatewayresult(is_success=True),gatewayresult(is_success=True)] + + def __init__(self,*args, **kwargs): + self.amount = 15 + self.credit_card_details = credit_card() + self.customer = { + 'first_name': 'John', + 'last_name': 'Doe', + 'id': 12 + } + self.created_at = datetime.datetime.now() + self.currency_iso_code = 'EUR' + +class vtransaction(): + def __init__(self,*args, **kwargs): + self.amount = 15 + self.credit_card_details = credit_card() + self.customer = { + 'first_name': 'John', + 'last_name': 'Doe', + 'id': 12 + } + self.created_at = datetime.datetime.now() + self.currency_iso_code = 'EUR' + +class vsubscription(): + def update(*args, **kwargs): + return gatewayresult(is_success=True) + + def cancel(*args, **kwargs): + return gatewayresult() + + def __init__(self, *args, **kwargs): + self.id = 121 + self.billing_period_end_date = (datetime.datetime.now()+datetime.timedelta(days=365)).date() + self.status = 'Active' + self.plan_id = 12 + self.price = 15 + self.never_expires = True + +class subscription(): + def create(*args, **kwargs): + return gatewayresult(is_success=True) + + def update(*args, **kwargs): + return gatewayresult(is_success=True) + + def cancel(*args, **kwargs): + return gatewayresult() + + def __init__(self, *args, **kwargs): + self.id = 121 + self.billing_period_end_date = (datetime.datetime.now()+datetime.timedelta(days=365)).date() + self.transactions = [vtransaction()] + self.status = 'Active' + self.plan_id = 12 + self.price = 15 + self.never_expires = True + + +class payment_method(): + def create(*args, **kwargs): + return gatewayresult() + + def __init__(self, *args, **kwargs): + self.token = 'liesjeleerdelotje' + +# mock braintree gateway +class MockBraintreeGateway(): + def __init__(self,*args, **kwargs): + self.customer = customer() + self.client_token = client_token() + self.plan = plan() + self.transaction = transaction() + self.subscription = subscription() + self.payment_method = payment_method() + + class mocked_rowingdata(rowingdata): def __init__(self, *args, **kwargs): super(mocked_rowingdata).__init__(*args, **kwargs) diff --git a/rowers/tests/test_errorpages.py b/rowers/tests/test_errorpages.py index 57ea66b0..cd9c23a0 100644 --- a/rowers/tests/test_errorpages.py +++ b/rowers/tests/test_errorpages.py @@ -17,3 +17,6 @@ class TestErrorPages(TestCase): self.assertEqual(response.status_code, 500) self.assertIn('500 Internal Server Error', unicode(response)) + response = error400_view(request) + self.assertEqual(response.status_code, 400) + diff --git a/rowers/tests/test_payments.py b/rowers/tests/test_payments.py new file mode 100644 index 00000000..c6341649 --- /dev/null +++ b/rowers/tests/test_payments.py @@ -0,0 +1,270 @@ +from statements import * + +nu = datetime.datetime.now() + +from django_countries import countries + +class PaymentTest(TestCase): + def setUp(self): + self.u = UserFactory() + self.r = Rower.objects.create(user=self.u, + birthdate=faker.profile()['birthdate'], + gdproptin=True, + gdproptindate=timezone.now(), + rowerplan='coach', + paymentprocessor='braintree', + street_address = faker.street_address(), + city = faker.city(), + postal_code = faker.postalcode(), + country = faker.country(), + ) + + p = PaidPlan( + shortname='free', + name='Basic', + external_id='a', + price=0, + paymentprocessor='braintree', + paymenttype='single', + ) + + p.save() + + p = PaidPlan( + shortname='pro_recurring', + name='Pro (recurring)', + external_id='b', + price=15, + paymentprocessor='braintree', + paymenttype='single', + ) + + p.save() + + p = PaidPlan( + shortname='pro_single', + name='Pro (single)', + external_id='c', + price=20, + paymentprocessor='braintree', + paymenttype='single', + ) + + p.save() + + self.c = Client() + self.password = faker.word() + self.u.set_password(self.password) + self.u.save() + + @patch('rowers.braintreestuff.braintree.BraintreeGateway',side_effect=MockBraintreeGateway) + def test_billing_view(self,mock_gateway): + login = self.c.login(username=self.u.username, password=self.password) + self.assertTrue(login) + + url = '/rowers/billing/' + + response = self.c.get(url) + self.assertEqual(response.status_code,200) + + plans = PaidPlan.objects.filter(price__gt=0).order_by('price') + plan = plans[0] + + country = faker.country() + countrycode = 'NL' + for code, name in list(countries): + if name.lower() == country.lower(): + countrycode = code + + form_data = { + 'street_address':faker.street_address(), + 'city':faker.city(), + 'postal_code':faker.postalcode(), + 'country':countrycode, + 'plan':plan.id, + } + + form = RowerBillingAddressForm(form_data) + self.assertTrue(form.is_valid) + + form = PlanSelectForm(form_data,paymentprocessor='braintree') + self.assertTrue(form.is_valid) + + response = self.c.post(url,form_data,follow=True) + self.assertEqual(response.status_code,200) + + expected_url = '/rowers/checkout/'+str(plan.id)+'/' + + self.assertRedirects(response, + expected_url = expected_url, + status_code=302,target_status_code=200) + + @patch('rowers.braintreestuff.braintree.BraintreeGateway',side_effect=MockBraintreeGateway) + def test_upgrade_view(self,mock_gateway): + self.r.country = 'NL' + self.r.customer_id = 34 + self.r.subscription_id = 34 + self.r.save() + + login = self.c.login(username=self.u.username, password=self.password) + self.assertTrue(login) + + url = '/rowers/upgrade/' + + response = self.c.get(url) + self.assertEqual(response.status_code,200) + + plans = PaidPlan.objects.filter(price__gt=0).order_by('price') + plan = plans[0] + + country = faker.country() + countrycode = 'NL' + for code, name in list(countries): + if name.lower() == country.lower(): + countrycode = code + + form_data = { + 'street_address':faker.street_address(), + 'city':faker.city(), + 'postal_code':faker.postalcode(), + 'country':countrycode, + 'plan':plan.id, + } + + form = RowerBillingAddressForm(form_data) + self.assertTrue(form.is_valid) + + form = PlanSelectForm(form_data,paymentprocessor='braintree') + self.assertTrue(form.is_valid) + + response = self.c.post(url,form_data,follow=True) + self.assertEqual(response.status_code,200) + + expected_url = '/rowers/upgradecheckout/'+str(plan.id)+'/' + + self.assertRedirects(response, + expected_url = expected_url, + status_code=302,target_status_code=200) + + @patch('rowers.braintreestuff.braintree.BraintreeGateway',side_effect=MockBraintreeGateway) + def test_down_view(self,mock_gateway): + self.r.country = 'NL' + self.r.customer_id = 34 + self.r.subscription_id = 34 + self.r.save() + + plans = PaidPlan.objects.all().order_by('price') + plan = plans[1] + + self.r.paidplan = plan + self.r.save() + + login = self.c.login(username=self.u.username, password=self.password) + self.assertTrue(login) + + url = '/rowers/downgrade/' + + response = self.c.get(url) + self.assertEqual(response.status_code,200) + + country = faker.country() + countrycode = 'NL' + for code, name in list(countries): + if name.lower() == country.lower(): + countrycode = code + + form_data = { + 'street_address':faker.street_address(), + 'city':faker.city(), + 'postal_code':faker.postalcode(), + 'country':countrycode, + 'plan':plans[0].id, + } + + form = RowerBillingAddressForm(form_data) + self.assertTrue(form.is_valid) + + form = PlanSelectForm(form_data,paymentprocessor='braintree') + self.assertTrue(form.is_valid) + + response = self.c.post(url,form_data,follow=True) + self.assertEqual(response.status_code,200) + + expected_url = '/rowers/downgradecheckout/'+str(plans[0].id)+'/' + + self.assertRedirects(response, + expected_url = expected_url, + status_code=302,target_status_code=200) + + @patch('rowers.braintreestuff.braintree.BraintreeGateway',side_effect=MockBraintreeGateway) + def test_planstop_view(self,mock_gateway): + self.r.country = 'NL' + self.r.customer_id = 34 + self.r.subscription_id = 34 + self.r.save() + + plans = PaidPlan.objects.all().order_by('price') + plan = plans[1] + + self.r.paidplan = plan + self.r.save() + + login = self.c.login(username=self.u.username, password=self.password) + self.assertTrue(login) + + url = '/rowers/me/cancelsubscriptions/' + + response = self.c.get(url) + self.assertEqual(response.status_code,200) + + + @patch('rowers.braintreestuff.braintree.BraintreeGateway',side_effect=MockBraintreeGateway) + def test_planstobasic_view(self,mock_gateway): + self.r.country = 'NL' + self.r.customer_id = 34 + self.r.subscription_id = 34 + self.r.save() + + plans = PaidPlan.objects.all().order_by('price') + plan = plans[1] + + self.r.paidplan = plan + self.r.save() + + login = self.c.login(username=self.u.username, password=self.password) + self.assertTrue(login) + + url = '/rowers/me/cancelsubscription/34/' + + response = self.c.get(url,follow=True) + self.assertEqual(response.status_code,200) + self.assertRedirects(response, + expected_url = '/rowers/me/cancelsubscriptions/', + status_code=302,target_status_code=200) + + @patch('rowers.braintreestuff.braintree.BraintreeGateway',side_effect=MockBraintreeGateway) + def test_checkouts_view(self,mock_gateway): + + plans = PaidPlan.objects.all().order_by('price') + plan = plans[1] + + form_data = { + 'amount':'15.00', + 'plan': plans[1].id, + 'payment_method_nonce': 'aap', + } + + form = BillingForm(form_data) + self.assertTrue(form.is_valid) + + login = self.c.login(username=self.u.username, password=self.password) + self.assertTrue(login) + + url = '/rowers/checkouts/' + + response = self.c.post(url, form_data,follow=True) + self.assertEqual(response.status_code,200) + + self.assertRedirects(response, + expected_url = '/rowers/paymentcompleted/', + status_code=302,target_status_code=200) diff --git a/rowers/tests/testdata/testdata.csv.gz b/rowers/tests/testdata/testdata.csv.gz index b3b0bd05..1473a31a 100644 Binary files a/rowers/tests/testdata/testdata.csv.gz and b/rowers/tests/testdata/testdata.csv.gz differ diff --git a/rowers/tests/testdata/testdata.tcx b/rowers/tests/testdata/testdata.tcx deleted file mode 100644 index 1d994ccf..00000000 --- a/rowers/tests/testdata/testdata.tcx +++ /dev/null @@ -1,2523 +0,0 @@ - - - - - 2016-05-20T13:41:26.962390+00:00 - - 537 - 2000 - 1 - - 148 - - - 156 - - Active - 21 - Manual - - - - 5.4 - - 127 - - 0 - - - 19 - - - - - - 13.1 - - 127 - - 19 - - - 26 - - - - - - 21.0 - - 128 - - 20 - - - 45 - - - - - - 30.3 - - 129 - - 20 - - - 64 - - - - - - 39.0 - - 130 - - 20 - - - 74 - - - - - - 48.2 - - 131 - - 21 - - - 80 - - - - - - 57.6 - - 131 - - 20 - - - 83 - - - - - - 66.4 - - 132 - - 20 - - - 87 - - - - - - 75.5 - - 132 - - 21 - - - 86 - - - - - - 85.1 - - 132 - - 20 - - - 88 - - - - - - 95.0 - - 132 - - 21 - - - 100 - - - - - - 105.0 - - 133 - - 22 - - - 127 - - - - - - 115.3 - - 134 - - 21 - - - 135 - - - - - - 125.8 - - 135 - - 21 - - - 139 - - - - - - 136.6 - - 136 - - 21 - - - 146 - - - - - - 147.2 - - 137 - - 22 - - - 150 - - - - - - 157.6 - - 139 - - 22 - - - 152 - - - - - - 167.8 - - 140 - - 21 - - - 146 - - - - - - 178.5 - - 140 - - 22 - - - 150 - - - - - - 188.5 - - 141 - - 21 - - - 155 - - - - - - 199.3 - - 141 - - 21 - - - 148 - - - - - - 209.4 - - 142 - - 22 - - - 151 - - - - - - 219.4 - - 142 - - 22 - - - 151 - - - - - - 230.2 - - 143 - - 22 - - - 148 - - - - - - 240.2 - - 144 - - 22 - - - 147 - - - - - - 250.1 - - 145 - - 23 - - - 150 - - - - - - 259.6 - - 145 - - 23 - - - 152 - - - - - - 270.3 - - 145 - - 23 - - - 152 - - - - - - 280.6 - - 145 - - 22 - - - 149 - - - - - - 290.7 - - 144 - - 22 - - - 150 - - - - - - 300.8 - - 145 - - 23 - - - 149 - - - - - - 311.1 - - 145 - - 22 - - - 152 - - - - - - 321.2 - - 145 - - 22 - - - 157 - - - - - - 331.9 - - 145 - - 21 - - - 150 - - - - - - 342.0 - - 146 - - 22 - - - 151 - - - - - - 352.4 - - 146 - - 22 - - - 151 - - - - - - 363.0 - - 146 - - 22 - - - 153 - - - - - - 373.4 - - 147 - - 22 - - - 152 - - - - - - 383.9 - - 147 - - 22 - - - 153 - - - - - - 394.6 - - 147 - - 22 - - - 152 - - - - - - 405.0 - - 147 - - 21 - - - 149 - - - - - - 415.3 - - 148 - - 22 - - - 152 - - - - - - 426.0 - - 148 - - 22 - - - 151 - - - - - - 436.5 - - 148 - - 21 - - - 149 - - - - - - 446.9 - - 148 - - 22 - - - 149 - - - - - - 456.9 - - 149 - - 22 - - - 156 - - - - - - 467.6 - - 149 - - 22 - - - 155 - - - - - - 478.5 - - 150 - - 22 - - - 156 - - - - - - 489.0 - - 150 - - 21 - - - 154 - - - - - - 499.1 - - 150 - - 21 - - - 148 - - - - - - 510.0 - - 150 - - 22 - - - 151 - - - - - - 519.9 - - 149 - - 22 - - - 153 - - - - - - 530.6 - - 149 - - 22 - - - 151 - - - - - - 540.8 - - 149 - - 22 - - - 148 - - - - - - 550.8 - - 148 - - 22 - - - 149 - - - - - - 560.8 - - 148 - - 22 - - - 144 - - - - - - 571.0 - - 147 - - 22 - - - 149 - - - - - - 580.7 - - 147 - - 22 - - - 150 - - - - - - 591.2 - - 147 - - 22 - - - 151 - - - - - - 601.4 - - 147 - - 22 - - - 150 - - - - - - 611.4 - - 147 - - 23 - - - 153 - - - - - - 621.8 - - 147 - - 23 - - - 151 - - - - - - 632.1 - - 147 - - 22 - - - 155 - - - - - - 642.3 - - 147 - - 22 - - - 154 - - - - - - 652.0 - - 148 - - 23 - - - 157 - - - - - - 662.7 - - 148 - - 23 - - - 162 - - - - - - 673.1 - - 148 - - 23 - - - 163 - - - - - - 683.6 - - 149 - - 22 - - - 163 - - - - - - 693.8 - - 149 - - 22 - - - 162 - - - - - - 703.8 - - 149 - - 22 - - - 164 - - - - - - 714.7 - - 150 - - 23 - - - 162 - - - - - - 724.9 - - 150 - - 22 - - - 162 - - - - - - 735.2 - - 151 - - 23 - - - 159 - - - - - - 745.4 - - 151 - - 22 - - - 158 - - - - - - 756.0 - - 151 - - 23 - - - 164 - - - - - - 766.3 - - 150 - - 22 - - - 163 - - - - - - 776.5 - - 150 - - 22 - - - 161 - - - - - - 786.9 - - 150 - - 23 - - - 163 - - - - - - 797.2 - - 150 - - 22 - - - 165 - - - - - - 807.8 - - 150 - - 23 - - - 166 - - - - - - 818.2 - - 150 - - 23 - - - 166 - - - - - - 828.4 - - 150 - - 22 - - - 168 - - - - - - 839.2 - - 150 - - 23 - - - 169 - - - - - - 849.6 - - 151 - - 23 - - - 166 - - - - - - 860.1 - - 151 - - 22 - - - 172 - - - - - - 870.3 - - 152 - - 22 - - - 172 - - - - - - 881.1 - - 152 - - 22 - - - 169 - - - - - - 891.7 - - 152 - - 23 - - - 167 - - - - - - 902.1 - - 152 - - 22 - - - 164 - - - - - - 913.1 - - 152 - - 22 - - - 161 - - - - - - 923.9 - - 153 - - 22 - - - 158 - - - - - - 934.6 - - 154 - - 21 - - - 158 - - - - - - 945.4 - - 154 - - 21 - - - 154 - - - - - - 956.0 - - 155 - - 21 - - - 155 - - - - - - 966.7 - - 155 - - 21 - - - 152 - - - - - - 977.4 - - 156 - - 21 - - - 150 - - - - - - 988.1 - - 156 - - 21 - - - 157 - - - - - - 998.8 - - 156 - - 21 - - - 155 - - - - - - 1009.6 - - 156 - - 21 - - - 151 - - - - - - 1020.6 - - 156 - - 21 - - - 147 - - - - - - 1031.5 - - 156 - - 20 - - - 145 - - - - - - 1042.5 - - 156 - - 21 - - - 144 - - - - - - 1053.3 - - 155 - - 20 - - - 145 - - - - - - 1064.1 - - 155 - - 21 - - - 147 - - - - - - 1075.3 - - 155 - - 20 - - - 142 - - - - - - 1086.1 - - 155 - - 20 - - - 136 - - - - - - 1097.5 - - 155 - - 21 - - - 141 - - - - - - 1108.5 - - 155 - - 20 - - - 146 - - - - - - 1119.2 - - 155 - - 20 - - - 143 - - - - - - 1130.6 - - 155 - - 20 - - - 143 - - - - - - 1141.3 - - 155 - - 20 - - - 143 - - - - - - 1152.4 - - 155 - - 21 - - - 142 - - - - - - 1163.3 - - 155 - - 20 - - - 138 - - - - - - 1173.8 - - 154 - - 20 - - - 141 - - - - - - 1184.8 - - 154 - - 21 - - - 146 - - - - - - 1195.8 - - 153 - - 21 - - - 146 - - - - - - 1206.6 - - 152 - - 21 - - - 141 - - - - - - 1217.3 - - 153 - - 21 - - - 141 - - - - - - 1227.8 - - 152 - - 21 - - - 140 - - - - - - 1238.7 - - 152 - - 21 - - - 143 - - - - - - 1249.5 - - 151 - - 21 - - - 149 - - - - - - 1260.1 - - 151 - - 20 - - - 141 - - - - - - 1270.9 - - 151 - - 21 - - - 141 - - - - - - 1281.8 - - 150 - - 21 - - - 145 - - - - - - 1292.7 - - 151 - - 20 - - - 142 - - - - - - 1303.4 - - 151 - - 20 - - - 141 - - - - - - 1314.3 - - 151 - - 21 - - - 141 - - - - - - 1325.2 - - 151 - - 21 - - - 146 - - - - - - 1336.1 - - 152 - - 20 - - - 143 - - - - - - 1346.9 - - 152 - - 21 - - - 144 - - - - - - 1357.4 - - 152 - - 20 - - - 141 - - - - - - 1368.1 - - 152 - - 21 - - - 138 - - - - - - 1379.0 - - 152 - - 20 - - - 142 - - - - - - 1389.5 - - 153 - - 21 - - - 145 - - - - - - 1399.9 - - 152 - - 21 - - - 138 - - - - - - 1410.7 - - 152 - - 20 - - - 139 - - - - - - 1422.0 - - 152 - - 20 - - - 139 - - - - - - 1432.8 - - 151 - - 20 - - - 141 - - - - - - 1443.6 - - 151 - - 21 - - - 146 - - - - - - 1454.4 - - 152 - - 20 - - - 143 - - - - - - 1465.1 - - 151 - - 21 - - - 143 - - - - - - 1475.9 - - 152 - - 21 - - - 145 - - - - - - 1486.6 - - 152 - - 21 - - - 148 - - - - - - 1497.4 - - 153 - - 21 - - - 143 - - - - - - 1508.2 - - 153 - - 20 - - - 140 - - - - - - 1519.2 - - 154 - - 20 - - - 144 - - - - - - 1530.0 - - 154 - - 21 - - - 143 - - - - - - 1540.9 - - 153 - - 20 - - - 141 - - - - - - 1551.3 - - 153 - - 21 - - - 143 - - - - - - 1562.6 - - 153 - - 21 - - - 146 - - - - - - 1573.3 - - 153 - - 20 - - - 141 - - - - - - 1584.2 - - 152 - - 20 - - - 139 - - - - - - 1594.6 - - 152 - - 21 - - - 145 - - - - - - 1606.0 - - 152 - - 21 - - - 143 - - - - - - 1616.2 - - 152 - - 20 - - - 138 - - - - - - 1627.4 - - 152 - - 21 - - - 140 - - - - - - 1638.0 - - 152 - - 21 - - - 144 - - - - - - 1649.2 - - 151 - - 20 - - - 143 - - - - - - 1660.2 - - 152 - - 20 - - - 143 - - - - - - 1670.8 - - 151 - - 20 - - - 142 - - - - - - 1681.4 - - 151 - - 21 - - - 140 - - - - - - 1692.1 - - 151 - - 21 - - - 140 - - - - - - 1702.5 - - 150 - - 21 - - - 141 - - - - - - 1713.7 - - 150 - - 21 - - - 144 - - - - - - 1724.4 - - 150 - - 21 - - - 146 - - - - - - 1735.1 - - 150 - - 20 - - - 141 - - - - - - 1745.6 - - 150 - - 21 - - - 140 - - - - - - 1756.3 - - 150 - - 21 - - - 141 - - - - - - 1766.2 - - 151 - - 20 - - - 142 - - - - - - 1777.1 - - 150 - - 22 - - - 138 - - - - - - 1787.5 - - 150 - - 21 - - - 138 - - - - - - 1797.7 - - 150 - - 22 - - - 140 - - - - - - 1808.4 - - 150 - - 21 - - - 140 - - - - - - 1818.4 - - 149 - - 21 - - - 138 - - - - - - 1828.9 - - 149 - - 22 - - - 146 - - - - - - 1839.9 - - 149 - - 21 - - - 142 - - - - - - 1850.5 - - 148 - - 21 - - - 142 - - - - - - 1861.2 - - 148 - - 21 - - - 145 - - - - - - 1871.9 - - 147 - - 21 - - - 143 - - - - - - 1882.6 - - 147 - - 20 - - - 139 - - - - - - 1893.3 - - 148 - - 20 - - - 140 - - - - - - 1904.3 - - 149 - - 21 - - - 144 - - - - - - 1915.4 - - 149 - - 20 - - - 148 - - - - - - 1926.2 - - 150 - - 20 - - - 139 - - - - - - 1937.3 - - 151 - - 20 - - - 140 - - - - - - 1947.8 - - 152 - - 20 - - - 144 - - - - - - 1959.1 - - 152 - - 20 - - - 142 - - - - - - 1969.8 - - 153 - - 20 - - - 140 - - - - - - 1980.6 - - 153 - - 21 - - - 143 - - - - - - 1991.4 - - 153 - - 21 - - - 143 - - - - - - 2000.0 - - 154 - - 21 - - - 147 - - - - - - <Element 'Notes' at 0x14f48668> - - - - rowsandall.com/rowingdata - - - rowingdata - - - 0 - 75 - - Release - - EN - 000-00000-00 - - diff --git a/rowers/views.py b/rowers/views.py index 396cf585..6400c2e4 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -1102,9 +1102,9 @@ def billing_view(request): setattr(r, attr, value) r.save() - if planselectform.is_valid(): - plan = planselectform.cleaned_data['plan'] - if billingaddressform.is_valid(): + if billingaddressform.is_valid(): + if planselectform.is_valid(): + plan = planselectform.cleaned_data['plan'] try: customer_id = braintreestuff.create_customer(r) except ProcessorCustomerError: @@ -1116,6 +1116,7 @@ def billing_view(request): 'planid':plan.id }) return HttpResponseRedirect(url) + else: billingaddressform = RowerBillingAddressForm(instance=r)