Passed
Branch master (eeaaf7)
by William
02:12 queued 34s
created

app.main.serve_manifest()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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