Skip to content

Commit b119ede

Browse files
chore: 🔨 lvl2 refactor
1 parent 731e66d commit b119ede

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+568
-483
lines changed

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ cover/
5757

5858
# Django stuff:
5959
*.log
60-
local_settings.py
60+
local_.py
6161
db.sqlite3
6262
db.sqlite3-journal
6363

@@ -130,7 +130,7 @@ ENV/
130130
env.bak/
131131
venv.bak/
132132

133-
# Spyder project settings
133+
# Spyder project
134134
.spyderproject
135135
.spyproject
136136

app.py

+22-455
Large diffs are not rendered by default.
File renamed without changes.

src/blueprints/__init__.py

Whitespace-only changes.

src/blueprints/additional.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from flask import render_template, Blueprint
2+
3+
4+
additional_bp = Blueprint('additional', __name__)
5+
6+
@additional_bp.route('/pricing')
7+
def pricing() -> str:
8+
return render_template('pricing.html')
9+
10+
@additional_bp.route('/features')
11+
def features() -> str:
12+
return render_template('features.html')
13+
14+
@additional_bp.route('/about')
15+
def about() -> str:
16+
return render_template('about.html')
17+
18+
19+
@additional_bp.route('/permission-denied')
20+
def permission_denied():
21+
return render_template('permission_denied.html')
22+
23+
@additional_bp.errorhandler(404)
24+
def page_not_found(e):
25+
return render_template('404.html'), 404
26+
27+
28+

src/blueprints/admin.py

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import psutil
2+
3+
from flask import render_template, request, session, redirect, url_for, flash, Blueprint
4+
5+
from flask_login import current_user, login_required
6+
from flask_login import current_user, login_required
7+
8+
from src.config import db
9+
from src.models import User, AuditLog, Settings, log_action
10+
11+
admin_bp = Blueprint('admin', __name__)
12+
13+
@admin_bp.route('/admin/manage_users', methods=['GET', 'POST'])
14+
@login_required
15+
def manage_users():
16+
if current_user.user_level != 'admin':
17+
return redirect(url_for('permission_denied'))
18+
19+
users = User.query.all()
20+
21+
if request.method == 'POST':
22+
user_id = request.form.get('user_id')
23+
new_level = request.form.get('user_level')
24+
25+
user = User.query.get(user_id)
26+
if user:
27+
user.user_level = new_level
28+
db.session.commit()
29+
flash(f"User {user.username}'s level updated to {new_level}.", 'success')
30+
else:
31+
flash("User not found.", 'error')
32+
33+
return render_template('manage_users.html', users=users)
34+
35+
@admin_bp.route('/settings', methods=['GET', 'POST'])
36+
@login_required
37+
def settings():
38+
if current_user.user_level != 'admin':
39+
return redirect(url_for('home'))
40+
41+
if request.method == 'POST':
42+
currency = request.form.get('currency')
43+
theme = request.form.get('theme')
44+
language = request.form.get('language')
45+
is_gold_jewellers_sidebar = int(request.form.get('is_gold_jewellers_sidebar'))
46+
is_gold_calculator_enabled = int(request.form.get('is_gold_calculator_enabled'))
47+
is_silver_calculator_enabled = int(request.form.get('is_silver_calculator_enabled'))
48+
49+
# Save the settings (you might save them to a database or a config file)
50+
# Assuming you have a Settings model or similar logic to save settings
51+
settings = Settings.query.first()
52+
if not settings:
53+
settings = Settings(currency=currency, theme=theme, language=language,
54+
is_gold_jewellers_sidebar=is_gold_jewellers_sidebar,
55+
is_gold_calculator_enabled=is_gold_calculator_enabled,
56+
is_silver_calculator_enabled=is_silver_calculator_enabled)
57+
else:
58+
settings.currency = currency
59+
settings.theme = theme
60+
settings.language = language
61+
settings.is_gold_jewellers_sidebar = is_gold_jewellers_sidebar
62+
settings.is_gold_calculator_enabled = is_gold_calculator_enabled
63+
settings.is_silver_calculator_enabled = is_silver_calculator_enabled
64+
65+
db.session.add(settings)
66+
db.session.commit()
67+
68+
log_action(current_user.id, current_user.username, 'System Settings Change', details=f"Currency set to {currency}, Theme set to {theme}")
69+
return redirect(url_for('settings'))
70+
71+
settings = Settings.query.first()
72+
return render_template('settings.html', settings=settings)
73+
74+
75+
@admin_bp.route('/admin/audit_log')
76+
@login_required
77+
def audit_log():
78+
if current_user.user_level != 'admin':
79+
return redirect(url_for('home'))
80+
81+
logs = AuditLog.query.order_by(AuditLog.timestamp.desc()).all()
82+
return render_template('audit_log.html', logs=logs)
83+
84+
85+
@admin_bp.route("/dashboard")
86+
@login_required
87+
def dashboard():
88+
if current_user.user_level == 'admin':
89+
total_users = User.query.count() # Count total users
90+
active_sessions = len(session) # This is a basic approach. You may want to track sessions differently.
91+
92+
# Example: If you store active users in the session, you might track like this:
93+
active_sessions = session.get('active_users', 0)
94+
95+
system_health = "Good" # This can be determined by your own logic
96+
cpu_core = psutil.cpu_count()
97+
cpu_utilization = psutil.cpu_percent(interval=1)
98+
99+
if cpu_utilization > 80:
100+
system_health = "Warning"
101+
else:
102+
system_health = "Good"
103+
104+
audit_logs = AuditLog.query.filter_by(user_id=current_user.id).all()
105+
return render_template('admin_dashboard.html',
106+
total_users=total_users,
107+
active_sessions=active_sessions,
108+
system_health=system_health,
109+
cpu_core=cpu_core,
110+
cpu_util=cpu_utilization,
111+
audit_logs=audit_logs)
112+
elif current_user.user_level == 'customer':
113+
audit_logs = AuditLog.query.filter_by(user_id=current_user.id).all()
114+
return render_template('customer_dashboard.html', audit_logs=audit_logs)
115+
116+

