From a9be74fe46ae3a4f7047c7dfdb52ef62bc77a79d Mon Sep 17 00:00:00 2001
From: Fabian Krueger <fabian.krueger@fau.de>
Date: Fri, 20 Sep 2019 19:00:29 +0200
Subject: [PATCH] backend now supports getLastTransfersList function

---
 store/backend.py      | 45 +++++++++++++++++---
 store/store_config.py | 10 +++--
 store/views.py        | 98 ++++++++++++++++++++++++-------------------
 3 files changed, 103 insertions(+), 50 deletions(-)

diff --git a/store/backend.py b/store/backend.py
index b8ad6ec..a5cf629 100644
--- a/store/backend.py
+++ b/store/backend.py
@@ -308,11 +308,11 @@ class TransferLogic:
     Returns a list of users that are possible recepiants for a transfer of money. The list first containts receivers
     that are often addressed by the specified user and after that users that have never been addressed.
     @param user_id: the id of the user thats receivers should be shown
-    @config-param max_receivers: depends on N_TRANSFER_RECEIVERS
+    @config-param max_receivers: depends on N_TRANSFERS_RECEIVERS
     """ 
     @staticmethod
     def getFreuquentTransferTargeds(user_id):
-        max_receivers = config['N_TRANSFER_RECEIVERS']
+        max_receivers = config['N_TRANSFERS_RECEIVERS']
         transfers = Transfer.objects.filter(sender=user_id).exclude(receiver=None).exclude(receiver=user_id)
         transfers = transfers.select_related('receiver')
         transfers = transfers.values('receiver', 'receiver__nickname')
@@ -322,6 +322,38 @@ class TransferLogic:
             transfers = transfers[:max_receivers]
         return list(transfers)
 
+    """
+    Returns a list of last transfers of a specified user sorted by the time of the transfer.
+    @param user_id: the id of the user that is logged in and wants to send money
+    @config-param max_transfers: depends on N_LAST_TRANSFERS
+    @config-param annullable_time: depends on T_ANNULLABLE_TRANSFERS_M
+    """
+    @staticmethod
+    def getLastTransfers(user_id):
+        max_transfers = config['N_LAST_TRANSFERS']
+        annullable_time = config['T_ANNULLABLE_TRANSFERS_M']
+
+        transfers = Transfer.objects.filter(sender=user_id)
+        transfers = transfers.select_related('receiver')
+        transfers = transfers.order_by('time_stamp').reverse()[:max_transfers]
+        transfers = transfers.values('id', 'annullated', 'amount', 'receiver__nickname', 'time_stamp')
+
+        # warning: summertime/wintertime currently is not respected in the following calculations. This should be
+        # implemented to avoid non-annullable transactions in the lost hour between summer- and wintertime
+        now = datetime.now()
+        time_limit = datetime.now() - timedelta(minutes=annullable_time)
+        timezone = pytz.timezone('Europe/Berlin')
+        time_limit = timezone.localize(time_limit)
+
+        for transfer in transfers:
+            if time_limit > transfer['time_stamp']:
+                transfer.update({'annullable': False})
+            else:
+                transfer.update({'annullable': True})
+            transfer['receiver_nickname'] = transfer.pop('receiver__nickname')
+        
+        return list(transfers)
+
     """
     Performs the transfer routine where a sender sends money to a receiver.
     @param user_id: id of the user that wants to send money
@@ -334,7 +366,7 @@ class TransferLogic:
         sender = list(User.objects.filter(id=user_id))[0]
         receiver = list(User.objects.filter(id=receiver_id))[0]
         try:
-            with transfer.atomic():
+            with transaction.atomic():
                 transfer_id = TransferLogic.__createTransferTuple(sender, receiver, amount, token)
                 TransferLogic.__updateSenderMoney(sender, amount)
                 TransferLogic.__updateReceiverMoney(receiver, amount)
@@ -342,15 +374,18 @@ class TransferLogic:
             return list(Transfers.objects.filter(token=token))[0]
         return transfer_id
 
-
+    @staticmethod
     def __createTransferTuple(sender, receiver, amount, token):
-        transfer = Transfer(sender=sender, receiver=receiver, amount=amount, token=token, annulated=False)
+        transfer = Transfer(sender=sender, receiver=receiver, amount=amount, token=token, annullated=False)
         transfer.save()
         return transfer.id
 
+    @staticmethod
     def __updateSenderMoney(sender, amount):
         sender.updateMoney((-1) * amount)
 
+    @staticmethod
     def __updateReceiverMoney(receiver, amount):
         receiver.updateMoney(amount) 
 
+
diff --git a/store/store_config.py b/store/store_config.py
index 6fdad47..d092b7a 100644
--- a/store/store_config.py
+++ b/store/store_config.py
@@ -9,9 +9,11 @@ N_USERS_LOGIN: number of users that should be shown in the users list in the log
 T_USERS_LOGIN_D: number of days in the past that are used as time intervall limit to search for users
 N_LAST_CHARGES: number of charges that should be shown in 'Letzte Aufladungen'. A negative number means 'all users are
     selected'
