from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals import braintree from django.utils import timezone import datetime from django.conf import settings import sys 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, ) import pandas as pd from rowsandall_app.settings import ( BRAINTREE_MERCHANT_ID,BRAINTREE_PUBLIC_KEY,BRAINTREE_PRIVATE_KEY, BRAINTREE_SANDBOX_MERCHANT_ID,BRAINTREE_SANDBOX_PUBLIC_KEY, BRAINTREE_SANDBOX_PRIVATE_KEY ) if settings.DEBUG or 'dev' in settings.SITE_URL: gateway = braintree.BraintreeGateway( braintree.Configuration( braintree.Environment.Sandbox, merchant_id=BRAINTREE_SANDBOX_MERCHANT_ID, public_key=BRAINTREE_SANDBOX_PUBLIC_KEY, private_key=BRAINTREE_SANDBOX_PRIVATE_KEY, ) ) else: gateway = braintree.BraintreeGateway( braintree.Configuration( braintree.Environment.Production, merchant_id=BRAINTREE_MERCHANT_ID, public_key=BRAINTREE_PUBLIC_KEY, private_key=BRAINTREE_PRIVATE_KEY, ) ) from rowers.models import Rower,PaidPlan, CoachingGroup from rowers.utils import ProcessorCustomerError def create_customer(rower,force=False): if not rower.customer_id or force: result = gateway.customer.create( { 'first_name':rower.user.first_name, 'last_name':rower.user.last_name, 'email':rower.user.email, }) if not result.is_success: raise ProcessorCustomerError else: rower.customer_id = result.customer.id rower.paymentprocessor = 'braintree' rower.save() return rower.customer_id else: return rower.customer_id def get_client_token(rower): try: client_token = gateway.client_token.generate({ "customer_id":rower.customer_id, }) except ValueError: customer_id = create_customer(rower,force=True) client_token = gateway.client_token.generate({ "customer_id": customer_id, }) return client_token def get_plans_costs(): plans = gateway.plan.all() localplans = PaidPlan.object.filter(paymentprocessor='braintree') for plan in localplans: for btplan in btplans: if int(btplan.id) == plan.external_id: plan.price = float(x) plan.save() return plans def make_payment(rower,data): nonce_from_the_client = data['payment_method_nonce'] nonce = gateway.payment_method_nonce.find(nonce_from_the_client) info = nonce.three_d_secure_info if info is None or not info.liability_shifted: return False,0 amount = data['amount'] amount = '{amount:.f2}'.format(amount=amount) result = gateway.transaction.sale({ "amount": amount, "payment_method_nonce": nonce_from_the_client, "options": { "submit_for_settlement": True } }) if result.is_success: transaction = result.transaction 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,'' else: return 0,'' def update_subscription(rower,data,method='up'): planid = data['plan'] plan = PaidPlan.objects.get(id=planid) nonce_from_the_client = data['payment_method_nonce'] nonce = gateway.payment_method_nonce.find(nonce_from_the_client) info = nonce.three_d_secure_info if info is None or not info.liability_shifted: return False,0 amount = data['amount'] amount = '{amount:.2f}'.format(amount=amount) gatewaydata = { "price": amount, "plan_id": plan.external_id, "payment_method_nonce": nonce_from_the_client, "options": { "prorate_charges":True, }, } if plan.paymenttype == 'single': gatewaydata['number_of_billing_cycles'] = 1 else: gatewaydata['never_expires'] = True try: result = gateway.subscription.update( rower.subscription_id, gatewaydata ) except: return False,0 if result.is_success: yesterday = (timezone.now()-datetime.timedelta(days=1)).date() rower.paidplan = plan rower.planexpires = result.subscription.billing_period_end_date rower.teamplanexpires = result.subscription.billing_period_end_date rower.clubsize = plan.clubsize rower.paymenttype = plan.paymenttype rower.rowerplan = plan.shortname rower.subscription_id = result.subscription.id rower.protrialexpires = yesterday rower.plantrialexpires = yesterday rower.save() name = '{f} {l}'.format( f = rower.user.first_name, l = rower.user.last_name, ) if rower.paidplan != 'coach': try: coachgroup = rower.mycoachgroup except CoachingGroup.DoesNotExist: coachgroup = CoachingGroup() coachgroup.save() rower.mycoachgroup = coachgroup rower.save() athletes = Rower.objects.filter(coachinggroups__in=[rower.mycoachgroup]).distinct() for athlete in athletes: athlete.coachinggroups.remove(rower.mycoachgroup) if method == 'up': transactions = result.subscription.transactions if transactions: amount = transactions[0].amount else: amount = 0 else: amount = 0 job = myqueue(queuehigh, handle_send_email_subscription_update, name, rower.user.email, plan.name, plan.paymenttype, plan.price, amount, result.subscription.billing_period_end_date.strftime('%Y-%m-%d'), method) return True,amount else: errors = result.errors.for_object("subscription") codes = [str(e.code) for e in errors] create_new = False proceed_codes = ['81901','81910'] for c in codes: if c in proceed_codes: create_new = True if create_new: return create_subscription(rower,data) return False,0 return False,0 def create_subscription(rower,data): nonce_from_the_client = data['payment_method_nonce'] nonce = gateway.payment_method_nonce.find(nonce_from_the_client) info = nonce.three_d_secure_info if info is None or not info.liability_shifted: return False,0 amount = data['amount'] planid = data['plan'] plan = PaidPlan.objects.get(id=planid) # create or find payment method result = gateway.payment_method.create({ "customer_id": rower.customer_id, "payment_method_nonce": nonce_from_the_client }) if result.is_success: payment_method_token = result.payment_method.token else: return False,0 result = gateway.subscription.create({ "payment_method_token": payment_method_token, "plan_id": plan.external_id }) if result.is_success: rower.paidplan = plan rower.planexpires = result.subscription.billing_period_end_date rower.teamplanexpires = result.subscription.billing_period_end_date rower.clubsize = plan.clubsize rower.paymenttype = plan.paymenttype rower.rowerplan = plan.shortname rower.subscription_id = result.subscription.id rower.save() name = '{f} {l}'.format( f = rower.user.first_name, l = rower.user.last_name, ) recurring = plan.paymenttype 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,plan.price else: return False,0 return False,0 def cancel_subscription(rower,id): themessages = [] errormessages = [] try: result = gateway.subscription.cancel(id) themessages.append("Subscription canceled") except: 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 basicplans = PaidPlan.objects.filter(price=0,paymentprocessor='braintree') rower.paidplan = basicplans[0] rower.teamplanexpires = timezone.now() rower.planexpires = timezone.now() rower.clubsize = 0 rower.rowerplan = 'basic' rower.subscription_id = None rower.save() themessages.append("Your plan was reset to basic") return True, themessages,errormessages def find_subscriptions(rower): try: result = gateway.customer.find(rower.customer_id) except: raise ProcessorCustomerError("We could not find the customer in the database") active_subscriptions = [] cards = result.credit_cards for card in cards: for subscription in card.subscriptions: if subscription.status == 'Active': active_subscriptions.append(subscription) try: paypal_accounts = result.paypal_accounts for account in paypal_accounts: for subscription in account.subscriptions: if subscription.status == 'Active': active_subscriptions.append(subscription) except AttributeError: pass result = [] for subscription in active_subscriptions: plan = PaidPlan.objects.filter(paymentprocessor="braintree", external_id=subscription.plan_id)[0] thedict = { 'end_date': subscription.billing_period_end_date, 'plan_id': subscription.plan_id, 'price': subscription.price, 'id': subscription.id, 'plan': plan.name, 'never_expires': subscription.never_expires } result.append(thedict) return result def get_transactions(start_date,end_date): results = gateway.transaction.search( braintree.TransactionSearch.created_at.between( start_date, end_date, ) ) amounts = [] countries = [] addresses = [] card_countries = [] names = [] emails = [] dates = [] currencies = [] statuses = [] ids = [] usernames = [] customerids = [] transactionids = [] subscriptionids = [] ownids = [] countlines = [1 for transaction in results] for transaction in results: r = None rs = Rower.objects.filter( customer_id=transaction.customer['id'], paymentprocessor='braintree') if rs: r = rs[0] countries.append(r.country) addresses.append('{street}, {city}, {postal_code}'.format( street = r.street_address, city = r.city, postal_code = r.postal_code)) ownids.append(r.id) usernames.append(r.user.username) else: countries.append( transaction.credit_card_details.country_of_issuance) ownids.append('unknown') usernames.append('unknown') addresses.append('') emails.append(transaction.customer_details.email) names.append('{f} {l}'.format( f = transaction.customer['first_name'], l = transaction.customer['last_name'] ) ) customerids.append(transaction.customer['id']) transactionids.append(transaction.id) subscriptionids.append(transaction.subscription_id) amounts.append(transaction.amount) dates.append(transaction.created_at) currencies.append(transaction.currency_iso_code) card_countries.append( transaction.credit_card_details.country_of_issuance) statuses.append(transaction.status) df = pd.DataFrame({ 'name':names, 'email':emails, 'date':dates, 'amount':amounts, 'currency':currencies, 'country':countries, 'card_country':card_countries, 'status':statuses, 'username':usernames, 'user_id':ownids, 'customer_id':customerids, 'transaction_id':transactionids, 'subscription_id':subscriptionids, 'address':addresses } ) return df def mocktest(rower): return '5'