aboutsummaryrefslogtreecommitdiff
path: root/app/app_wallet.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/app_wallet.py')
-rw-r--r--app/app_wallet.py95
1 files changed, 95 insertions, 0 deletions
diff --git a/app/app_wallet.py b/app/app_wallet.py
new file mode 100644
index 0000000..9dffbd5
--- /dev/null
+++ b/app/app_wallet.py
@@ -0,0 +1,95 @@
1# UGE / L2 / Intro to relational databases / Python project prototype
2# Author: Pacien TRAN-GIRARD
3# Licence: EUPL-1.2
4
5from decimal import Decimal
6
7from fastapi import APIRouter, Form, Depends, status
8
9from embrace.exceptions import IntegrityError
10from psycopg2.errors import CheckViolation
11from psycopg2.extensions import ISOLATION_LEVEL_SERIALIZABLE
12
13from app_sessions import UserSession
14from app_database import db_transaction
15
16
17router = APIRouter()
18
19
20# TODO: add paging for the transaction history
21@router.get('/wallet')
22def wallet(
23 session: UserSession=Depends(UserSession.authenticated),
24):
25 with db_transaction() as tx:
26 history = tx.fetch_transactions(user_id=session.get_user_id())
27 return list(history)
28
29
30@router.post('/wallet/transfer')
31def wallet_transfer(
32 session: UserSession=Depends(UserSession.authenticated),
33 recipient: str=Form(...),
34 amount: Decimal=Form(...),
35):
36 if amount <= 0:
37 return 'error: Invalid transaction amount.'
38
39 try:
40 with db_transaction(ISOLATION_LEVEL_SERIALIZABLE) as tx:
41 recipient_user = tx.fetch_account_username(username=recipient)
42 if recipient_user is None:
43 raise LookupError('Could not find recipient')
44
45 tx.transfer(
46 from_user_id=session.get_user_id(),
47 to_user_id=recipient_user.id,
48 amount=amount,
49 fee=amount * Decimal(0.10))
50
51 return 'Your business is appreciated.'
52
53 except LookupError as exception:
54 return 'error: ' + str(exception)
55
56 except IntegrityError as exception:
57 if isinstance(exception.__cause__, CheckViolation):
58 return 'error: Insufficient funds.'
59 else:
60 raise exception
61
62
63@router.post('/wallet/deposit')
64def wallet_deposit(
65 session: UserSession=Depends(UserSession.authenticated),
66 amount: Decimal=Form(...),
67):
68 if amount <= 0:
69 return 'error: Invalid transaction amount.'
70
71 with db_transaction(ISOLATION_LEVEL_SERIALIZABLE) as tx:
72 tx.deposit(user_id=session.get_user_id(), amount=amount)
73
74 return 'Your business is appreciated.'
75
76
77@router.post('/wallet/withdraw')
78def wallet_withdraw(
79 session: UserSession=Depends(UserSession.authenticated),
80 amount: Decimal=Form(...),
81):
82 if amount <= 0:
83 return 'error: Invalid transaction amount.'
84
85 try:
86 with db_transaction(ISOLATION_LEVEL_SERIALIZABLE) as tx:
87 tx.withdraw(user_id=session.get_user_id(), amount=amount)
88
89 return 'Annnnnd... It\'s gone.'
90
91 except IntegrityError as exception:
92 if isinstance(exception.__cause__, CheckViolation):
93 return 'error: Insufficient funds.'
94 else:
95 raise exception