Private
Public Access
1
0

Merge branch 'feature/refundpolicy' into develop

This commit is contained in:
Sander Roosendaal
2019-02-08 13:02:30 +01:00
14 changed files with 306 additions and 27 deletions

View File

@@ -304,15 +304,16 @@ def getmaxwattinterval(tt,ww,i):
if len(w_roll):
# now goes with # data points - should be fixed seconds
indexmax = w_roll.idxmax(axis=1)
indexmaxpos = indexmax.get_loc(indexmax)
# indexmaxpos = indexmax.get_loc(indexmax)
indexmaxpos = indexmax
try:
t_0 = tt.iloc[indexmaxpos]
t_1 = tt.iloc[indexmaxpos-i]
deltas = tt.iloc[indexmaxpos-i:indexmaxpos].diff().dropna()
t_0 = tt.ix[indexmaxpos]
t_1 = tt.ix[indexmaxpos-i]
deltas = tt.ix[indexmaxpos-i:indexmaxpos].diff().dropna()
testres = 1.0e-3*deltas.max() < 30.
if testres:
deltat = 1.0e-3*(t_0-t_1)
wmax = w_roll.iloc[indexmaxpos]
wmax = w_roll.ix[indexmaxpos]
#if wmax > 800 or wmax*5.0e-4*deltat > 800.0:
# wmax = 0
else:

View File

@@ -44,6 +44,7 @@ class BillingForm(forms.Form):
max_digits=8)
plan = forms.IntegerField(widget=forms.HiddenInput())
payment_method_nonce = forms.CharField(max_length=255,required=True)
tac= forms.BooleanField(required=True,initial=False)
# login form

View File

@@ -22,7 +22,8 @@
as a price per year. You can downgrade or cancel your
plan at any time, through the <a href="/rowers/me/edit/">settings page</a>.
Please refer to our <a href="/rowers/legal/">terms and conditions</a> for our
payments and refunds policy. Accepted payment methods are the payment methods offered
payments and <a href="/rowers/legal/#refunds">refunds policy</a>.
Accepted payment methods are the payment methods offered
by
<a href="https://www.braintreegateway.com/merchants/jytq7yxsm66qqdzb/verified">Braintree</a>
through us. If you have any questions about our payments and refunds policy, please contact

View File

@@ -72,6 +72,11 @@
<input type="hidden" id="nonce" name="payment_method_nonce" />
<input type="hidden" id="plan" name="plan" value="{{ plan.id }}">
<p>
<input id="tac" type="checkbox" name="tac" value="tac">I have taken note of the
<a href="/rowers/legal/#refunds" target="_blank">Refund and Cancellation</a>
Policy and agree with the <a href="/rowers/legal/" target="_blank">Terms of Service</a>.
</p>
{% csrf_token %}
<button type="submit" id="submit-button"><span>Downgrade to the &euro; {{ plan.price|currency }} plan</span></button>
</form>

View File

