Skip to content

Commit 4861497

Browse files
committed
Update to version 3.2.1: Adding default currencies UI”
1 parent 41657b0 commit 4861497

File tree

7 files changed

+94
-57
lines changed

7 files changed

+94
-57
lines changed

app.py

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,28 @@ def calculate_balances(user_id):
808808

809809
# Return only non-zero balances
810810
return [balance for balance in balances.values() if abs(balance['amount']) > 0.01]
811+
812+
def get_base_currency():
813+
"""Get the current user's default currency or fall back to base currency if not set"""
814+
if current_user.is_authenticated and current_user.default_currency_code and current_user.default_currency:
815+
# User has set a default currency, use that
816+
return {
817+
'code': current_user.default_currency.code,
818+
'symbol': current_user.default_currency.symbol,
819+
'name': current_user.default_currency.name
820+
}
821+
else:
822+
# Fall back to system base currency if user has no preference
823+
base_currency = Currency.query.filter_by(is_base=True).first()
824+
if not base_currency:
825+
# Default to USD if no base currency is set
826+
return {'code': 'USD', 'symbol': '$', 'name': 'US Dollar'}
827+
return {
828+
'code': base_currency.code,
829+
'symbol': base_currency.symbol,
830+
'name': base_currency.name
831+
}
832+
811833
def send_welcome_email(user):
812834
"""
813835
Send a welcome email to a newly registered user
@@ -1237,7 +1259,7 @@ def logout():
12371259
@login_required_dev
12381260
def dashboard():
12391261
now = datetime.now()
1240-
1262+
base_currency = get_base_currency()
12411263
# Fetch all expenses where the user is either the creator or a split participant
12421264
expenses = Expense.query.filter(
12431265
or_(
@@ -1391,6 +1413,7 @@ def dashboard():
13911413
users=users,
13921414
groups=groups,
13931415
iou_data=iou_data,
1416+
base_currency=base_currency,
13941417
currencies=currencies,
13951418
now=now)
13961419

@@ -1533,6 +1556,7 @@ def delete_tag(tag_id):
15331556
@app.route('/recurring')
15341557
@login_required_dev
15351558
def recurring():
1559+
base_currency = get_base_currency()
15361560
recurring_expenses = RecurringExpense.query.filter(
15371561
or_(
15381562
RecurringExpense.user_id == current_user.id,
@@ -1546,6 +1570,7 @@ def recurring():
15461570
recurring_expenses=recurring_expenses,
15471571
users=users,
15481572
currencies=currencies,
1573+
base_currency=base_currency,
15491574
groups=groups)
15501575

15511576
@app.route('/add_recurring', methods=['POST'])
@@ -1711,7 +1736,9 @@ def create_group():
17111736
@app.route('/groups/<int:group_id>')
17121737
@login_required_dev
17131738
def group_details(group_id):
1739+
base_currency = get_base_currency()
17141740
group = Group.query.get_or_404(group_id)
1741+
17151742
# Check if user is member of group
17161743
if current_user not in group.members:
17171744
flash('Access denied. You are not a member of this group.')
@@ -1720,7 +1747,7 @@ def group_details(group_id):
17201747
expenses = Expense.query.filter_by(group_id=group_id).order_by(Expense.date.desc()).all()
17211748
all_users = User.query.all()
17221749
currencies = Currency.query.all()
1723-
return render_template('group_details.html', group=group, expenses=expenses,currencies=currencies, users=all_users)
1750+
return render_template('group_details.html', group=group, expenses=expenses,currencies=currencies, base_currency=base_currency,users=all_users)
17241751

17251752
@app.route('/groups/<int:group_id>/add_member', methods=['POST'])
17261753
@login_required_dev
@@ -1859,6 +1886,7 @@ def admin_reset_password():
18591886
@login_required_dev
18601887
def settlements():
18611888
# Get all settlements involving the current user
1889+
base_currency = get_base_currency()
18621890
settlements = Settlement.query.filter(
18631891
or_(
18641892
Settlement.payer_id == current_user.id,
@@ -1899,6 +1927,7 @@ def settlements():
18991927
users=users,
19001928
you_owe=you_owe,
19011929
you_are_owed=you_are_owed,
1930+
base_currency=base_currency,
19021931
current_user_id=current_user.id)
19031932

19041933
@app.route('/add_settlement', methods=['POST'])
@@ -2079,15 +2108,15 @@ def set_base_currency(code):
20792108
# Ensure user is an admin
20802109
if not current_user.is_admin:
20812110
flash('Unauthorized. Admin access required.', 'error')
2082-
return redirect(url_for('currencies'))
2111+
return redirect(url_for('manage_currencies')) # Changed 'currencies' to 'manage_currencies'
20832112

20842113
try:
20852114
# Find the currency to be set as base
20862115
new_base_currency = Currency.query.filter_by(code=code).first()
20872116

20882117
if not new_base_currency:
20892118
flash(f'Currency {code} not found.', 'error')
2090-
return redirect(url_for('currencies'))
2119+
return redirect(url_for('manage_currencies')) # Changed 'currencies' to 'manage_currencies'
20912120

20922121
# Find and unset the current base currency
20932122
current_base_currency = Currency.query.filter_by(is_base=True).first()
@@ -2122,7 +2151,7 @@ def set_base_currency(code):
21222151

21232152
flash('An error occurred while changing the base currency.', 'error')
21242153

2125-
return redirect(url_for('currencies'))
2154+
return redirect(url_for('manage_currencies')) # Changed 'currencies' to 'manage_currencies'
21262155
@app.route('/update_currency_rates', methods=['POST'])
21272156
@login_required_dev
21282157
def update_rates_route():
@@ -2162,6 +2191,7 @@ def set_default_currency():
21622191
def transactions():
21632192
"""Display all transactions with filtering capabilities"""
21642193
# Fetch all expenses where the user is either the creator or a split participant
2194+
base_currency = get_base_currency()
21652195
expenses = Expense.query.filter(
21662196
or_(
21672197
Expense.user_id == current_user.id,
@@ -2278,6 +2308,7 @@ def transactions():
22782308
current_month_total=current_month_total,
22792309
unique_cards=unique_cards,
22802310
users=users,
2311+
base_currency=base_currency,
22812312
currencies=currencies)
22822313

22832314
#--------------------
@@ -2488,6 +2519,7 @@ def update_color():
24882519
def stats():
24892520
"""Display financial statistics and visualizations that are user-centric"""
24902521
# Get filter parameters from request
2522+
base_currency = get_base_currency()
24912523
start_date_str = request.args.get('startDate', None)
24922524
end_date_str = request.args.get('endDate', None)
24932525
group_id = request.args.get('groupId', 'all')
@@ -2803,6 +2835,7 @@ def stats():
28032835
balance_amounts=balance_amounts,
28042836
group_names=group_names,
28052837
group_totals=group_totals,
2838+
base_currency=base_currency,
28062839
top_expenses=top_expenses)
28072840

28082841

templates/dashboard.html

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ <h4 class="mb-3">Add New Expense</h4>
1919
<input type="text" class="form-control bg-dark text-light" id="description" name="description" required>
2020
</div>
2121
<div class="col-md-6 mb-3">
22-
<label for="amount" class="form-label">Amount ($)</label>
22+
<label for="amount" class="form-label">Amount ({{ base_currency.symbol }})</label>
2323
<input type="number" step="0.01" class="form-control bg-dark text-light" id="amount" name="amount" required>
2424
</div>
2525
<div class="col-md-6 mb-3">
@@ -105,8 +105,8 @@ <h5 class="mb-0">Customize Split Values</h5>
105105
</div>
106106
<div class="d-flex justify-content-between align-items-center mt-3">
107107
<div>
108-
<span class="text-muted">Total: $<span id="split_total">0.00</span></span>
109-
<span class="ms-2 text-muted">Expense: $<span id="expense_amount">0.00</span></span>
108+
<span class="text-muted">Total: {{ base_currency.symbol }}<span id="split_total">0.00</span></span>
109+
<span class="ms-2 text-muted">Expense: {{ base_currency.symbol }}<span id="expense_amount">0.00</span></span>
110110
</div>
111111
<div>
112112
<span class="badge bg-success" id="split_status">Balanced</span>
@@ -160,15 +160,15 @@ <h5 class="mb-0">Customize Split Values</h5>
160160
<div class="card">
161161
<div class="card-body">
162162
<h5 class="card-title text-muted mb-3">Yearly Total</h5>
163-
<h2 class="mb-0">${{ "%.2f"|format(total_expenses) }}</h2>
163+
<h2 class="mb-0">{{ base_currency.symbol }}{{ "%.2f"|format(total_expenses) }}</h2>
164164
</div>
165165
</div>
166166
</div>
167167
<div class="col-md-4">
168168
<div class="card">
169169
<div class="card-body">
170170
<h5 class="card-title text-muted mb-3">This Month</h5>
171-
<h2 class="mb-0">${{ "%.2f"|format(current_month_total) }}</h2>
171+
<h2 class="mb-0">{{ base_currency.symbol }}{{ "%.2f"|format(current_month_total) }}</h2>
172172
</div>
173173
</div>
174174
</div>
@@ -208,7 +208,7 @@ <h6 class="text-success mb-3">
208208
<span class="badge me-2" style="background-color: {{ get_user_color(user_id) }};">{{ data.name }}</span>
209209
</div>
210210
<div class="d-flex align-items-center">
211-
<span class="badge bg-success me-2">${{ "%.2f"|format(data.amount) }}</span>
211+
<span class="badge bg-success me-2">{{ base_currency.symbol }}{{ "%.2f"|format(data.amount) }}</span>
212212
<button class="btn btn-secondary btn-sm"
213213
onclick="prepareSettlement('{{ user_id }}', '{{ data.name }}', {{ data.amount }}, false)">
214214
<i class="fas fa-check me-1"></i>Record
@@ -236,7 +236,7 @@ <h6 class="text-danger mb-3">
236236
<span class="badge me-2" style="background-color: {{ get_user_color(user_id) }};">{{ data.name }}</span>
237237
</div>
238238
<div class="d-flex align-items-center">
239-
<span class="badge bg-danger me-2">${{ "%.2f"|format(data.amount) }}</span>
239+
<span class="badge bg-danger me-2">{{ base_currency.symbol }}{{ "%.2f"|format(data.amount) }}</span>
240240
<button class="btn btn-success btn-sm"
241241
onclick="prepareSettlement('{{ user_id }}', '{{ data.name }}', {{ data.amount }}, true)">
242242
<i class="fas fa-money-bill-wave me-1"></i>Pay
@@ -260,7 +260,7 @@ <h6>Your Net Balance</h6>
260260
{% else %}
261261
<i class="fas fa-minus-circle me-1"></i>
262262
{% endif %}
263-
${{ "%.2f"|format(iou_data.net_balance|abs) }}
263+
{{ base_currency.symbol }}{{ "%.2f"|format(iou_data.net_balance|abs) }}
264264
</span>
265265
<p class="small text-muted mt-2">
266266
{% if iou_data.net_balance > 0 %}
@@ -303,7 +303,7 @@ <h4 class="mb-3">Record a Settlement</h4>
303303
</div>
304304
<div class="row">
305305
<div class="col-md-4 mb-3">
306-
<label for="amount" class="form-label">Amount ($)</label>
306+
<label for="amount" class="form-label">Amount ({{ base_currency.symbol }})</label>
307307
<input type="number" step="0.01" class="form-control bg-dark text-light" id="settlement_amount" name="amount" required>
308308
</div>
309309
<div class="col-md-4 mb-3">
@@ -344,7 +344,7 @@ <h5 class="mb-0">Monthly Spending Breakdown</h5>
344344
{% for month, data in monthly_totals.items()|sort(reverse=true) %}
345345
<tr>
346346
<td>{{ month }}</td>
347-
<td>${{ "%.2f"|format(data.total) }}</td>
347+
<td>{{ base_currency.symbol }}{{ "%.2f"|format(data.total) }}</td>
348348
<td>
349349
<!-- Contributors with amounts -->
350350
{% for user_id, amount in data.contributors.items() %}
@@ -356,15 +356,15 @@ <h5 class="mb-0">Monthly Spending Breakdown</h5>
356356
</span>
357357
{% endif %}
358358
{% endfor %}
359-
<span class="badge bg-success">${{ "%.2f"|format(amount) }}</span>
359+
<span class="badge bg-success">{{ base_currency.symbol }}{{ "%.2f"|format(amount) }}</span>
360360
</div>
361361
{% endfor %}
362362
</td>
363363
<!-- Cards used this month -->
364364
{% for card, amount in data.by_card.items() %}
365365
<div class="mb-1">
366366
<span class="badge bg-secondary">{{ card }}</span>
367-
<span class="badge bg-info">${{ "%.2f"|format(amount) }}</span>
367+
<span class="badge bg-info">{{ base_currency.symbol }}{{ "%.2f"|format(amount) }}</span>
368368
</div>
369369
{% endfor %}
370370
</td>
@@ -401,7 +401,7 @@ <h6 class="mb-3">Expense Details for {{ month }}</h6>
401401
<tr>
402402
<td>{{ expense.date.strftime('%d') }}</td>
403403
<td>{{ expense.description }}</td>
404-
<td>${{ "%.2f"|format(expense.amount) }}</td>
404+
<td>{{ base_currency.symbol }}{{ "%.2f"|format(expense.amount) }}</td>
405405
<td>{{ splits.payer.name }}</td>
406406
<td>{{ expense.card_used }}</td>
407407
<td>
@@ -412,7 +412,7 @@ <h6 class="mb-3">Expense Details for {{ month }}</h6>
412412
<span class="badge" style="background-color: {{ payer_user.user_color if payer_user and payer_user.user_color else '#15803d' }};">
413413
{{ splits.payer.name }}
414414
</span>:
415-
${{ "%.2f"|format(splits.payer.amount) }}
415+
{{ base_currency.symbol }}{{ "%.2f"|format(splits.payer.amount) }}
416416
</small>
417417
{% endif %}
418418

@@ -423,7 +423,7 @@ <h6 class="mb-3">Expense Details for {{ month }}</h6>
423423
<span class="badge" style="background-color: {{ split_user.user_color if split_user and split_user.user_color else '#15803d' }};">
424424
{{ split.name }}
425425
</span>:
426-
${{ "%.2f"|format(split.amount) }}
426+
{{ base_currency.symbol }}{{ "%.2f"|format(split.amount) }}
427427
</small>
428428
{% endfor %}
429429
</td>
@@ -451,7 +451,7 @@ <h6 class="mb-3">Expense Details for {{ month }}</h6>
451451
{% block scripts %}
452452

453453
<script>
454-
454+
const baseCurrencySymbol = "{{ base_currency.symbol }}";
455455

456456
function initializeTagCheckboxes() {
457457
const tagCheckboxes = document.querySelectorAll('.tag-checkbox');

0 commit comments

Comments
 (0)