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.py46
1 files changed, 33 insertions, 13 deletions
diff --git a/app/app_wallet.py b/app/app_wallet.py
index 9dffbd5..922c683 100644
--- a/app/app_wallet.py
+++ b/app/app_wallet.py
@@ -5,36 +5,45 @@
5from decimal import Decimal 5from decimal import Decimal
6 6
7from fastapi import APIRouter, Form, Depends, status 7from fastapi import APIRouter, Form, Depends, status
8from fastapi.responses import RedirectResponse, HTMLResponse
8 9
9from embrace.exceptions import IntegrityError 10from embrace.exceptions import IntegrityError
10from psycopg2.errors import CheckViolation 11from psycopg2.errors import CheckViolation
11from psycopg2.extensions import ISOLATION_LEVEL_SERIALIZABLE 12from psycopg2.extensions import ISOLATION_LEVEL_SERIALIZABLE
12 13
13from app_sessions import UserSession 14from app_sessions import UserSession, FlashMessageQueue
14from app_database import db_transaction 15from app_database import db_transaction
16from app_templating import TemplateRenderer
15 17
16 18
19to_wallet = RedirectResponse('/wallet', status_code=status.HTTP_303_SEE_OTHER)
20
17router = APIRouter() 21router = APIRouter()
18 22
19 23
20# TODO: add paging for the transaction history 24# TODO: add paging for the transaction history
21@router.get('/wallet') 25@router.get('/wallet', response_class=HTMLResponse)
22def wallet( 26def wallet(
23 session: UserSession=Depends(UserSession.authenticated), 27 session: UserSession=Depends(UserSession.authenticated),
28 messages: FlashMessageQueue=Depends(FlashMessageQueue),
29 render: TemplateRenderer=Depends(TemplateRenderer),
24): 30):
25 with db_transaction() as tx: 31 with db_transaction() as tx:
26 history = tx.fetch_transactions(user_id=session.get_user_id()) 32 history = tx.fetch_transactions(user_id=session.get_user_id())
27 return list(history) 33 # rendering done in the transaction to make use the iteration cursor
34 return render('wallet.html.jinja', transactions=history)
28 35
29 36
30@router.post('/wallet/transfer') 37@router.post('/wallet/transfer', response_class=HTMLResponse)
31def wallet_transfer( 38def wallet_transfer(
32 session: UserSession=Depends(UserSession.authenticated), 39 session: UserSession=Depends(UserSession.authenticated),
40 messages: FlashMessageQueue=Depends(FlashMessageQueue),
33 recipient: str=Form(...), 41 recipient: str=Form(...),
34 amount: Decimal=Form(...), 42 amount: Decimal=Form(...),
35): 43):
36 if amount <= 0: 44 if amount <= 0:
37 return 'error: Invalid transaction amount.' 45 messages.add('error', 'Invalid transaction amount.')
46 return to_wallet
38 47
39 try: 48 try:
40 with db_transaction(ISOLATION_LEVEL_SERIALIZABLE) as tx: 49 with db_transaction(ISOLATION_LEVEL_SERIALIZABLE) as tx:
@@ -48,14 +57,17 @@ def wallet_transfer(
48 amount=amount, 57 amount=amount,
49 fee=amount * Decimal(0.10)) 58 fee=amount * Decimal(0.10))
50 59
51 return 'Your business is appreciated.' 60 messages.add('success', 'Your business is appreciated.')
61 return to_wallet
52 62
53 except LookupError as exception: 63 except LookupError as exception:
54 return 'error: ' + str(exception) 64 messages.add('error', str(exception))
65 return to_wallet
55 66
56 except IntegrityError as exception: 67 except IntegrityError as exception:
57 if isinstance(exception.__cause__, CheckViolation): 68 if isinstance(exception.__cause__, CheckViolation):
58 return 'error: Insufficient funds.' 69 messages.add('error', 'Insufficient funds.')
70 return to_wallet
59 else: 71 else:
60 raise exception 72 raise exception
61 73
@@ -63,33 +75,41 @@ def wallet_transfer(
63@router.post('/wallet/deposit') 75@router.post('/wallet/deposit')
64def wallet_deposit( 76def wallet_deposit(
65 session: UserSession=Depends(UserSession.authenticated), 77 session: UserSession=Depends(UserSession.authenticated),
78 messages: FlashMessageQueue=Depends(FlashMessageQueue),
66 amount: Decimal=Form(...), 79 amount: Decimal=Form(...),
67): 80):
68 if amount <= 0: 81 if amount <= 0:
69 return 'error: Invalid transaction amount.' 82 messages.add('error', 'Invalid transaction amount.')
83 return to_wallet
70 84
71 with db_transaction(ISOLATION_LEVEL_SERIALIZABLE) as tx: 85 with db_transaction(ISOLATION_LEVEL_SERIALIZABLE) as tx:
72 tx.deposit(user_id=session.get_user_id(), amount=amount) 86 tx.deposit(user_id=session.get_user_id(), amount=amount)
73 87
74 return 'Your business is appreciated.' 88 messages.add('success', 'Your business is appreciated.')
89 return to_wallet
75 90
76 91
77@router.post('/wallet/withdraw') 92@router.post('/wallet/withdraw')
78def wallet_withdraw( 93def wallet_withdraw(
79 session: UserSession=Depends(UserSession.authenticated), 94 session: UserSession=Depends(UserSession.authenticated),
95 messages: FlashMessageQueue=Depends(FlashMessageQueue),
96 render: TemplateRenderer=Depends(TemplateRenderer),
80 amount: Decimal=Form(...), 97 amount: Decimal=Form(...),
81): 98):
82 if amount <= 0: 99 if amount <= 0:
83 return 'error: Invalid transaction amount.' 100 messages.add('error', 'Invalid transaction amount.')
101 return to_wallet
84 102
85 try: 103 try:
86 with db_transaction(ISOLATION_LEVEL_SERIALIZABLE) as tx: 104 with db_transaction(ISOLATION_LEVEL_SERIALIZABLE) as tx:
87 tx.withdraw(user_id=session.get_user_id(), amount=amount) 105 tx.withdraw(user_id=session.get_user_id(), amount=amount)
88 106
89 return 'Annnnnd... It\'s gone.' 107 messages.add('success', 'Annnnnd... It\'s gone.')
108 return render('launder.html.jinja')
90 109
91 except IntegrityError as exception: 110 except IntegrityError as exception:
92 if isinstance(exception.__cause__, CheckViolation): 111 if isinstance(exception.__cause__, CheckViolation):
93 return 'error: Insufficient funds.' 112 messages.add('error', 'Insufficient funds.')
113 return to_wallet
94 else: 114 else:
95 raise exception 115 raise exception