Passed
Push — master ( 1613e1...bdc329 )
by William
01:30
created

app.main.main_page()   A

Complexity

Conditions 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nop 2
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
from flask import request, redirect, url_for, send_from_directory, flash, send_file
2
from flask_login import login_required, current_user
3
from flask import Blueprint, render_template
4
from .models import Schedule, Balance, Total, Running, User, Settings, Transactions, Email, Hold, Skip
5
from app import db
6
from datetime import datetime
7
import os
8
from sqlalchemy import desc, extract, asc
9
from werkzeug.security import generate_password_hash
10
from .cashflow import calc_schedule, calc_transactions, plot_cash
11
12
13
main = Blueprint('main', __name__)
14
15
16
@main.route('/', methods=('GET', 'POST'))
17
@login_required
18
def index():
19
    # get today's date
20
    todaydate = datetime.today().strftime('%A, %B %d, %Y')
21
22
    # query the latest balance information
23
    balance = Balance.query.order_by(desc(Balance.date), desc(Balance.id)).first()
24
25
    try:
26
        if balance.amount:
27
            db.session.query(Balance).delete()
28
            balance = Balance(amount=balance.amount, date=datetime.today())
29
            db.session.add(balance)
30
            db.session.commit()
31
    except:
32
        balance = Balance(amount='0',
33
                          date=datetime.today())
34
        db.session.add(balance)
35
        db.session.commit()
36
37
    main_page(todaydate, balance)
38
39
    # empty the tables to create fresh data from the schedule
40
    db.session.query(Total).delete()
41
    db.session.query(Running).delete()
42
    db.session.query(Transactions).delete()
43
    db.session.commit()
44
45
    # calculate total events for the year amount
46
    calc_schedule()
47
48
    # calculate sum of running transactions
49
    calc_transactions(balance)
50
51
    # plot cash flow results
52
    minbalance, graphJSON = plot_cash()
53
54
    if current_user.admin:
55
        return render_template('index.html', title='Index', todaydate=todaydate, balance=balance.amount,
56
                           minbalance=minbalance, graphJSON=graphJSON)
57
    else:
58
        return render_template('index_guest.html', title='Index', todaydate=todaydate, balance=balance.amount,
59
                           minbalance=minbalance, graphJSON=graphJSON)
60
61
62
def main_page(todaydate, balance):
63
    # plot cash flow results
64
    minbalance, graphJSON = plot_cash()
65
66
    if current_user.admin:
67
        return render_template('index.html', title='Index', todaydate=todaydate, balance=balance.amount,
68
                               minbalance=minbalance, graphJSON=graphJSON)
69
    else:
70
        return render_template('index_guest.html', title='Index', todaydate=todaydate, balance=balance.amount,
71
                               minbalance=minbalance, graphJSON=graphJSON)
72
73
74
@main.route('/profile')
75
@login_required
76
def profile():
77
78
    if current_user.admin:
79
        return render_template('profile.html')
80
    else:
81
        return render_template('profile_guest.html')
82
83
84
@main.route('/settings')
85
@login_required
86
def settings_page():
87
88
    if current_user.admin:
89
        return render_template('settings.html')
90
    else:
91
        return redirect(url_for('main.index'))
92
93
94
@main.route('/schedule')
95
@login_required
96
def schedule():
97
    schedule = Schedule.query.order_by(asc(extract('day', Schedule.startdate)))
98
99
    if current_user.admin:
100
        return render_template('schedule_table.html', title='Schedule Table', schedule=schedule)
101
    else:
102
        return redirect(url_for('main.index'))
103
104
105
@main.route('/holds')
106
@login_required
107
def holds():
108
    hold = Hold.query
109
    skip = Skip.query
110
111
    if current_user.admin:
112
        return render_template('holds_table.html', title='Holds Table', hold=hold, skip=skip)
113
    else:
114
        return redirect(url_for('main.index'))
115
116
117
@main.route('/create', methods=('GET', 'POST'))
118
@login_required
119
def create():
120
    # create a new schedule item
121
    if current_user.admin:
122
        format = '%Y-%m-%d'