@@ -3,6 +3,52 @@
{% block title %}Legal{% endblock title %}
{% block main %}
<h1>Welcome to Rowsandall</h1>
<p>Welcome to Rowsandall. We want you to know and understand your rights and our rights relating
to the provision o fthe Services (as defined below). Please review them carefully.
Here are a few highlights:
</p>
<p>
<ul>
<li>
Your privacy is critically important to us. See how we collect and use your personal
information in our <a href="#privacy">Privacy Policy</a>
</li>
<li>
<a href="#deactivation">You can cancel your membership or delete your account at any time.</a>
</li>
<li>
<a href="#content">You own your content, but give us a right to use it</a>
</li>
<li>
<a href="#conduct">We expect our members to act with respect and we can cancel
your account if you act inappropriately</a>
</li>
<li>
<a href="#liability">Rowsandall is not liable for your activities and no warranties
are made by Rowsandall</a>
</li>
<li>
<a href="#termination">
We can cancel your account if you act inappropriately.
</a>
</li>
<li>
<a href="#refunds">
We offer paid plans with extended functionality. These are governed by
our refund policy.
</a>
</li>
<li>
<a href="#contact">
There are easy ways to reach us if you have questions or need help.
</a>
</li>
</ul>
</p>
<h1>Terms and Conditions</h1>
<h2>Credit</h2>
@@ -32,7 +78,12 @@
</p>
<h2>Acceptable use</h2>
<h2 id="conduct">Acceptable use</h2>
<p>You must not use this website to copy, store, host, transmit, sned, use, publish or
distribute any material which is illegal, obscene, defamatory, threatening, harassing, abusive,
or hateful or that advocates violence.
</p>
<p>You must not use this website in any way that causes, or may cause, damage to the website or impairment of the availability or accessibility of the website; or in any way which is unlawful, illegal, fraudulent or harmful, or in connection with any unlawful, illegal, fraudulent or harmful purpose or activity.</p>
@@ -51,7 +102,7 @@
<p>rowsandall.com may disable your user ID and password in rowsandall.com&rsquo;s sole discretion without notice or explanation.</p>
<h2>User content</h2>
<h2 id="content">User content</h2>
<p>In these terms and conditions, <q>your user content</q> means material (including without limitation text, images, audio material, video material and audio-visual material) that you submit to this website, for whatever purpose.</p>
@@ -78,7 +129,7 @@
<p>Nothing on this website constitutes, or is meant to constitute, advice of any kind. If you require advice in relation to any legal, financial or medica] matter you should consult an appropriate professional.</p>
<h2>Limitations of liability</h2>
<h2 id="liability">Limitations of liability</h2>
<p>rowsandall.com will not be liable to you (whether under the law of contact, the law of torts or otherwise) in relation to the contents of, or use of, or otherwise in connection with, this website:
@@ -136,6 +187,27 @@
<p>If a provision of these terms and conditions is determined by any court or other competent authority to be unlawful and/or unenforceable, the other provisions will continue in effect. If any unlawful and/or unenforceable provision would be lawful or enforceable if part of it were deleted, that part will be deemed to be deleted, and the rest of the provision will continue in effect. </p>
<h2 id="termination">Termination</h2>
<p>
You agree that Rowsandall may, under certain circumstances and without prior notice,
immediately terminate your accountand/or access to the site. Cause for such termination
shall include, but not be limited to, (a) breaches or violations of the Terms or
other incorporated agreements, policies, or guidelines, (b) requests by law enforcement
or other government agencies, (c) a request by you (self-initiated account deletions),
(d) discontinuance or material modification to the services (or any portion thereof), (e)
unexpected technical or security issues or problems, f) extended periods of inactivity,
and/or (g) nonpayment of any fees owed by you in connection with the Services.
Termination of your account may include (x) removal of access to all offerings within the
Services, (y) deletion of your information, files and Content associated with your account,
and (z) barring of further use of the Services. Further, you agree that all terminations
for cause shall be made in Rowsandalls sole discretion and that Strava shall not be liable
to you or any third party for any termination of your account or access to the Services.
The following Sections shall survive termination of your account
and/or the Terms: Member Content Submitted to the Services, Proprietary Rights,
Your Feedback, Disclaimer of Warranties and Liability, Indemnity, Applicable Laws and General.
</p>
<h2>Entire agreement</h2>
<p>These terms and conditions constitute the entire agreement between you and rowsandall.com in relation to your use of this website, and supersede all previous agreements in respect of your use of this website.</p>
@@ -145,7 +217,7 @@
<p>These terms and conditions will be governed by and construed in accordance with Czech Law and any disputes relating to these terms and conditions will be subject to the exclusive jurisdiction of the courts of The Czech Republic.</p>
<h2>rowsandall.com&rsquo;s details</h2>
<h2 id="contact">rowsandall.com&rsquo;s details</h2>
<p>The rowsandall.com site is owned by Rowsandall s.r.o., Nov&eacute; sady 988/2, Star&eacute; Brno, 602 00 Brno, Czech Republic (company identification number 070 48 572)</p>
@@ -156,7 +228,7 @@
{% include "refunds.html" %}
<h2>Privacy Policy</h2>
<h2 id="privacy">Privacy Policy</h2>
{% include "privacypolicy.html" %}

