Remove machina, remove default cache config, add some upgrades and compatibility...
[wolnelektury.git] / src / paypal / rest.py
index 3590c6f..11693cb 100644 (file)
@@ -1,17 +1,15 @@
-# -*- coding: utf-8 -*-
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from datetime import timedelta
-
+from datetime import date, datetime, timedelta
+from decimal import Decimal
 import paypalrestsdk
 import pytz
 from django.contrib.sites.models import Site
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 from django.utils import timezone
-from paypalrestsdk import BillingPlan, BillingAgreement, ResourceNotFound
 from django.conf import settings
-from .models import BillingPlan as BillingPlanModel, BillingAgreement as BillingAgreementModel
+from .models import BillingPlan, BillingAgreement
 
 paypalrestsdk.configure(settings.PAYPAL_CONFIG)
 
@@ -20,17 +18,17 @@ class PaypalError(Exception):
     pass
 
 
-def absolute_url(url_name):
-    return "http://%s%s" % (Site.objects.get_current().domain, reverse(url_name))
+def absolute_url(url_name, kwargs=None):
+    return "http://%s%s" % (Site.objects.get_current().domain, reverse(url_name, kwargs=kwargs))
 
 
 def create_plan(amount):
-    billing_plan = BillingPlan({
+    billing_plan = paypalrestsdk.BillingPlan({
         "name": "Cykliczna darowizna na Wolne Lektury: %s zł" % amount,
         "description": "Cykliczna darowizna na wsparcie Wolnych Lektur",
         "merchant_preferences": {
             "auto_bill_amount": "yes",
-            "return_url": absolute_url('paypal_return'),
+            "return_url": absolute_url('paypal_return', {'key': '-'}),
             "cancel_url": absolute_url('paypal_cancel'),
             # "initial_fail_amount_action": "continue",
             "max_fail_attempts": "3",
@@ -55,7 +53,7 @@ def create_plan(amount):
         raise PaypalError(billing_plan.error)
     if not billing_plan.activate():
         raise PaypalError(billing_plan.error)
-    plan, created = BillingPlanModel.objects.get_or_create(amount=amount, defaults={'plan_id': billing_plan.id})
+    plan, created = BillingPlan.objects.get_or_create(amount=amount, defaults={'plan_id': billing_plan.id})
     return plan.plan_id
 
 
@@ -65,17 +63,17 @@ def get_link(links, rel):
             return link.href
 
 
-def create_agreement(amount, app=False):
+def create_agreement(amount, key, app=False):
     try:
-        plan = BillingPlanModel.objects.get(amount=amount)
-    except BillingPlanModel.DoesNotExist:
+        plan = BillingPlan.objects.get(amount=amount)
+    except BillingPlan.DoesNotExist:
         plan_id = create_plan(amount)
     else:
         plan_id = plan.plan_id
     start = (timezone.now() + timedelta(0, 3600*24)).astimezone(pytz.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
-    billing_agreement = BillingAgreement({
-        "name": u"Subskrypcja klubu WL",
-        "description": u"Stałe wsparcie Wolnych Lektur kwotą %s złotych" % amount,
+    billing_agreement = paypalrestsdk.BillingAgreement({
+        "name": "Subskrypcja klubu WL",
+        "description": "Stałe wsparcie Wolnych Lektur kwotą %s złotych" % amount,
         "start_date": start,
         "plan": {
             "id": plan_id,
@@ -86,9 +84,14 @@ def create_agreement(amount, app=False):
     })
     if app:
         billing_agreement['override_merchant_preferences'] = {
-            'return_url': absolute_url('paypal_app_return'),
+            'return_url': absolute_url('paypal_app_return', {'key': key}),
+        }
+    else:
+        billing_agreement['override_merchant_preferences'] = {
+            'return_url': absolute_url('paypal_return', {'key': key}),
         }
 
+
     response = billing_agreement.create()
     if response:
         return billing_agreement
@@ -96,15 +99,15 @@ def create_agreement(amount, app=False):
         raise PaypalError(billing_agreement.error)
 
 
-def agreement_approval_url(amount, app=False):
-    agreement = create_agreement(amount, app=app)
+def agreement_approval_url(amount, key, app=False):
+    agreement = create_agreement(amount, key, app=app)
     return get_link(agreement.links, 'approval_url')
 
 
 def get_agreement(agreement_id):
     try:
-        return BillingAgreement.find(agreement_id)
-    except ResourceNotFound:
+        return paypalrestsdk.BillingAgreement.find(agreement_id)
+    except paypalrestsdk.ResourceNotFound:
         return None
 
 
@@ -114,10 +117,27 @@ def check_agreement(agreement_id):
         return a.state == 'Active'
 
 
-def user_is_subscribed(user):
-    agreements = BillingAgreementModel.objects.filter(user=user)
-    return any(agreement.check_agreement() for agreement in agreements)
+def execute_agreement(token):
+    return paypalrestsdk.BillingAgreement.execute(token)
 
 
-def execute_agreement(token):
-    return BillingAgreement.execute(token)
+def get_donations(agreement_id, year):
+    a = get_agreement(agreement_id)
+    transactions = []
+    for transaction in a.search_transactions(
+            date(year - 1, 12, 31),
+            date(year + 1, 1, 1))['agreement_transaction_list']:
+        if transaction['status'] != 'Completed':
+            continue
+        dt = datetime.strptime(
+            transaction['time_stamp'],
+            '%Y-%m-%dT%H:%M:%S%z'
+        ).astimezone()
+        if dt.year != year:
+            continue
+        assert transaction['amount']['currency'] == 'PLN'
+        transactions.append({
+            'timestamp': dt,
+            'amount': Decimal(transaction['amount']['value'])
+        })
+    return transactions