123
        if request.method == 'POST':
124
            name = request.form['name']
125
            amount = request.form['amount']
126
            frequency = request.form['frequency']
127
            startdate = request.form['startdate']
128
            type = request.form['type']
129
            schedule = Schedule(name=name,
130
                              type=type,
131
                              amount=amount,
132
                              frequency=frequency,
133
                              startdate=datetime.strptime(startdate, format).date())
134
            existing = Schedule.query.filter_by(name=name).first()
135
            if existing:
136
                flash("Schedule already exists")
137
                return redirect(url_for('main.schedule'))
138
            db.session.add(schedule)
139
            db.session.commit()
140
            flash("Added Successfully")
141
142
            return redirect(url_for('main.schedule'))
143
144
        return redirect(url_for('main.schedule'))
145
    else:
146
        return redirect(url_for('main.index'))
147
148
149
@main.route('/update', methods=['GET', 'POST'])
150
@login_required
151
def update():
152
    # update an existing schedule item
153
    if current_user.admin:
154
        format = '%Y-%m-%d'
155
156
        if request.method == 'POST':
157
            current = Schedule.query.filter_by(id=request.form['id']).first()
158
            existing = Schedule.query.filter_by(name=request.form['name']).first()
159
            if existing:
160
                if current.name != request.form['name']:
161
                    flash("Schedule name already exists")
162
                    return redirect(url_for('main.schedule'))
163
            my_data = Schedule.query.get(request.form.get('id'))
164
            my_data.name = request.form['name']
165
            my_data.amount = request.form['amount']
166
            my_data.type = request.form['type']
167
            my_data.frequency = request.form['frequency']
168
            my_data.startdate = request.form['startdate']
169
            startdate = request.form['startdate']
170
            my_data.startdate = datetime.strptime(startdate, format).date()
171
            db.session.commit()
172
            flash("Updated Successfully")
173
174
            return redirect(url_for('main.schedule'))
175
176
        return redirect(url_for('main.schedule'))
177
    else:
178
        return redirect(url_for('main.index'))
179
180
181
@main.route('/addhold/<id>')
182
@login_required
183
def addhold(id):
184
    # add a hold item from the schedule
185
    if current_user.admin:
186
        schedule = Schedule.query.filter_by(id=id).first()
187
        hold = Hold(name=schedule.name, type=schedule.type, amount=schedule.amount)
188
        db.session.add(hold)
189
        db.session.commit()
190
191
        return redirect(url_for('main.schedule'))
192
    else:
193
        return redirect(url_for('main.index'))
194
195
196
@main.route('/addskip/<id>')
197
@login_required
198
def addskip(id):
199
    # add a skip item from the schedule
200
    if current_user.admin:
201
        transaction = Transactions.query.filter_by(id=id).first()
202
        trans_type = ""
203
        if transaction.type == "Expense":
204
            trans_type = "Income"
205
        elif transaction.type == "Income":
206
            trans_type = "Expense"
207
        skip = Skip(name=transaction.name + " (SKIP)", type=trans_type, amount=transaction.amount, date=transaction.date)
208
        db.session.add(skip)
209
        db.session.commit()
210
211
        return redirect(url_for('main.transactions'))
212
    else:
213
        return redirect(url_for('main.index'))
214
215
216
@main.route('/deletehold/<id>')
217
@login_required
218
def holds_delete(id):
219
    # delete a hold item
220
    if current_user.admin:
221
        hold = Hold.query.filter_by(id=id).first()
222
223
        if hold:
224
            db.session.delete(hold)
225
            db.session.commit()
226
            flash("Deleted Successfully")
227
228
        return redirect(url_for('main.holds'))
229
    else:
230
        return redirect(url_for('main.index'))
231
232
233
@main.route('/deleteskip/<id>')
234
@login_required
235
def skips_delete(id):
236
    # delete a skip item
237
    if current_user.admin:
238
        skip = Skip.query.filter_by(id=id).first()
239
240
        if skip:
241
            db.session.delete(skip)
242
            db.session.commit()
243
            flash("Deleted Successfully")
244
245
        return redirect(url_for('main.holds'))