View File

@@ -302,7 +302,11 @@
<h2>Terms and Conditions, Contact Information</h2>
<p>Our paid plans follow the <a href="/rowers/legal/">Terms and Conditions</a>.</p>
<p>
Before purchasing any of our paid plans, you must
review and acknowledge our <a href="/rowers/legal/">Terms and Conditions</a>,
and <a href="/rowers/legal#refunds">Refunds and Returns Policy</a>
</p>
<p>Payments are made to "Rowsandall s.r.o.", with the following contact information:</p>
<p><strong>Rowsandall s.r.o.</strong><br />

View File

@@ -24,7 +24,8 @@
as a price per year. You can downgrade or cancel your
plan at any time, through the <a href="/rowers/me/edit/">settings page</a>.
Please refer to our <a href="/rowers/legal/">terms and conditions</a> for our
payments and refunds policy. Accepted payment methods are the payment methods offered
<a href="/rowers/legel/#refunds">payments and refunds policy</a>.
Accepted payment methods are the payment methods offered
by
<a href="https://www.braintreegateway.com/merchants/jytq7yxsm66qqdzb/verified">Braintree</a>
through us. If you have any questions about our payments and refunds policy, please contact

View File

@@ -20,7 +20,7 @@
</p>
<p>
Payments will be procesed by Braintree (A PayPal service):
Payments will be processed by Braintree (A PayPal service):
</p>
<p>
<a href="https://www.braintreegateway.com/merchants/{{ BRAINTREE_MERCHANT_ID }}/verified" target="_blank">
@@ -93,6 +93,11 @@
<input type="hidden" id="nonce" name="payment_method_nonce" />
<input type="hidden" id="plan" name="plan" value="{{ plan.id }}">
<p>
<input id="tac" type="checkbox" name="tac" value="tac">I have taken note of the
<a href="/rowers/legal/#refunds" target="_blank">Refund and Cancellation</a>
Policy and agree with the <a href="/rowers/legal/" target="_blank">Terms of Service</a>.
</p>
{% csrf_token %}
<button type="submit" id="submit-button"><span>Pay &euro; {{ plan.price|currency }}</span></button>
</form>
@@ -101,7 +106,6 @@
{% include 'braintreedropin.html' %}
{% endblock %}
{% block sidebar %}

View File

@@ -116,7 +116,7 @@
posts.
</p>
<h2>Data Deletion</h2>
<h2 id="deactivation">Membership Cancellation and Data Deletion</h2>
<p>If you have previously consented to allow rowsandall.com to store and process your personal
data in accordance with this privacy policy, and you wish to withdraw your conent,
@@ -237,7 +237,7 @@
edit your heart rate and power settings, as well as functional threshold information and the account information accessible on your
settings page under the header "Account Information". The team manager is not able to access or change your passwords, team memberships,
favorite charts, export settings, workflow layout, or secret tokens. Also, the team manager is not able to download all your data,
not can he deactivate or delete your account.
nor can he deactivate or delete your account.
</p>
<p>
@@ -274,6 +274,7 @@
has suitable GDPR compliant measures in place.
</p>
<h2>Inactive Users - accounts are deleted after 18 months</h2>
<p>

View File