src/blueprints/auth.py

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
2+
from flask import render_template, request, redirect, url_for, Blueprint
3+
4+
from flask_login import login_user, logout_user
5+
6+
from src.config import app, db, bcrypt, login_manager
7+
from src.models import User, log_action
8+
9+
auth_bp = Blueprint('auth', __name__)
10+
11+
@auth_bp.route("/register", methods=['GET', 'POST'])
12+
def register():
13+
if request.method == 'POST':
14+
fname = request.form.get('fname')
15+
lname = request.form.get('lname')
16+
username = request.form.get('username')
17+
email = request.form.get('email')
18+
password = bcrypt.generate_password_hash(request.form.get('password')).decode('utf-8')
19+
# Check if this is the first user
20+
if User.query.count() == 0:
21+
user_level = 'admin' # Make the first user an admin
22+
else:
23+
user_level = 'customer' # Default to 'customer' for all other users
24+
user = User(fname=fname, lname=lname, username=username, email=email, password=password, user_level=user_level)
25+
db.session.add(user)
26+
db.session.commit()
27+
return redirect(url_for('login'))
28+
return render_template('register.html')
29+
30+
@auth_bp.route("/login", methods=['GET', 'POST'])
31+
def login():
32+
if request.method == 'POST':
33+
email = request.form.get('email')
34+
password = request.form.get('password')
35+
user = User.query.filter_by(email=email).first()
36+
if user and bcrypt.check_password_hash(user.password, password):
37+
login_user(user)
38+
log_action(user.id, user.username, 'Login', f'User {user.username} logged in.')
39+
return redirect(url_for('admin.dashboard'))
40+
return render_template('login.html')
41+
42+
@auth_bp.route("/logout")
43+
def logout():
44+
logout_user()
45+
return redirect(url_for('auth.login'))
46+
47+
@login_manager.user_loader
48+
def load_user(user_id):
49+
return User.query.get(int(user_id))
50+
51+

src/blueprints/config.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
from flask import render_template, request, redirect, url_for, Blueprint
3+
4+
from src.config import db
5+
from src.models import JewellerDetails
6+
7+
config_bp = Blueprint('config', __name__)
8+
9+
@config_bp.route('/config', methods=['GET', 'POST'])
10+
def update_jeweller_details():
11+
if request.method == 'POST':
12+
jeweller = JewellerDetails.query.first()
13+
14+
jeweller.jeweller_name = request.form['jeweller_name']
15+
jeweller.jeweller_address = request.form['jeweller_address']
16+
jeweller.jeweller_contact = request.form['jeweller_contact']
17+
jeweller.jeweller_email = request.form['jeweller_email']
18+
jeweller.jeweller_website = request.form['jeweller_website']
19+
jeweller.jeweller_gstin = request.form['jeweller_gstin']
20+
jeweller.gold_price_per_gram = float(request.form['gold_price_per_gram'])
21+
22+
if 'jeweller_logo' in request.files:
23+
logo = request.files['jeweller_logo']
24+
logo.save(f'static/images/{logo.filename}')
25+
jeweller.jeweller_logo = f'images/{logo.filename}'
26+
27+
db.session.commit()
28+
return redirect(url_for('update_jeweller_details'))
29+
30+
jeweller = JewellerDetails.query.first()
31+
return render_template('config.html', jeweller=jeweller)
32+
33+