246
    else:
247
        return redirect(url_for('main.index'))
248
249
250
@main.route('/clearholds')
251
@login_required
252
def clear_holds():
253
    # clear holds
254
    if current_user.admin:
255
        db.session.query(Hold).delete()
256
        db.session.commit()
257
258
        return redirect(url_for('main.holds'))
259
    else:
260
        return redirect(url_for('main.index'))
261
262
263
@main.route('/clearskips')
264
@login_required
265
def clear_skips():
266
    # clear skips
267
    if current_user.admin:
268
        db.session.query(Skip).delete()
269
        db.session.commit()
270
271
        return redirect(url_for('main.index'))
272
    else:
273
        return redirect(url_for('main.index'))
274
275
276
@main.route('/delete/<id>')
277
@login_required
278
def schedule_delete(id):
279
    # delete a schedule item
280
    if current_user.admin:
281
        schedule = Schedule.query.filter_by(id=id).first()
282
283
        if schedule:
284
            db.session.delete(schedule)
285
            db.session.commit()
286
            flash("Deleted Successfully")
287
288
        return redirect(url_for('main.schedule'))
289
    else:
290
        return redirect(url_for('main.index'))
291
292
293
@main.route('/favicon')
294
def favicon():
295
    return send_from_directory(os.path.join(main.root_path, 'static'),
296
                               'favicon.ico', mimetype='image/vnd.microsoft.icon')
297
298
299
@main.route('/appleicon')
300
def appleicon():
301
    return send_from_directory(os.path.join(main.root_path, 'static'),
302
                               'apple-touch-icon.png', mimetype='image/png')
303
304
305
@main.route('/balance', methods=('GET', 'POST'))
306
@login_required
307
def balance():
308
    # manually update the balance from the balance button
309
    if current_user.admin:
310
        format = '%Y-%m-%d'
311
        if request.method == 'POST':
312
            amount = request.form['amount']
313
            dateentry = request.form['date']
314
            balance = Balance(amount=amount,
315
                              date=datetime.strptime(dateentry, format).date())
316
            db.session.add(balance)
317
            db.session.commit()
318
319
            return redirect(url_for('main.index'))
320
    else:
321
        return redirect(url_for('main.index'))
322
323
324
@main.route('/changepw', methods=('GET', 'POST'))
325
@login_required
326
def changepw():
327
    # change the users password from the profile page
328
    if request.method == 'POST':
329
        curr_user = current_user.id
330
        my_user = User.query.filter_by(id=curr_user).first()
331
        password = request.form['password']
332
        my_user.password = generate_password_hash(password, method='scrypt')
333
        db.session.commit()
334
335
        return redirect(url_for('main.profile'))
336
337
    return redirect(url_for('main.profile'))
338
339
340
@main.route('/settings', methods=('GET', 'POST'))
341
@login_required
342
def settings():
343
    # set the settings options, in this case disable signups, from the profile page
344
    if current_user.admin:
345
        if request.method == 'POST':
346
            signupsettingname = Settings.query.filter_by(name='signup').first()
347
348
            if signupsettingname:
349
                signupvalue = request.form['signupvalue']
350
                signupsettingname.value = eval(signupvalue)
351
                db.session.commit()
352
353
                return redirect(url_for('main.profile'))
354
355
            # store the signup option value in the database to check when the user clicks signup
356
            signupvalue = request.form['signupvalue']
357
            signupvalue = eval(signupvalue)
358
            settings = Settings(name="signup",
359
                              value=signupvalue)
360
            db.session.add(settings)
361
            db.session.commit()
362
363
            return redirect(url_for('main.profile'))
364
365
        return redirect(url_for('main.profile'))
366
    else:
367
        return redirect(url_for('main.index'))
368
369
370
@main.route('/transactions')
371
@login_required
372
def transactions():
373
    total = Transactions.query
374
375
    if current_user.admin:
376
        return render_template('transactions_table.html', total=total)
377
    else:
378
        return redirect(url_for('main.index'))
379
380
381
@main.route('/email', methods=('GET', 'POST'))
382
@login_required
383
def email():
384
    # set the users email address, password, and server for the auto email balance update