@@ -1,5 +1,5 @@
<p>Thank you for shopping at Rowsandall.</p>
<p id="refunds">Thank you for shopping at Rowsandall.</p>
<h3>Digital products</h3>
@@ -9,19 +9,36 @@
of the plan, you can cancel the recurring payment. We do not issue refunds for payments
regarding the current plan period.</p>
<p>We do not issue refunds for digital products once the order is
confirmed and the product is sent.</p>
<p>If you are not 100% satisfied with your purchase, you can get a refund or
exhchange the product for another one.
</p>
<p>You can return a product for up to 30 days from the date you purchased it.
To be eligible for a refund, you need to contact us using the contact information
below. To improve our service, we ask you to explain how the product did not meet
your expectations. If your refund is approved, we will initiate a refund to your
credit card (or original method of payment). You will receive the credit within
a certain amount of days, depending on your card issuer's policies.
</p>
<p>We recommend contacting us for assistance if you experience any issues receiving
our products.</p>
<h3>Upgrades and Downgrades</h3>
<h3>Upgrades and Downgrades, Cancellations</h3>
Upgrades and downgrades between paid plans are effective immediately, but the billing cycle
is not changed. Upgrades are charged a pro-rated amount for the current billing cycle. Downgrades
will result in a credit on our accounts, leading to a lower charge at the beginning of the
subsequent billing cycle.
<p>
Upgrades and downgrades between paid plans are effective immediately, but the billing cycle
is not changed. Upgrades are charged a pro-rated amount for the current billing cycle. Downgrades
will result in a credit on our accounts, leading to a lower charge at the beginning of the
subsequent billing cycle.
</p>
<p>
With the exception of an approved refund within 30 days of purchase (see above), we do not
issue refunds upon cancellation of the plan. If you are eligible for a refund, contact
us within 30 days of your purchase.
</p>
<h3>Contact us</h3>

View File

@@ -20,7 +20,7 @@
</p>
<p>
Payments will be procesed by Braintree (A PayPal service):
Payments will be processed by Braintree (A PayPal service):
</p>
<p>
<a href="https://www.braintreegateway.com/merchants/{{ BRAINTREE_MERCHANT_ID }}/verified" target="_blank">
@@ -93,6 +93,11 @@
<input type="hidden" id="nonce" name="payment_method_nonce" />
<input type="hidden" id="plan" name="plan" value="{{ plan.id }}">
<p>
<input id="tac" type="checkbox" name="tac" value="tac">I have taken note of the
<a href="/rowers/legal/#refunds" target="_blank">Refund and Cancellation</a>
Policy and agree with the <a href="/rowers/legal/" target="_blank">Terms of Service</a>.
</p>
{% csrf_token %}
<button type="submit" id="submit-button"><span>Upgrade to the &euro; {{ plan.price|currency }} plan</span></button>
</form>

View File