-T_ANNULLABLE_CHARGE_M: time of minutes a user has for a charge to undo it
-N_TRANSFER_RECEIVERS: number of receivers that should be shown in 'alle Überweisungen'. A negative value means 'all
+T_ANNULLABLE_CHARGE_M: time in minutes a user has for a charge to undo it
+N_TRANSFERS_RECEIVERS: number of receivers that should be shown in 'alle Empfänger'. A negative value means 'all
 users are shown'
+N_LAST_TRANSFERS: number of transfers that should be shown in 'Letzte Überweisungen'
+T_ANNULLABLE_TRANSFERS_M: time in minutes a user has for a transfer to undo it
 """
 KAFFEEKASSE = {'N_LAST_BOUGHT_PRODUCTS': 5,
                'T_LAST_BOUGHT_PRODUCTS_D': 30,
@@ -22,5 +24,7 @@ KAFFEEKASSE = {'N_LAST_BOUGHT_PRODUCTS': 5,
                'T_USERS_LOGIN_D': 356,
                'N_LAST_CHARGES': 10,
                'T_ANNULLABLE_CHARGE_M': 60,
-               'N_TRANSFER_RECEIVERS': -1,
+               'N_TRANSFERS_RECEIVERS': -1,
+               'N_LAST_TRANSFERS': 5,
+               'T_ANNULLABLE_TRANSFERS_M': 60,
                }
diff --git a/store/views.py b/store/views.py
index c1ad43a..98ce7df 100644
--- a/store/views.py
+++ b/store/views.py
@@ -40,47 +40,52 @@ def charge(request):
 @login_required(login_url="index")
 @require_http_methods(["GET"])
 def transfer(request):
-    dummyTransfers = [
-        {
-            "id": 1,
-            "annullated": True,
-            "annullable": False,
-            "amount": 12.4,
-            "receiver_nickname": "franz",
-        },
-        {
-            "id": 2,
-            "annullated": False,
-            "annullable": True,
-            "amount": 12.4,
-            "receiver_nickname": "hans"
-        },
-        {
-            "id": 3,
-            "annullated": True,
-            "annullable": False,
-            "amount": 12.4,
-            "receiver_nickname": "fritz"
-        },
-        {
-            "id": 4,
-            "annullated": True,
-            "annullable": False,
-            "amount": 11.4,
-            "receiver_nickname": "peter"
-        },
-        {
-            "id": 5,
-            "annullated": False,
-            "annullable": False,
-            "amount": 13.4,
-            "receiver_nickname": "scooter"
-        }
-    ]
     return render(request, "transfer.html", {
+        # "users": TransferLogic.getFreuquentTransferTargeds(request.user.id),
         "users": User.objects.all(),
-        "recent_transfers": dummyTransfers,
-    })
+        "recent_transfers": TransferLogic.getLastTransfers(request.user.id),
+        })
+    # dummyTransfers = [
+    #     {
+    #         "id": 1,
+    #         "annullated": True,
+    #         "annullable": False,
+    #         "amount": 12.4,
+    #         "receiver_nickname": "franz",
+    #     },
+    #     {
+    #         "id": 2,
+    #         "annullated": False,
+    #         "annullable": True,
+    #         "amount": 12.4,
+    #         "receiver_nickname": "hans"
+    #     },
+    #     {
+    #         "id": 3,
+    #         "annullated": True,
+    #         "annullable": False,
+    #         "amount": 12.4,
+    #         "receiver_nickname": "fritz"
+    #     },
+    #     {
+    #         "id": 4,
+    #         "annullated": True,
+    #         "annullable": False,
+    #         "amount": 11.4,
+    #         "receiver_nickname": "peter"
+    #     },
+    #     {
+    #         "id": 5,
+    #         "annullated": False,
+    #         "annullable": False,
+    #         "amount": 13.4,
+    #         "receiver_nickname": "scooter"
+    #     }
+    # ]
+    # return render(request, "transfer.html", {
+    #     "users": User.objects.all(),
+    #     "recent_transfers": dummyTransfers,
+    # })
 
 
 # Authentication
@@ -141,7 +146,6 @@ def revert_purchase(request):
 @login_required(login_url="index")
 @require_http_methods(["POST"])
 def charge_money(request):
-    print(request.POST)
     user_id = request.user.id
     token = request.POST.get("token")
     amount = request.POST.get("amount")
@@ -163,7 +167,13 @@ def revert_charge(request):
 
 
 def transfer_money(request):
-    return JsonResponse({"transfer_id": 3})
+    print(request.POST)
+    user_id = request.user.id
+    token = request.POST.get("token")
+    receiver_id = request.POST.get("receiver")
+    amount = Decimal(request.POST.get("amount"))
+    transfer_id = TransferLogic.transfer(user_id, receiver_id, amount, token)
+    return JsonResponse({"transfer_id": transfer_id})
 
 
 def revert_transfer(request):
@@ -178,4 +188,8 @@ def test(request):
 
 
 def test2(request):
-    ChargeLogic.annullateCharge(1900)
+    transfers = TransferLogic.getFreuquentTransferTargeds(1)
+    for transfer in transfers:
+        print(transfer)
+    print("n_transfers:", len(transfers))
+
-- 
GitLab