Spaces:
Runtime error
Runtime error
Upload 24 files
Browse files- Dockerfile +20 -0
- Jenkinsfile +53 -0
- Procfile +1 -0
- app.py +165 -0
- min ibank/Dockerfile +20 -0
- min ibank/app.py +165 -0
- min ibank/pycash.db +0 -0
- min ibank/requirements.txt +6 -0
- min ibank/static/requirements.txt +5 -0
- min ibank/static/styles.css +120 -0
- min ibank/templates/add_deposit.html +23 -0
- min ibank/templates/add_payment.html +30 -0
- min ibank/templates/index.html +19 -0
- min ibank/templates/requirements.txt +5 -0
- min ibank/templates/view_finances.html +31 -0
- pycash.db +0 -0
- requirements.txt +6 -0
- static/requirements.txt +5 -0
- static/styles.css +120 -0
- templates/add_deposit.html +23 -0
- templates/add_payment.html +30 -0
- templates/index.html +19 -0
- templates/requirements.txt +5 -0
- templates/view_finances.html +31 -0
Dockerfile
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Use an official Python runtime as a parent images
|
2 |
+
FROM python:3.9-slim
|
3 |
+
|
4 |
+
# Set the working directory in the container
|
5 |
+
WORKDIR /app
|
6 |
+
|
7 |
+
# Copy the current directory contents into the container at /app
|
8 |
+
COPY . /app
|
9 |
+
|
10 |
+
# Install any needed dependencies specified in requirements.txt
|
11 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
12 |
+
|
13 |
+
# Expose port 5000 to the outside world
|
14 |
+
EXPOSE 5000
|
15 |
+
|
16 |
+
# Define environment variable
|
17 |
+
ENV FLASK_APP=app.py
|
18 |
+
|
19 |
+
# Run app.py when the container launches
|
20 |
+
CMD ["flask", "run", "--host=0.0.0.0"]
|
Jenkinsfile
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
pipeline {
|
2 |
+
agent any
|
3 |
+
|
4 |
+
environment {
|
5 |
+
DOCKER_IMAGE = "my-flask-app:latest"
|
6 |
+
}
|
7 |
+
|
8 |
+
stages {
|
9 |
+
stage('Checkout SCM') {
|
10 |
+
steps {
|
11 |
+
checkout([$class: 'GitSCM', branches: [[name: '*/main']],
|
12 |
+
userRemoteConfigs: [[url: 'https://github.com/iamironman4279/bk.git']]
|
13 |
+
])
|
14 |
+
}
|
15 |
+
}
|
16 |
+
|
17 |
+
stage('Build Docker Image') {
|
18 |
+
steps {
|
19 |
+
script {
|
20 |
+
sh 'docker build -t ${DOCKER_IMAGE} .'
|
21 |
+
}
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
+
stage('Run Docker Container') {
|
26 |
+
steps {
|
27 |
+
script {
|
28 |
+
sh 'docker run -d -p 5000:5000 ${DOCKER_IMAGE}'
|
29 |
+
}
|
30 |
+
}
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
post {
|
35 |
+
always {
|
36 |
+
script {
|
37 |
+
try {
|
38 |
+
sh 'docker ps -a'
|
39 |
+
} catch (Exception e) {
|
40 |
+
echo "Error in post stage: ${e.getMessage()}"
|
41 |
+
}
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
success {
|
46 |
+
echo 'Pipeline completed successfully.'
|
47 |
+
}
|
48 |
+
|
49 |
+
failure {
|
50 |
+
echo 'Pipeline failed.'
|
51 |
+
}
|
52 |
+
}
|
53 |
+
}
|
Procfile
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
web: gunicorn app:app
|
app.py
ADDED
@@ -0,0 +1,165 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from flask import Flask, render_template, request, redirect, url_for, send_file, flash
|
2 |
+
import sqlite3
|
3 |
+
from reportlab.lib.pagesizes import letter
|
4 |
+
from reportlab.pdfgen import canvas
|
5 |
+
import io
|
6 |
+
from datetime import datetime
|
7 |
+
|
8 |
+
app = Flask(__name__)
|
9 |
+
app.secret_key = 'your_secret_key' # Needed for flashing messages
|
10 |
+
|
11 |
+
def init_db():
|
12 |
+
conn = sqlite3.connect('pycash.db')
|
13 |
+
c = conn.cursor()
|
14 |
+
c.execute('''
|
15 |
+
CREATE TABLE IF NOT EXISTS transactions (
|
16 |
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
17 |
+
type TEXT,
|
18 |
+
amount REAL,
|
19 |
+
recipient TEXT,
|
20 |
+
date TEXT,
|
21 |
+
memo TEXT
|
22 |
+
)
|
23 |
+
''')
|
24 |
+
c.execute('''
|
25 |
+
CREATE TABLE IF NOT EXISTS balance (
|
26 |
+
id INTEGER PRIMARY KEY,
|
27 |
+
total REAL
|
28 |
+
)
|
29 |
+
''')
|
30 |
+
c.execute('SELECT COUNT(*) FROM balance')
|
31 |
+
if c.fetchone()[0] == 0:
|
32 |
+
c.execute('INSERT INTO balance (id, total) VALUES (1, 0)')
|
33 |
+
conn.commit()
|
34 |
+
conn.close()
|
35 |
+
|
36 |
+
init_db()
|
37 |
+
|
38 |
+
def update_balance(amount, operation):
|
39 |
+
conn = sqlite3.connect('pycash.db')
|
40 |
+
c = conn.cursor()
|
41 |
+
c.execute('SELECT total FROM balance WHERE id = 1')
|
42 |
+
current_balance = c.fetchone()[0]
|
43 |
+
new_balance = current_balance + amount if operation == 'deposit' else current_balance - amount
|
44 |
+
c.execute('UPDATE balance SET total = ? WHERE id = 1', (new_balance,))
|
45 |
+
conn.commit()
|
46 |
+
conn.close()
|
47 |
+
|
48 |
+
@app.route('/')
|
49 |
+
def index():
|
50 |
+
return render_template('index.html')
|
51 |
+
|
52 |
+
@app.route('/add_payment', methods=['GET', 'POST'])
|
53 |
+
def add_payment():
|
54 |
+
if request.method == 'POST':
|
55 |
+
amount = float(request.form['dollars'])
|
56 |
+
payment_to = request.form['paymentTo']
|
57 |
+
date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
58 |
+
memo = request.form.get('memo', '')
|
59 |
+
|
60 |
+
conn = sqlite3.connect('pycash.db')
|
61 |
+
c = conn.cursor()
|
62 |
+
c.execute('SELECT total FROM balance WHERE id = 1')
|
63 |
+
current_balance = c.fetchone()[0]
|
64 |
+
|
65 |
+
if amount > current_balance:
|
66 |
+
flash('Insufficient funds!')
|
67 |
+
return redirect(url_for('add_payment'))
|
68 |
+
|
69 |
+
c.execute('''
|
70 |
+
INSERT INTO transactions (type, amount, recipient, date, memo)
|
71 |
+
VALUES (?, ?, ?, ?, ?)
|
72 |
+
''', ('Payment', amount, payment_to, date, memo))
|
73 |
+
conn.commit()
|
74 |
+
conn.close()
|
75 |
+
|
76 |
+
update_balance(amount, 'payment')
|
77 |
+
|
78 |
+
return redirect(url_for('index'))
|
79 |
+
return render_template('add_payment.html')
|
80 |
+
|
81 |
+
@app.route('/add_deposit', methods=['GET', 'POST'])
|
82 |
+
def add_deposit():
|
83 |
+
if request.method == 'POST':
|
84 |
+
amount = float(request.form['dollars'])
|
85 |
+
date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
86 |
+
memo = request.form.get('memo', '')
|
87 |
+
|
88 |
+
conn = sqlite3.connect('pycash.db')
|
89 |
+
c = conn.cursor()
|
90 |
+
c.execute('''
|
91 |
+
INSERT INTO transactions (type, amount, recipient, date, memo)
|
92 |
+
VALUES (?, ?, ?, ?, ?)
|
93 |
+
''', ('Deposit', amount, '', date, memo))
|
94 |
+
conn.commit()
|
95 |
+
conn.close()
|
96 |
+
|
97 |
+
update_balance(amount, 'deposit')
|
98 |
+
|
99 |
+
return redirect(url_for('index'))
|
100 |
+
return render_template('add_deposit.html')
|
101 |
+
|
102 |
+
@app.route('/view_finances', methods=['GET'])
|
103 |
+
def view_finances():
|
104 |
+
conn = sqlite3.connect('pycash.db')
|
105 |
+
c = conn.cursor()
|
106 |
+
c.execute('SELECT * FROM transactions')
|
107 |
+
transactions = c.fetchall()
|
108 |
+
c.execute('SELECT total FROM balance WHERE id = 1')
|
109 |
+
balance = c.fetchone()[0]
|
110 |
+
conn.close()
|
111 |
+
return render_template('view_finances.html', transactions=transactions, balance=balance)
|
112 |
+
|
113 |
+
@app.route('/generate_pdf')
|
114 |
+
def generate_pdf():
|
115 |
+
conn = sqlite3.connect('pycash.db')
|
116 |
+
c = conn.cursor()
|
117 |
+
c.execute('SELECT * FROM transactions')
|
118 |
+
transactions = c.fetchall()
|
119 |
+
c.execute('SELECT total FROM balance WHERE id = 1')
|
120 |
+
balance = c.fetchone()[0]
|
121 |
+
conn.close()
|
122 |
+
|
123 |
+
pdf_buffer = io.BytesIO()
|
124 |
+
pdf = canvas.Canvas(pdf_buffer, pagesize=letter)
|
125 |
+
width, height = letter
|
126 |
+
|
127 |
+
pdf.setFont("Helvetica-Bold", 16)
|
128 |
+
pdf.drawString(30, height - 30, "Transaction Statement")
|
129 |
+
|
130 |
+
pdf.setFont("Helvetica-Bold", 12)
|
131 |
+
pdf.drawString(30, height - 60, "Type")
|
132 |
+
pdf.drawString(120, height - 60, "Amount")
|
133 |
+
pdf.drawString(210, height - 60, "Date")
|
134 |
+
pdf.drawString(300, height - 60, "From")
|
135 |
+
|
136 |
+
y = height - 80
|
137 |
+
pdf.setFont("Helvetica", 12)
|
138 |
+
for transaction in transactions:
|
139 |
+
transaction_type, amount, recipient, date, memo = transaction[1], transaction[2], transaction[3], transaction[4], transaction[5]
|
140 |
+
pdf.drawString(30, y, transaction_type)
|
141 |
+
pdf.drawString(120, y, f"₹{amount:.2f}")
|
142 |
+
pdf.drawString(210, y, date)
|
143 |
+
pdf.drawString(300, y, From)
|
144 |
+
y -= 20
|
145 |
+
|
146 |
+
pdf.setFont("Helvetica-Bold", 14)
|
147 |
+
pdf.drawString(30, y - 20, f"Current Balance: ₹{balance:.2f}")
|
148 |
+
|
149 |
+
pdf.save()
|
150 |
+
pdf_buffer.seek(0)
|
151 |
+
|
152 |
+
return send_file(pdf_buffer, as_attachment=True, download_name='statement.pdf', mimetype='application/pdf')
|
153 |
+
|
154 |
+
@app.route('/clear_transactions', methods=['POST'])
|
155 |
+
def clear_transactions():
|
156 |
+
conn = sqlite3.connect('pycash.db')
|
157 |
+
c = conn.cursor()
|
158 |
+
c.execute('DELETE FROM transactions')
|
159 |
+
c.execute('UPDATE balance SET total = 0 WHERE id = 1')
|
160 |
+
conn.commit()
|
161 |
+
conn.close()
|
162 |
+
return redirect(url_for('index'))
|
163 |
+
|
164 |
+
if __name__ == '__main__':
|
165 |
+
app.run(debug=True)
|
min ibank/Dockerfile
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Use an official Python runtime as a parent image
|
2 |
+
FROM python:3.9-slim
|
3 |
+
|
4 |
+
# Set the working directory in the container
|
5 |
+
WORKDIR /app
|
6 |
+
|
7 |
+
# Copy the current directory contents into the container at /app
|
8 |
+
COPY . /app
|
9 |
+
|
10 |
+
# Install any needed dependencies specified in requirements.txt
|
11 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
12 |
+
|
13 |
+
# Expose port 5000 to the outside world
|
14 |
+
EXPOSE 5000
|
15 |
+
|
16 |
+
# Define environment variable
|
17 |
+
ENV FLASK_APP=app.py
|
18 |
+
|
19 |
+
# Run app.py when the container launches
|
20 |
+
CMD ["flask", "run", "--host=0.0.0.0"]
|
min ibank/app.py
ADDED
@@ -0,0 +1,165 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from flask import Flask, render_template, request, redirect, url_for, send_file, flash
|
2 |
+
import sqlite3
|
3 |
+
from reportlab.lib.pagesizes import letter
|
4 |
+
from reportlab.pdfgen import canvas
|
5 |
+
import io
|
6 |
+
from datetime import datetime
|
7 |
+
|
8 |
+
app = Flask(__name__)
|
9 |
+
app.secret_key = 'your_secret_key' # Needed for flashing messages
|
10 |
+
|
11 |
+
def init_db():
|
12 |
+
conn = sqlite3.connect('pycash.db')
|
13 |
+
c = conn.cursor()
|
14 |
+
c.execute('''
|
15 |
+
CREATE TABLE IF NOT EXISTS transactions (
|
16 |
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
17 |
+
type TEXT,
|
18 |
+
amount REAL,
|
19 |
+
recipient TEXT,
|
20 |
+
date TEXT,
|
21 |
+
memo TEXT
|
22 |
+
)
|
23 |
+
''')
|
24 |
+
c.execute('''
|
25 |
+
CREATE TABLE IF NOT EXISTS balance (
|
26 |
+
id INTEGER PRIMARY KEY,
|
27 |
+
total REAL
|
28 |
+
)
|
29 |
+
''')
|
30 |
+
c.execute('SELECT COUNT(*) FROM balance')
|
31 |
+
if c.fetchone()[0] == 0:
|
32 |
+
c.execute('INSERT INTO balance (id, total) VALUES (1, 0)')
|
33 |
+
conn.commit()
|
34 |
+
conn.close()
|
35 |
+
|
36 |
+
init_db()
|
37 |
+
|
38 |
+
def update_balance(amount, operation):
|
39 |
+
conn = sqlite3.connect('pycash.db')
|
40 |
+
c = conn.cursor()
|
41 |
+
c.execute('SELECT total FROM balance WHERE id = 1')
|
42 |
+
current_balance = c.fetchone()[0]
|
43 |
+
new_balance = current_balance + amount if operation == 'deposit' else current_balance - amount
|
44 |
+
c.execute('UPDATE balance SET total = ? WHERE id = 1', (new_balance,))
|
45 |
+
conn.commit()
|
46 |
+
conn.close()
|
47 |
+
|
48 |
+
@app.route('/')
|
49 |
+
def index():
|
50 |
+
return render_template('index.html')
|
51 |
+
|
52 |
+
@app.route('/add_payment', methods=['GET', 'POST'])
|
53 |
+
def add_payment():
|
54 |
+
if request.method == 'POST':
|
55 |
+
amount = float(request.form['dollars'])
|
56 |
+
payment_to = request.form['paymentTo']
|
57 |
+
date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
58 |
+
memo = request.form.get('memo', '')
|
59 |
+
|
60 |
+
conn = sqlite3.connect('pycash.db')
|
61 |
+
c = conn.cursor()
|
62 |
+
c.execute('SELECT total FROM balance WHERE id = 1')
|
63 |
+
current_balance = c.fetchone()[0]
|
64 |
+
|
65 |
+
if amount > current_balance:
|
66 |
+
flash('Insufficient funds!')
|
67 |
+
return redirect(url_for('add_payment'))
|
68 |
+
|
69 |
+
c.execute('''
|
70 |
+
INSERT INTO transactions (type, amount, recipient, date, memo)
|
71 |
+
VALUES (?, ?, ?, ?, ?)
|
72 |
+
''', ('Payment', amount, payment_to, date, memo))
|
73 |
+
conn.commit()
|
74 |
+
conn.close()
|
75 |
+
|
76 |
+
update_balance(amount, 'payment')
|
77 |
+
|
78 |
+
return redirect(url_for('index'))
|
79 |
+
return render_template('add_payment.html')
|
80 |
+
|
81 |
+
@app.route('/add_deposit', methods=['GET', 'POST'])
|
82 |
+
def add_deposit():
|
83 |
+
if request.method == 'POST':
|
84 |
+
amount = float(request.form['dollars'])
|
85 |
+
date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
86 |
+
memo = request.form.get('memo', '')
|
87 |
+
|
88 |
+
conn = sqlite3.connect('pycash.db')
|
89 |
+
c = conn.cursor()
|
90 |
+
c.execute('''
|
91 |
+
INSERT INTO transactions (type, amount, recipient, date, memo)
|
92 |
+
VALUES (?, ?, ?, ?, ?)
|
93 |
+
''', ('Deposit', amount, '', date, memo))
|
94 |
+
conn.commit()
|
95 |
+
conn.close()
|
96 |
+
|
97 |
+
update_balance(amount, 'deposit')
|
98 |
+
|
99 |
+
return redirect(url_for('index'))
|
100 |
+
return render_template('add_deposit.html')
|
101 |
+
|
102 |
+
@app.route('/view_finances', methods=['GET'])
|
103 |
+
def view_finances():
|
104 |
+
conn = sqlite3.connect('pycash.db')
|
105 |
+
c = conn.cursor()
|
106 |
+
c.execute('SELECT * FROM transactions')
|
107 |
+
transactions = c.fetchall()
|
108 |
+
c.execute('SELECT total FROM balance WHERE id = 1')
|
109 |
+
balance = c.fetchone()[0]
|
110 |
+
conn.close()
|
111 |
+
return render_template('view_finances.html', transactions=transactions, balance=balance)
|
112 |
+
|
113 |
+
@app.route('/generate_pdf')
|
114 |
+
def generate_pdf():
|
115 |
+
conn = sqlite3.connect('pycash.db')
|
116 |
+
c = conn.cursor()
|
117 |
+
c.execute('SELECT * FROM transactions')
|
118 |
+
transactions = c.fetchall()
|
119 |
+
c.execute('SELECT total FROM balance WHERE id = 1')
|
120 |
+
balance = c.fetchone()[0]
|
121 |
+
conn.close()
|
122 |
+
|
123 |
+
pdf_buffer = io.BytesIO()
|
124 |
+
pdf = canvas.Canvas(pdf_buffer, pagesize=letter)
|
125 |
+
width, height = letter
|
126 |
+
|
127 |
+
pdf.setFont("Helvetica-Bold", 16)
|
128 |
+
pdf.drawString(30, height - 30, "Transaction Statement")
|
129 |
+
|
130 |
+
pdf.setFont("Helvetica-Bold", 12)
|
131 |
+
pdf.drawString(30, height - 60, "Type")
|
132 |
+
pdf.drawString(120, height - 60, "Amount")
|
133 |
+
pdf.drawString(210, height - 60, "Date")
|
134 |
+
pdf.drawString(300, height - 60, "From")
|
135 |
+
|
136 |
+
y = height - 80
|
137 |
+
pdf.setFont("Helvetica", 12)
|
138 |
+
for transaction in transactions:
|
139 |
+
transaction_type, amount, recipient, date, memo = transaction[1], transaction[2], transaction[3], transaction[4], transaction[5]
|
140 |
+
pdf.drawString(30, y, transaction_type)
|
141 |
+
pdf.drawString(120, y, f"₹{amount:.2f}")
|
142 |
+
pdf.drawString(210, y, date)
|
143 |
+
pdf.drawString(300, y, From)
|
144 |
+
y -= 20
|
145 |
+
|
146 |
+
pdf.setFont("Helvetica-Bold", 14)
|
147 |
+
pdf.drawString(30, y - 20, f"Current Balance: ₹{balance:.2f}")
|
148 |
+
|
149 |
+
pdf.save()
|
150 |
+
pdf_buffer.seek(0)
|
151 |
+
|
152 |
+
return send_file(pdf_buffer, as_attachment=True, download_name='statement.pdf', mimetype='application/pdf')
|
153 |
+
|
154 |
+
@app.route('/clear_transactions', methods=['POST'])
|
155 |
+
def clear_transactions():
|
156 |
+
conn = sqlite3.connect('pycash.db')
|
157 |
+
c = conn.cursor()
|
158 |
+
c.execute('DELETE FROM transactions')
|
159 |
+
c.execute('UPDATE balance SET total = 0 WHERE id = 1')
|
160 |
+
conn.commit()
|
161 |
+
conn.close()
|
162 |
+
return redirect(url_for('index'))
|
163 |
+
|
164 |
+
if __name__ == '__main__':
|
165 |
+
app.run(debug=True)
|
min ibank/pycash.db
ADDED
Binary file (16.4 kB). View file
|
|
min ibank/requirements.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Flask==2.0.3
|
2 |
+
Jinja2==3.0.3
|
3 |
+
itsdangerous==2.0.1
|
4 |
+
Werkzeug==2.0.3
|
5 |
+
reportlab==3.6.12
|
6 |
+
gunicorn==20.1.0
|
min ibank/static/requirements.txt
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Flask==2.0.3
|
2 |
+
Jinja2==3.0.3
|
3 |
+
itsdangerous==2.0.1
|
4 |
+
Werkzeug==2.0.3
|
5 |
+
reportlab==3.6.12
|
min ibank/static/styles.css
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
body {
|
2 |
+
font-family: Arial, sans-serif;
|
3 |
+
background-color: #f4f4f4;
|
4 |
+
text-align: center;
|
5 |
+
padding: 50px;
|
6 |
+
}
|
7 |
+
|
8 |
+
h1 {
|
9 |
+
color: #333;
|
10 |
+
}
|
11 |
+
|
12 |
+
.menu a {
|
13 |
+
display: inline-block;
|
14 |
+
margin: 10px;
|
15 |
+
padding: 10px 20px;
|
16 |
+
background-color: #333;
|
17 |
+
color: #fff;
|
18 |
+
text-decoration: none;
|
19 |
+
}
|
20 |
+
|
21 |
+
form {
|
22 |
+
display: inline-block;
|
23 |
+
text-align: left;
|
24 |
+
}
|
25 |
+
|
26 |
+
label, input {
|
27 |
+
display: block;
|
28 |
+
margin: 10px 0;
|
29 |
+
}
|
30 |
+
|
31 |
+
input[type="submit"] {
|
32 |
+
background-color: #333;
|
33 |
+
color: #fff;
|
34 |
+
border: none;
|
35 |
+
padding: 10px 20px;
|
36 |
+
}
|
37 |
+
body {
|
38 |
+
font-family: Arial, sans-serif;
|
39 |
+
background-color: #f4f4f4;
|
40 |
+
text-align: center;
|
41 |
+
padding: 50px;
|
42 |
+
}
|
43 |
+
|
44 |
+
h1 {
|
45 |
+
color: #333;
|
46 |
+
}
|
47 |
+
|
48 |
+
.menu a, .button {
|
49 |
+
display: inline-block;
|
50 |
+
margin: 10px;
|
51 |
+
padding: 10px 20px;
|
52 |
+
background-color: #333;
|
53 |
+
color: #fff;
|
54 |
+
text-decoration: none;
|
55 |
+
border-radius: 5px;
|
56 |
+
}
|
57 |
+
|
58 |
+
table {
|
59 |
+
margin: 20px auto;
|
60 |
+
border-collapse: collapse;
|
61 |
+
width: 80%;
|
62 |
+
}
|
63 |
+
|
64 |
+
th, td {
|
65 |
+
padding: 10px;
|
66 |
+
border: 1px solid #ddd;
|
67 |
+
text-align: left;
|
68 |
+
}
|
69 |
+
|
70 |
+
th {
|
71 |
+
background-color: #333;
|
72 |
+
color: white;
|
73 |
+
}
|
74 |
+
|
75 |
+
a.button {
|
76 |
+
margin-top: 20px;
|
77 |
+
}
|
78 |
+
body {
|
79 |
+
font-family: Arial, sans-serif;
|
80 |
+
background-color: #f4f4f4;
|
81 |
+
text-align: center;
|
82 |
+
padding: 50px;
|
83 |
+
}
|
84 |
+
|
85 |
+
h1 {
|
86 |
+
color: #333;
|
87 |
+
}
|
88 |
+
|
89 |
+
.menu a, .button, form button {
|
90 |
+
display: inline-block;
|
91 |
+
margin: 10px;
|
92 |
+
padding: 10px 20px;
|
93 |
+
background-color: #333;
|
94 |
+
color: #fff;
|
95 |
+
text-decoration: none;
|
96 |
+
border-radius: 5px;
|
97 |
+
border: none;
|
98 |
+
cursor: pointer;
|
99 |
+
}
|
100 |
+
|
101 |
+
table {
|
102 |
+
margin: 20px auto;
|
103 |
+
border-collapse: collapse;
|
104 |
+
width: 80%;
|
105 |
+
}
|
106 |
+
|
107 |
+
th, td {
|
108 |
+
padding: 10px;
|
109 |
+
border: 1px solid #ddd;
|
110 |
+
text-align: left;
|
111 |
+
}
|
112 |
+
|
113 |
+
th {
|
114 |
+
background-color: #333;
|
115 |
+
color: white;
|
116 |
+
}
|
117 |
+
|
118 |
+
a.button {
|
119 |
+
margin-top: 20px;
|
120 |
+
}
|
min ibank/templates/add_deposit.html
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<title>Add Deposit</title>
|
6 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
7 |
+
</head>
|
8 |
+
<body>
|
9 |
+
<h1>Add Deposit</h1>
|
10 |
+
<form method="POST">
|
11 |
+
<label for="dollars">Amount:</label>
|
12 |
+
<input type="text" name="dollars" required>
|
13 |
+
|
14 |
+
<label for="memo">From:</label>
|
15 |
+
<input type="text" name="memo">
|
16 |
+
|
17 |
+
|
18 |
+
|
19 |
+
<input type="submit" value="Submit">
|
20 |
+
</form>
|
21 |
+
<a href="/">Back to Home</a>
|
22 |
+
</body>
|
23 |
+
</html>
|
min ibank/templates/add_payment.html
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<title>Add Payment</title>
|
6 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
7 |
+
</head>
|
8 |
+
<body>
|
9 |
+
<h1>Add Payment</h1>
|
10 |
+
<form action="{{ url_for('add_payment') }}" method="post">
|
11 |
+
<label for="dollars">Amount (₹):</label>
|
12 |
+
<input type="number" step="0.01" name="dollars" required>
|
13 |
+
<br>
|
14 |
+
<label for="paymentTo">Paid to</label>
|
15 |
+
<input type="text" name="paymentTo" required>
|
16 |
+
<br>
|
17 |
+
<button type="submit">Submit Payment</button>
|
18 |
+
</form>
|
19 |
+
{% with messages = get_flashed_messages() %}
|
20 |
+
{% if messages %}
|
21 |
+
<ul>
|
22 |
+
{% for message in messages %}
|
23 |
+
<li>{{ message }}</li>
|
24 |
+
{% endfor %}
|
25 |
+
</ul>
|
26 |
+
{% endif %}
|
27 |
+
{% endwith %}
|
28 |
+
<a href="/">Back to Home</a>
|
29 |
+
</body>
|
30 |
+
</html>
|
min ibank/templates/index.html
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<title>PyCash</title>
|
6 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
7 |
+
</head>
|
8 |
+
<body>
|
9 |
+
<h1>Welcome to PyCash</h1>
|
10 |
+
<div class="menu">
|
11 |
+
<a href="{{ url_for('add_payment') }}" class="button">Make Payment</a>
|
12 |
+
<a href="{{ url_for('add_deposit') }}" class="button">Add Deposit</a>
|
13 |
+
<a href="{{ url_for('view_finances') }}" class="button">Show Transactions</a>
|
14 |
+
<form action="{{ url_for('clear_transactions') }}" method="post" style="display: inline;">
|
15 |
+
<button type="submit" class="button">Clear Transactions</button>
|
16 |
+
</form>
|
17 |
+
</div>
|
18 |
+
</body>
|
19 |
+
</html>
|
min ibank/templates/requirements.txt
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Flask==2.0.3
|
2 |
+
Jinja2==3.0.3
|
3 |
+
itsdangerous==2.0.1
|
4 |
+
Werkzeug==2.0.3
|
5 |
+
reportlab==3.6.12
|
min ibank/templates/view_finances.html
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<title>View Finances</title>
|
6 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
7 |
+
</head>
|
8 |
+
<body>
|
9 |
+
<h1>View Finances</h1>
|
10 |
+
<table>
|
11 |
+
<tr>
|
12 |
+
<th>Type</th>
|
13 |
+
<th>Amount</th>
|
14 |
+
<th>Date</th>
|
15 |
+
<th>From</th>
|
16 |
+
</tr>
|
17 |
+
{% for transaction in transactions %}
|
18 |
+
<tr>
|
19 |
+
<td>{{ transaction[1] }}</td>
|
20 |
+
<td>₹{{ '%.2f' % transaction[2] }}</td>
|
21 |
+
<td>{{ transaction[4] }}</td>
|
22 |
+
<td>{{ transaction[5] }}</td>
|
23 |
+
</tr>
|
24 |
+
{% endfor %}
|
25 |
+
</table>
|
26 |
+
<h2>Current Balance: ₹{{ '%.2f' % balance }}</h2>
|
27 |
+
<a href="/">Back to Home</a>
|
28 |
+
<br><br>
|
29 |
+
<a href="/generate_pdf" class="button">Download PDF Statement</a>
|
30 |
+
</body>
|
31 |
+
</html>
|
pycash.db
ADDED
Binary file (16.4 kB). View file
|
|
requirements.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Flask==2.0.3
|
2 |
+
Jinja2==3.0.3
|
3 |
+
itsdangerous==2.0.1
|
4 |
+
Werkzeug==2.0.3
|
5 |
+
reportlab==3.6.12
|
6 |
+
gunicorn==20.1.0
|
static/requirements.txt
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Flask==2.0.3
|
2 |
+
Jinja2==3.0.3
|
3 |
+
itsdangerous==2.0.1
|
4 |
+
Werkzeug==2.0.3
|
5 |
+
reportlab==3.6.12
|
static/styles.css
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
body {
|
2 |
+
font-family: Arial, sans-serif;
|
3 |
+
background-color: #f4f4f4;
|
4 |
+
text-align: center;
|
5 |
+
padding: 50px;
|
6 |
+
}
|
7 |
+
|
8 |
+
h1 {
|
9 |
+
color: #333;
|
10 |
+
}
|
11 |
+
|
12 |
+
.menu a {
|
13 |
+
display: inline-block;
|
14 |
+
margin: 10px;
|
15 |
+
padding: 10px 20px;
|
16 |
+
background-color: #333;
|
17 |
+
color: #fff;
|
18 |
+
text-decoration: none;
|
19 |
+
}
|
20 |
+
|
21 |
+
form {
|
22 |
+
display: inline-block;
|
23 |
+
text-align: left;
|
24 |
+
}
|
25 |
+
|
26 |
+
label, input {
|
27 |
+
display: block;
|
28 |
+
margin: 10px 0;
|
29 |
+
}
|
30 |
+
|
31 |
+
input[type="submit"] {
|
32 |
+
background-color: #333;
|
33 |
+
color: #fff;
|
34 |
+
border: none;
|
35 |
+
padding: 10px 20px;
|
36 |
+
}
|
37 |
+
body {
|
38 |
+
font-family: Arial, sans-serif;
|
39 |
+
background-color: #f4f4f4;
|
40 |
+
text-align: center;
|
41 |
+
padding: 50px;
|
42 |
+
}
|
43 |
+
|
44 |
+
h1 {
|
45 |
+
color: #333;
|
46 |
+
}
|
47 |
+
|
48 |
+
.menu a, .button {
|
49 |
+
display: inline-block;
|
50 |
+
margin: 10px;
|
51 |
+
padding: 10px 20px;
|
52 |
+
background-color: #333;
|
53 |
+
color: #fff;
|
54 |
+
text-decoration: none;
|
55 |
+
border-radius: 5px;
|
56 |
+
}
|
57 |
+
|
58 |
+
table {
|
59 |
+
margin: 20px auto;
|
60 |
+
border-collapse: collapse;
|
61 |
+
width: 80%;
|
62 |
+
}
|
63 |
+
|
64 |
+
th, td {
|
65 |
+
padding: 10px;
|
66 |
+
border: 1px solid #ddd;
|
67 |
+
text-align: left;
|
68 |
+
}
|
69 |
+
|
70 |
+
th {
|
71 |
+
background-color: #333;
|
72 |
+
color: white;
|
73 |
+
}
|
74 |
+
|
75 |
+
a.button {
|
76 |
+
margin-top: 20px;
|
77 |
+
}
|
78 |
+
body {
|
79 |
+
font-family: Arial, sans-serif;
|
80 |
+
background-color: #f4f4f4;
|
81 |
+
text-align: center;
|
82 |
+
padding: 50px;
|
83 |
+
}
|
84 |
+
|
85 |
+
h1 {
|
86 |
+
color: #333;
|
87 |
+
}
|
88 |
+
|
89 |
+
.menu a, .button, form button {
|
90 |
+
display: inline-block;
|
91 |
+
margin: 10px;
|
92 |
+
padding: 10px 20px;
|
93 |
+
background-color: #333;
|
94 |
+
color: #fff;
|
95 |
+
text-decoration: none;
|
96 |
+
border-radius: 5px;
|
97 |
+
border: none;
|
98 |
+
cursor: pointer;
|
99 |
+
}
|
100 |
+
|
101 |
+
table {
|
102 |
+
margin: 20px auto;
|
103 |
+
border-collapse: collapse;
|
104 |
+
width: 80%;
|
105 |
+
}
|
106 |
+
|
107 |
+
th, td {
|
108 |
+
padding: 10px;
|
109 |
+
border: 1px solid #ddd;
|
110 |
+
text-align: left;
|
111 |
+
}
|
112 |
+
|
113 |
+
th {
|
114 |
+
background-color: #333;
|
115 |
+
color: white;
|
116 |
+
}
|
117 |
+
|
118 |
+
a.button {
|
119 |
+
margin-top: 20px;
|
120 |
+
}
|
templates/add_deposit.html
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<title>Add Deposit</title>
|
6 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
7 |
+
</head>
|
8 |
+
<body>
|
9 |
+
<h1>Add Deposit To Your Bank Ac:</h1>
|
10 |
+
<form method="POST">
|
11 |
+
<label for="dollars">Amount:</label>
|
12 |
+
<input type="text" name="dollars" required>
|
13 |
+
|
14 |
+
<label for="memo">From:</label>
|
15 |
+
<input type="text" name="memo">
|
16 |
+
|
17 |
+
|
18 |
+
|
19 |
+
<input type="submit" value="Submit">
|
20 |
+
</form>
|
21 |
+
<a href="/">Back to Home</a>
|
22 |
+
</body>
|
23 |
+
</html>
|
templates/add_payment.html
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<title>Add Payment</title>
|
6 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
7 |
+
</head>
|
8 |
+
<body>
|
9 |
+
<h1>Add Payment</h1>
|
10 |
+
<form action="{{ url_for('add_payment') }}" method="post">
|
11 |
+
<label for="dollars">Amount (₹):</label>
|
12 |
+
<input type="number" step="0.01" name="dollars" required>
|
13 |
+
<br>
|
14 |
+
<label for="paymentTo">Paid to</label>
|
15 |
+
<input type="text" name="paymentTo" required>
|
16 |
+
<br>
|
17 |
+
<button type="submit">Submit Payment</button>
|
18 |
+
</form>
|
19 |
+
{% with messages = get_flashed_messages() %}
|
20 |
+
{% if messages %}
|
21 |
+
<ul>
|
22 |
+
{% for message in messages %}
|
23 |
+
<li>{{ message }}</li>
|
24 |
+
{% endfor %}
|
25 |
+
</ul>
|
26 |
+
{% endif %}
|
27 |
+
{% endwith %}
|
28 |
+
<a href="/">Back to Home</a>
|
29 |
+
</body>
|
30 |
+
</html>
|
templates/index.html
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<title>PyCash</title>
|
6 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
7 |
+
</head>
|
8 |
+
<body>
|
9 |
+
<h1>Welcome to PyCash</h1>
|
10 |
+
<div class="menu">
|
11 |
+
<a href="{{ url_for('add_payment') }}" class="button">Make Payment</a>
|
12 |
+
<a href="{{ url_for('add_deposit') }}" class="button">Add Deposit</a>
|
13 |
+
<a href="{{ url_for('view_finances') }}" class="button">Show Transactions</a>
|
14 |
+
<form action="{{ url_for('clear_transactions') }}" method="post" style="display: inline;">
|
15 |
+
<button type="submit" class="button">Clear Transactions</button>
|
16 |
+
</form>
|
17 |
+
</div>
|
18 |
+
</body>
|
19 |
+
</html>
|
templates/requirements.txt
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Flask==2.0.3
|
2 |
+
Jinja2==3.0.3
|
3 |
+
itsdangerous==2.0.1
|
4 |
+
Werkzeug==2.0.3
|
5 |
+
reportlab==3.6.12
|
templates/view_finances.html
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<title>View Finances</title>
|
6 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
|
7 |
+
</head>
|
8 |
+
<body>
|
9 |
+
<h1>View Finances</h1>
|
10 |
+
<table>
|
11 |
+
<tr>
|
12 |
+
<th>Type</th>
|
13 |
+
<th>Amount</th>
|
14 |
+
<th>Date</th>
|
15 |
+
<th>From</th>
|
16 |
+
</tr>
|
17 |
+
{% for transaction in transactions %}
|
18 |
+
<tr>
|
19 |
+
<td>{{ transaction[1] }}</td>
|
20 |
+
<td>₹{{ '%.2f' % transaction[2] }}</td>
|
21 |
+
<td>{{ transaction[4] }}</td>
|
22 |
+
<td>{{ transaction[5] }}</td>
|
23 |
+
</tr>
|
24 |
+
{% endfor %}
|
25 |
+
</table>
|
26 |
+
<h2>Current Balance: ₹{{ '%.2f' % balance }}</h2>
|
27 |
+
<a href="/">Back to Home</a>
|
28 |
+
<br><br>
|
29 |
+
<a href="/generate_pdf" class="button">Download PDF Statement</a>
|
30 |
+
</body>
|
31 |
+
</html>
|