385
    if current_user.admin:
386
        if request.method == 'POST':
387
            emailsettings = Email.query.filter_by(id=1).first()
388
389
            if emailsettings:
390
                email = request.form['email']
391
                password = request.form['password']
392
                server = request.form['server']
393
                subjectstr = request.form['subject_str']
394
                startstr = request.form['start_str']
395
                endstr = request.form['end_str']
396
                emailsettings.email = email
397
                emailsettings.password = password
398
                emailsettings.server = server
399
                emailsettings.subjectstr = subjectstr
400
                emailsettings.startstr = startstr
401
                emailsettings.endstr = endstr
402
                db.session.commit()
403
404
                return redirect(url_for('main.profile'))
405
406
            email = request.form['email']
407
            password = request.form['password']
408
            server = request.form['server']
409
            subjectstr = request.form['subject_str']
410
            startstr = request.form['start_str']
411
            endstr = request.form['end_str']
412
            emailentry = Email(email=email, password=password, server=server, subjectstr=subjectstr, startstr=startstr,
413
                               endstr=endstr)
414
            db.session.add(emailentry)
415
            db.session.commit()
416
417
            return redirect(url_for('main.profile'))
418
419
        return redirect(url_for('main.profile'))
420
    else:
421
        return redirect(url_for('main.index'))
422
423
424
@main.route('/users_table')
425
@login_required
426
def users():
427
    users = User.query
428
429
    if current_user.admin:
430
        return render_template('users_table.html', title='Users Table', users=users)
431
    else:
432
        return redirect(url_for('main.index'))
433
434
435
@main.route('/update_user', methods=['GET', 'POST'])
436
@login_required
437
def update_user():
438
    # update an existing user
439
    if current_user.admin:
440
        if request.method == 'POST':
441
            current = User.query.filter_by(id=request.form['id']).first()
442
            existing = User.query.filter_by(email=request.form['email']).first()
443
            if existing:
444
                if current.email != request.form['email']:
445
                    flash("Email already exists")
446
                    return redirect(url_for('main.users'))
447
            my_data = User.query.get(request.form.get('id'))
448
            my_data.name = request.form['name']
449
            my_data.email = request.form['email']
450
            my_data.admin = eval(request.form['admin'])
451
            db.session.commit()
452
            flash("Updated Successfully")
453
454
            return redirect(url_for('main.users'))
455
456
        return redirect(url_for('main.users'))
457
    else:
458
        return redirect(url_for('main.index'))
459
460
461
@main.route('/delete_user/<id>')
462
@login_required
463
def delete_user(id):
464
    # delete a user
465
    if current_user.admin:
466
        user = User.query.filter_by(id=id).first()
467
468
        if user:
469
            db.session.delete(user)
470
            db.session.commit()
471
            flash("Deleted Successfully")
472
473
        return redirect(url_for('main.users'))
474
    else:
475
        return redirect(url_for('main.index'))
476
477
478
@main.route('/create_user', methods=('GET', 'POST'))
479
@login_required
480
def create_user():
481
    # create a new user
482
    if current_user.admin:
483
        if request.method == 'POST':
484
            name = request.form['name']
485
            email = request.form['email']
486
            admin = eval(request.form['admin'])
487
            password = generate_password_hash(request.form['password'], method='scrypt')
488
            user = User(name=name, email=email, admin=admin, password=password)
489
            existing = User.query.filter_by(email=email).first()
490
            if existing:
491
                flash("User already exists")
492
                return redirect(url_for('main.users'))
493
            db.session.add(user)
494
            db.session.commit()
495
            flash("Added Successfully")
496
497
            return redirect(url_for('main.users'))
498
499
        return redirect(url_for('main.users'))
500
    else:
501
        return redirect(url_for('main.index'))
502
503
504
@main.route('/manifest.json')
505
def serve_manifest():
506
    return send_file('manifest.json', mimetype='application/manifest+json')
507
508
509
@main.route('/sw.js')
510
def serve_sw():
511
    return send_file('sw.js', mimetype='application/javascript')
512