@@ -366,6 +366,7 @@ class PaymentTest(TestCase):
'amount':'15.00',
'plan': plans[1].id,
'payment_method_nonce': 'aap',
'tac':'tac',
}
form = BillingForm(form_data)
@@ -410,6 +411,7 @@ class PaymentTest(TestCase):
'amount':'15.00',
'plan': plans[1].id,
'payment_method_nonce': 'aap',
'tac':'tac',
}
form = BillingForm(form_data)
@@ -453,6 +455,7 @@ class PaymentTest(TestCase):
'amount':'15.00',
'plan': plans[1].id,
'payment_method_nonce': 'aap',
'tac':'tac',
}
form = BillingForm(form_data)
@@ -470,3 +473,138 @@ class PaymentTest(TestCase):
expected_url = '/rowers/downgradecompleted/',
status_code=302,target_status_code=200)
@patch('rowers.views.braintreestuff.create_subscription', side_effect=mock_create_subscription)
def test_checkouts_view(self,mock_subscription):
u = UserFactory()
r = Rower.objects.create(user=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(),
)
r.save()
u.set_password(self.password)
u.save()
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(not form.is_valid())
login = self.c.login(username=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/checkout/{planid}/'.format(
planid=plans[1].id),
status_code=302,target_status_code=200)
@patch('rowers.views.braintreestuff.update_subscription', side_effect=mock_update_subscription)
def test_upgrade_checkouts_view(self,mock_subscription):
u = UserFactory()
r = Rower.objects.create(user=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(),
)
r.save()
u.set_password(self.password)
u.save()
plans = PaidPlan.objects.all().order_by('price')
plan = plans[1]
form_data = {
'amount':'15.00',
'plan': plans[1].id,
'payment_method_nonce': 'aap',
# 'tac':'tac',
}
form = BillingForm(form_data)
self.assertTrue(not form.is_valid())
login = self.c.login(username=u.username, password=self.password)
self.assertTrue(login)
url = '/rowers/upgradecheckouts/'
response = self.c.post(url, form_data,follow=True)
self.assertEqual(response.status_code,200)
self.assertRedirects(response,
expected_url = '/rowers/upgradecheckout/{planid}/'.format(
planid=plans[1].id),
status_code=302,target_status_code=200)
@patch('rowers.views.braintreestuff.update_subscription', side_effect=mock_update_subscription)
def test_downgrade_checkouts_view(self,mock_subscription):
u = UserFactory()
r = Rower.objects.create(user=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(),
)
r.save()
u.set_password(self.password)
u.save()
plans = PaidPlan.objects.all().order_by('price')
plan = plans[1]
form_data = {
'amount':'15.00',
'plan': plans[1].id,
'payment_method_nonce': 'aap',
# 'tac':'tac',
}
form = BillingForm(form_data)
self.assertTrue(not form.is_valid())
login = self.c.login(username=u.username, password=self.password)
self.assertTrue(login)
url = '/rowers/downgradecheckouts/'
response = self.c.post(url, form_data,follow=True)
self.assertEqual(response.status_code,200)
self.assertRedirects(response,
expected_url = '/rowers/downgradecheckout/{planid}/'.format(
planid=plans[1].id),
status_code=302,target_status_code=200)

Binary file not shown.

View File

@@ -329,7 +329,16 @@ def checkouts_view(request):
messages.error(request,"There was a problem with your payment")
url = reverse(billing_view)
return HttpResponseRedirect(url)
elif 'tac' not in request.POST:
try:
planid = int(request.POST['plan'])
url = reverse('payment_confirm_view',kwargs={'planid':planid})
messages.error(request,"You must review and acknowledge the terms and conditions")
return HttpResponseRedirect(url)
except IndexError:
messages.error(request,"There was an error in the payment form")
url = reverse('billing_view')
return HttpResponseRedirect(url)
else:
messages.error(request,"There was an error in the payment form")
url = reverse(billing_view)
@@ -366,6 +375,16 @@ def upgrade_checkouts_view(request):
url = reverse(upgrade_view)
return HttpResponseRedirect(url)
elif 'tac' not in request.POST:
try:
planid = int(request.POST['plan'])
url = reverse('upgrade_confirm_view',kwargs={'planid':planid})
messages.error(request,"You must review and acknowledge the terms and conditions")
return HttpResponseRedirect(url)
except IndexError:
messages.error(request,"There was an error in the payment form")
url = reverse('billing_view')
return HttpResponseRedirect(url)
else:
messages.error(request,"There was an error in the payment form")
url = reverse(upgrade_view)
@@ -399,6 +418,16 @@ def downgrade_checkouts_view(request):
messages.error(request,"There was a problem with your transaction")
url = reverse(upgrade_view)
return HttpResponseRedirect(url)
elif 'tac' not in request.POST:
try:
planid = int(request.POST['plan'])
url = reverse('downgrade_confirm_view',kwargs={'planid':planid})
messages.error(request,"You must review and acknowledge the terms and conditions")
return HttpResponseRedirect(url)
except IndexError:
messages.error(request,"There was an error in the payment form")
url = reverse('billing_view')
return HttpResponseRedirect(url)
else:
messages.error(request,"There was an error in the payment form")