src/blueprints/gold_calculator.py

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
2+
import logging
3+
4+
from flask import render_template, request, session, redirect, url_for, flash, Blueprint
5+
from flask_login import current_user
6+
from calculators import GoldCalculator
7+
8+
from src.config import db
9+
from src.models import Settings, GoldTransaction, JewellerDetails, log_action
10+
from src.blueprints.helper import get_currency_symbol
11+
12+
gold_calculator_bp = Blueprint('gold_calculator', __name__)
13+
14+
# Gold calculator route
15+
@gold_calculator_bp.route('/gold-calculator', methods=['GET', 'POST'])
16+
def gold_calculator():
17+
system_settings = Settings.query.first()
18+
jeweller_details = JewellerDetails.query.first()
19+
if not system_settings.is_gold_calculator_enabled:
20+
return redirect(url_for('permission_denied'))
21+
if request.method == 'POST':
22+
try:
23+
weight = float(request.form['weight'])
24+
gold_price_per_gram = float(request.form['price_per_gram'])
25+
gold_service_charge = float(request.form['service_charge'])
26+
gold_tax = float(request.form['tax'])
27+
purity = request.form['purity']
28+
29+
# Save price per gram to session
30+
session['gold_price_per_gram'] = gold_price_per_gram
31+
session['gold_service_charge'] = gold_service_charge
32+
session['gold_tax'] = gold_tax
33+
34+
# Calculate gold price
35+
gold_item = GoldCalculator(weight, gold_price_per_gram, gold_service_charge, gold_tax)
36+
bill_details = gold_item.calculate_price()
37+
38+
# Save to database
39+
transaction = GoldTransaction(
40+
weight=weight,
41+
price_per_gram=gold_price_per_gram,
42+
purity=purity,
43+
service_charge=gold_service_charge,
44+
tax=gold_tax,
45+
total=bill_details['Final Price'],
46+
currency=system_settings.currency,
47+
)
48+
db.session.add(transaction)
49+
db.session.commit()
50+
51+
# if user is logged in, log the transaction
52+
if current_user.is_authenticated:
53+
log_action(user_id=current_user.id, username=current_user.username,
54+
action='Gold Calculator', details=f"Calculated gold price for weight {weight} grams")
55+
else:
56+
log_action(user_id="-1", username="Anonymous",
57+
action='Gold Calculator', details=f"Calculated gold price for weight {weight} grams")
58+
59+
return render_template('gold_bill.html',
60+
bill=bill_details,
61+
weight=weight,
62+
price_per_gram=gold_price_per_gram,
63+
purity=purity,
64+
settings=system_settings,
65+
jeweller_details=jeweller_details,
66+
currency_symbol=get_currency_symbol(system_settings.currency))
67+
68+
except ValueError as e:
69+
logging.error(f"ValueError in gold calculator: {str(e)}")
70+
flash(f"Input error: {str(e)}", 'error')
71+
return redirect(url_for('gold_calculator'))
72+
73+
# Use session-stored price per gram or a default value
74+
gold_price_per_gram = session.get('gold_price_per_gram', 0)
75+
gold_service_charge = session.get('gold_service_charge', 0)
76+
gold_tax = session.get('gold_tax', 0)
77+
78+
return render_template('gold_calculator.html',
79+
price_per_gram=gold_price_per_gram,
80+
service_charge=gold_service_charge,
81+
tax=gold_tax,
82+
settings=system_settings,
83+
jeweller_details=jeweller_details,
84+
currency_symbol=get_currency_symbol(system_settings.currency))
85+
86+

src/blueprints/health.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from datetime import datetime
2+
3+
from flask import render_template, Blueprint
4+
5+
health_bp = Blueprint('health', __name__)
6+
7+
@health_bp.route('/health')
8+
def health():
9+
health_info = {
10+
"status": "healthy",
11+
"message": "The server is up and running.",
12+
"version": "1.0.0",
13+
"timestamp": datetime.now().isoformat()
14+
}
15+
return render_template('health.html', **health_info)

src/blueprints/helper.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
def get_currency_symbol(currency):
2+
currency_to_symbol_dict = {
3+
"INR" : "₹",
4+
"USD" : "$ ",
5+
"EUR" : "€ ",
6+
"GBP" : "£ ",
7+
"JPY" : "¥ ",
8+
"AUD" : "A$ ",
9+
}
10+
return currency_to_symbol_dict.get(currency, currency)

0 commit comments

Comments
 (0)