diff options
Diffstat (limited to 'app/app_wallet.py')
-rw-r--r-- | app/app_wallet.py | 46 |
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 @@ | |||
5 | from decimal import Decimal | 5 | from decimal import Decimal |
6 | 6 | ||
7 | from fastapi import APIRouter, Form, Depends, status | 7 | from fastapi import APIRouter, Form, Depends, status |
8 | from fastapi.responses import RedirectResponse, HTMLResponse | ||
8 | 9 | ||
9 | from embrace.exceptions import IntegrityError | 10 | from embrace.exceptions import IntegrityError |
10 | from psycopg2.errors import CheckViolation | 11 | from psycopg2.errors import CheckViolation |
11 | from psycopg2.extensions import ISOLATION_LEVEL_SERIALIZABLE | 12 | from psycopg2.extensions import ISOLATION_LEVEL_SERIALIZABLE |
12 | 13 | ||
13 | from app_sessions import UserSession | 14 | from app_sessions import UserSession, FlashMessageQueue |
14 | from app_database import db_transaction | 15 | from app_database import db_transaction |
16 | from app_templating import TemplateRenderer | ||
15 | 17 | ||
16 | 18 | ||
19 | to_wallet = RedirectResponse('/wallet', status_code=status.HTTP_303_SEE_OTHER) | ||
20 | |||
17 | router = APIRouter() | 21 | router = 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) |
22 | def wallet( | 26 | def 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) |
31 | def wallet_transfer( | 38 | def 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') |
64 | def wallet_deposit( | 76 | def 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') |
78 | def wallet_withdraw( | 93 | def 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 |