monopyly 1.5.0__py3-none-any.whl → 1.5.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- monopyly/CHANGELOG.md +23 -0
- monopyly/README.md +2 -2
- monopyly/__init__.py +22 -27
- monopyly/_version.py +14 -2
- monopyly/auth/actions.py +12 -0
- monopyly/auth/routes.py +31 -22
- monopyly/auth/tools.py +1 -2
- monopyly/banking/accounts.py +3 -3
- monopyly/banking/banks.py +1 -1
- monopyly/banking/routes.py +1 -1
- monopyly/banking/transactions.py +14 -5
- monopyly/common/forms/utils.py +1 -2
- monopyly/common/transactions.py +17 -7
- monopyly/core/actions.py +0 -7
- monopyly/core/routes.py +0 -6
- monopyly/credit/accounts.py +1 -1
- monopyly/credit/cards.py +7 -3
- monopyly/credit/forms.py +1 -1
- monopyly/credit/routes.py +46 -25
- monopyly/credit/statements.py +1 -1
- monopyly/credit/transactions/_transactions.py +18 -5
- monopyly/credit/transactions/activity/parser.py +14 -6
- monopyly/credit/transactions/activity/reconciliation.py +20 -1
- monopyly/database/__init__.py +1 -56
- monopyly/database/models.py +181 -273
- monopyly/static/css/style.css +191 -11
- monopyly/static/js/create-balance-chart.js +1 -1
- monopyly/templates/auth/change_password.html +21 -0
- monopyly/templates/auth/login.html +3 -1
- monopyly/templates/auth/register.html +17 -7
- monopyly/templates/core/profile.html +2 -2
- monopyly/templates/credit/statement_reconciliation/statement_reconciliation_inquiry.html +1 -1
- monopyly/templates/credit/transaction_submission_page.html +64 -71
- monopyly/templates/credit/transactions_table/condensed_row_content.html +0 -1
- monopyly/templates/layout.html +2 -2
- {monopyly-1.5.0.dist-info → monopyly-1.5.2.dist-info}/METADATA +12 -13
- {monopyly-1.5.0.dist-info → monopyly-1.5.2.dist-info}/RECORD +41 -45
- {monopyly-1.5.0.dist-info → monopyly-1.5.2.dist-info}/WHEEL +1 -1
- monopyly-1.5.2.dist-info/entry_points.txt +2 -0
- monopyly/cli/apps.py +0 -108
- monopyly/cli/launch.py +0 -135
- monopyly/config/__init__.py +0 -1
- monopyly/config/default_settings.py +0 -56
- monopyly/config/settings.py +0 -59
- monopyly-1.5.0.dist-info/entry_points.txt +0 -2
- {monopyly-1.5.0.dist-info → monopyly-1.5.2.dist-info}/licenses/COPYING +0 -0
- {monopyly-1.5.0.dist-info → monopyly-1.5.2.dist-info}/licenses/LICENSE +0 -0
monopyly/static/css/style.css
CHANGED
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
--masthead-height: 50px;
|
|
12
12
|
--masthead-color: #2b2b2b;
|
|
13
13
|
--border-gray: #dddddd;
|
|
14
|
+
--button-background-base: #fbfbfb;
|
|
15
|
+
--button-background: linear-gradient(#fbfbfb, #efefef);
|
|
16
|
+
--button-block-background-base: #eeeeee;
|
|
17
|
+
--button-block-background: linear-gradient(#eeeeee, #e6e6e6);
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
html {
|
|
@@ -386,6 +390,35 @@ aside.sidebar {
|
|
|
386
390
|
}
|
|
387
391
|
|
|
388
392
|
|
|
393
|
+
/*
|
|
394
|
+
* Provide styles for flashed messages
|
|
395
|
+
*/
|
|
396
|
+
.flash.success,
|
|
397
|
+
.flash.warning,
|
|
398
|
+
.flash.error {
|
|
399
|
+
margin: 20px 0;
|
|
400
|
+
padding: 10px 20px;
|
|
401
|
+
border-radius: 10px;
|
|
402
|
+
box-shadow: 1px 1px 4px #ddd;
|
|
403
|
+
font-size: 0.9em;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.flash.success {
|
|
407
|
+
border: 1px solid #6fda6f;
|
|
408
|
+
background: linear-gradient(45deg, #e6efe1, #f5fef1);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
.flash.warning {
|
|
412
|
+
border: 1px solid #dac96f;
|
|
413
|
+
background: linear-gradient(45deg, #efede1, #fefbf1);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.flash.error {
|
|
417
|
+
border: 1px solid #da6f6f;
|
|
418
|
+
background: linear-gradient(45deg, #f3e8e8, #fef1f1);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
|
|
389
422
|
/*
|
|
390
423
|
* Provide styles for error pages
|
|
391
424
|
*/
|
|
@@ -459,8 +492,8 @@ aside.sidebar {
|
|
|
459
492
|
border: 1px solid var(--border-gray);
|
|
460
493
|
border-radius: 10px;
|
|
461
494
|
box-shadow: 1px 1px 3px #bbbbbb;
|
|
462
|
-
background-color:
|
|
463
|
-
background-image:
|
|
495
|
+
background-color: var(--button-block-background-base);
|
|
496
|
+
background-image: var(--button-block-background);
|
|
464
497
|
color: inherit;
|
|
465
498
|
}
|
|
466
499
|
|
|
@@ -546,15 +579,16 @@ aside.sidebar {
|
|
|
546
579
|
left: 0;
|
|
547
580
|
height: 100%;
|
|
548
581
|
width: 100%;
|
|
582
|
+
display: flex;
|
|
583
|
+
flex-direction: column;
|
|
584
|
+
justify-content: center;
|
|
585
|
+
align-items: center;
|
|
549
586
|
background-color: rgba(0, 0, 0, 0.75);
|
|
550
587
|
z-index: 50; /* in front of content, but behind the header */
|
|
551
588
|
}
|
|
552
589
|
|
|
553
590
|
.modal {
|
|
554
|
-
|
|
555
|
-
top: 0%;
|
|
556
|
-
left: 50%;
|
|
557
|
-
transform: translate(-50%, 15%);
|
|
591
|
+
min-width: 200px;
|
|
558
592
|
}
|
|
559
593
|
|
|
560
594
|
.modal-box {
|
|
@@ -638,8 +672,8 @@ form input.button {
|
|
|
638
672
|
align-items: center;
|
|
639
673
|
margin-top: 20px;
|
|
640
674
|
padding: 10px;
|
|
641
|
-
background-color:
|
|
642
|
-
background-image:
|
|
675
|
+
background-color: var(--button-background-base);
|
|
676
|
+
background-image: var(--button-background);
|
|
643
677
|
color: #333333;
|
|
644
678
|
font-weight:bold;
|
|
645
679
|
text-align: center;
|
|
@@ -2564,6 +2598,21 @@ form .autocomplete-box .item.active {
|
|
|
2564
2598
|
}
|
|
2565
2599
|
|
|
2566
2600
|
|
|
2601
|
+
/*
|
|
2602
|
+
* Customization for the 'Registration' page
|
|
2603
|
+
*/
|
|
2604
|
+
.no-registration-notice {
|
|
2605
|
+
width: 60%;
|
|
2606
|
+
margin: 25px auto;
|
|
2607
|
+
padding: 10px;
|
|
2608
|
+
border: 1px solid var(--moneytree-leaves);
|
|
2609
|
+
border-radius: 10px;
|
|
2610
|
+
box-shadow: 0 0 10px var(--moneytree-leaves);
|
|
2611
|
+
background-color: #f5f5f5;
|
|
2612
|
+
text-align: center;
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2615
|
+
|
|
2567
2616
|
/*
|
|
2568
2617
|
* Customization for the 'Profile' page
|
|
2569
2618
|
*/
|
|
@@ -3532,7 +3581,6 @@ form#pay #make-payment[type="submit"] #prompt {
|
|
|
3532
3581
|
#statement-reconciliation.modal {
|
|
3533
3582
|
width: 50%;
|
|
3534
3583
|
min-width: 300px;
|
|
3535
|
-
transform: translate(-50%, 100%);
|
|
3536
3584
|
}
|
|
3537
3585
|
|
|
3538
3586
|
#statement-reconciliation.modal .modal-box {
|
|
@@ -3604,13 +3652,145 @@ form#credit-transaction .merchant-field {
|
|
|
3604
3652
|
/*
|
|
3605
3653
|
* Customization for the transaction submission page
|
|
3606
3654
|
*/
|
|
3607
|
-
#
|
|
3608
|
-
|
|
3655
|
+
#submission {
|
|
3656
|
+
display: flex;
|
|
3657
|
+
flex-direction: column;
|
|
3658
|
+
align-items: center;
|
|
3659
|
+
width: 50%;
|
|
3609
3660
|
margin: auto;
|
|
3610
3661
|
}
|
|
3662
|
+
@media screen and (max-width: 600px) {
|
|
3663
|
+
/* Mobile layout */
|
|
3664
|
+
#submission {
|
|
3665
|
+
width: 90%;
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
3668
|
+
|
|
3669
|
+
#submission-title {
|
|
3670
|
+
text-align: center;
|
|
3671
|
+
}
|
|
3672
|
+
|
|
3673
|
+
#receipt {
|
|
3674
|
+
width: 60%;
|
|
3675
|
+
min-width: 250px;
|
|
3676
|
+
max-width: 300px;
|
|
3677
|
+
margin: 40px auto;
|
|
3678
|
+
padding: 10px 20px 30px;
|
|
3679
|
+
box-shadow: 2px 2px 6px #bbbbbb;
|
|
3680
|
+
background-color: #fafafa;
|
|
3681
|
+
font-family: monospace;
|
|
3682
|
+
}
|
|
3683
|
+
@media screen and (max-width: 600px) {
|
|
3684
|
+
/* Mobile layout */
|
|
3685
|
+
#receipt {
|
|
3686
|
+
margin: 10px auto 30px;
|
|
3687
|
+
}
|
|
3688
|
+
}
|
|
3611
3689
|
|
|
3612
3690
|
#receipt-title {
|
|
3691
|
+
margin-bottom: 20px;
|
|
3613
3692
|
text-align: center;
|
|
3693
|
+
color: var(--silver-dollar);
|
|
3694
|
+
font-size: 10pt;
|
|
3695
|
+
font-weight: 400;
|
|
3696
|
+
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
3697
|
+
letter-spacing: 2px;
|
|
3698
|
+
text-transform: uppercase;
|
|
3699
|
+
}
|
|
3700
|
+
|
|
3701
|
+
#receipt .receipt-item {
|
|
3702
|
+
display: flex;
|
|
3703
|
+
margin: 15px 0;
|
|
3704
|
+
}
|
|
3705
|
+
|
|
3706
|
+
#receipt .receipt-item .receipt-key {
|
|
3707
|
+
font-weight: bold;
|
|
3708
|
+
}
|
|
3709
|
+
|
|
3710
|
+
#receipt #receipt-header {
|
|
3711
|
+
margin-bottom: 40px;
|
|
3712
|
+
}
|
|
3713
|
+
|
|
3714
|
+
#receipt #receipt-header #receipt-merchant {
|
|
3715
|
+
font-size: 14pt;
|
|
3716
|
+
justify-content: center;
|
|
3717
|
+
}
|
|
3718
|
+
|
|
3719
|
+
#receipt #receipt-header #receipt-date {
|
|
3720
|
+
font-size: 10pt;
|
|
3721
|
+
font-weight: normal;
|
|
3722
|
+
justify-content: center;
|
|
3723
|
+
}
|
|
3724
|
+
|
|
3725
|
+
#receipt .receipt-subtransaction {
|
|
3726
|
+
display: flex;
|
|
3727
|
+
gap: 10px 20px;
|
|
3728
|
+
margin: 10px 0;
|
|
3729
|
+
}
|
|
3730
|
+
|
|
3731
|
+
#receipt .receipt-subtransaction .note,
|
|
3732
|
+
#receipt #receipt-total .total {
|
|
3733
|
+
flex: 4;
|
|
3734
|
+
}
|
|
3735
|
+
|
|
3736
|
+
#receipt .receipt-subtransaction .amount,
|
|
3737
|
+
#receipt #receipt-total .amount {
|
|
3738
|
+
flex: 1;
|
|
3739
|
+
text-align: right;
|
|
3740
|
+
}
|
|
3741
|
+
|
|
3742
|
+
#receipt #receipt-card {
|
|
3743
|
+
margin-top: 40px;
|
|
3744
|
+
}
|
|
3745
|
+
|
|
3746
|
+
#receipt #receipt-card .receipt-item {
|
|
3747
|
+
flex-direction: column;
|
|
3748
|
+
}
|
|
3749
|
+
|
|
3750
|
+
#receipt #receipt-card .receipt-item .receipt-key {
|
|
3751
|
+
margin-bottom: 5px;
|
|
3752
|
+
}
|
|
3753
|
+
|
|
3754
|
+
#receipt #receipt-card .receipt-item .receipt-value {
|
|
3755
|
+
margin-left: 0;
|
|
3756
|
+
}
|
|
3757
|
+
|
|
3758
|
+
#submission-actions {
|
|
3759
|
+
display: flex;
|
|
3760
|
+
flex-direction: column;
|
|
3761
|
+
gap: 3px;
|
|
3762
|
+
align-items: center;
|
|
3763
|
+
width: 100%;
|
|
3764
|
+
max-width: 400px;
|
|
3765
|
+
}
|
|
3766
|
+
@media screen and (max-width: 600px) {
|
|
3767
|
+
/* Mobile layout */
|
|
3768
|
+
#submission-actions {
|
|
3769
|
+
gap: 5px;
|
|
3770
|
+
}
|
|
3771
|
+
}
|
|
3772
|
+
|
|
3773
|
+
#submission-actions .submission.button {
|
|
3774
|
+
width: 100%;
|
|
3775
|
+
padding: 3px 10px;
|
|
3776
|
+
border: 1px solid var(--border-gray);
|
|
3777
|
+
border-radius: 5px;
|
|
3778
|
+
background-color: var(--button-background-base);
|
|
3779
|
+
background-image: var(--button-background);;
|
|
3780
|
+
font-size: 12pt;
|
|
3781
|
+
text-decoration: none;
|
|
3782
|
+
box-sizing: border-box;
|
|
3783
|
+
}
|
|
3784
|
+
@media screen and (max-width: 600px) {
|
|
3785
|
+
/* Mobile layout */
|
|
3786
|
+
#submission-actions .submission.button {
|
|
3787
|
+
padding: 10px;
|
|
3788
|
+
font-size: 10pt;
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3791
|
+
|
|
3792
|
+
#submission-actions .submission.button:hover {
|
|
3793
|
+
filter: brightness(0.98);
|
|
3614
3794
|
}
|
|
3615
3795
|
|
|
3616
3796
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{% extends 'layout.html' %}
|
|
2
|
+
|
|
3
|
+
{% block header %}
|
|
4
|
+
<h1>{% block title %}Change Password{% endblock %}</h1>
|
|
5
|
+
{% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block content %}
|
|
8
|
+
|
|
9
|
+
<form id="change-password" method="post">
|
|
10
|
+
<p class="instructions">
|
|
11
|
+
Use this form to change the password for user: <b>{{ g.user.username }}</b>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<label for="password">Current Password</label>
|
|
15
|
+
<input type="password" name="current-password" id="current-password" required>
|
|
16
|
+
<label for="new-password">New Password</label>
|
|
17
|
+
<input type="password" name="new-password" id="new-password" required>
|
|
18
|
+
<input class="button" type="submit" value="Update" />
|
|
19
|
+
</form>
|
|
20
|
+
|
|
21
|
+
{% endblock %}
|
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
{% endblock %}
|
|
6
6
|
|
|
7
7
|
{% block content %}
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
<form id="log-in" method="post">
|
|
9
10
|
<label for="username">Username</label>
|
|
10
11
|
<input name="username" id="username" required>
|
|
11
12
|
<label for="password">Password</label>
|
|
12
13
|
<input type="password" name="password" id="password" required>
|
|
13
14
|
<input class="button" type="submit" value="Log In" />
|
|
14
15
|
</form>
|
|
16
|
+
|
|
15
17
|
{% endblock %}
|
|
@@ -5,11 +5,21 @@
|
|
|
5
5
|
{% endblock %}
|
|
6
6
|
|
|
7
7
|
{% block content %}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
|
|
9
|
+
{% if not config['REGISTRATION'] %}
|
|
10
|
+
<div class="no-registration-notice">
|
|
11
|
+
<b>Notice:</b> The app is not currently accepting new registrations.
|
|
12
|
+
</div>
|
|
13
|
+
{% endif %}
|
|
14
|
+
|
|
15
|
+
{% with input_status = 'required' if config['REGISTRATION'] else 'disabled' %}
|
|
16
|
+
<form id="register" method="post">
|
|
17
|
+
<label for="username">Username</label>
|
|
18
|
+
<input name="username" id="username" {{ input_status }}>
|
|
19
|
+
<label for="password">Password</label>
|
|
20
|
+
<input type="password" name="password" id="password" {{ input_status }}>
|
|
21
|
+
<input class="button" type="submit" value="Register" />
|
|
22
|
+
</form>
|
|
23
|
+
{% endwith %}
|
|
24
|
+
|
|
15
25
|
{% endblock %}
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
<div class=user-settings">
|
|
26
26
|
|
|
27
27
|
<div class="password">
|
|
28
|
-
<a style="color: gray;" href="{{ url_for('
|
|
29
|
-
Change password
|
|
28
|
+
<a style="color: gray;" href="{{ url_for('auth.change_password') }}">
|
|
29
|
+
Change password
|
|
30
30
|
</a>
|
|
31
31
|
</div>
|
|
32
32
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
</div>
|
|
9
9
|
|
|
10
10
|
<p class="instructions">
|
|
11
|
-
Load a CSV file containing credit activity for comparison against this statement.
|
|
11
|
+
Load a CSV file containing credit activity for comparison against this statement.
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
<form action="{{ url_for('credit.load_statement_reconciliation_details', statement_id=statement_id) }}" method="post" enctype="multipart/form-data">
|
|
@@ -12,83 +12,76 @@
|
|
|
12
12
|
|
|
13
13
|
{% block content %}
|
|
14
14
|
|
|
15
|
-
<div id="
|
|
15
|
+
<div id="submission">
|
|
16
16
|
|
|
17
|
-
<p id="
|
|
17
|
+
<p id="submission-title">
|
|
18
18
|
The transaction was saved successfully.
|
|
19
19
|
</p>
|
|
20
|
-
<br>
|
|
21
20
|
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
<p>
|
|
59
|
-
<b>Statement Date: </b>
|
|
60
|
-
{{ transaction.statement.issue_date }}
|
|
61
|
-
</p>
|
|
21
|
+
<div id="receipt">
|
|
22
|
+
|
|
23
|
+
<div id="receipt-header">
|
|
24
|
+
<h2 id="receipt-title">Transaction Submission</h2>
|
|
25
|
+
<h3 id="receipt-merchant" class="receipt-item">{{ transaction.merchant }}</h3>
|
|
26
|
+
<h4 id="receipt-date" class="receipt-item">{{ transaction.transaction_date }}</h4>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
{% for subtransaction in subtransactions %}
|
|
30
|
+
<div class="receipt-subtransaction">
|
|
31
|
+
<div class="note">{{ subtransaction['note'] }}</div>
|
|
32
|
+
<div class="amount">${{ subtransaction['subtotal']|currency }}</div>
|
|
33
|
+
</div>
|
|
34
|
+
{% endfor %}
|
|
35
|
+
|
|
36
|
+
{% if subtransactions|length > 1 %}
|
|
37
|
+
<div id="receipt-total" class="receipt-item">
|
|
38
|
+
<div class="total receipt-key">Total:</div>
|
|
39
|
+
<div class="amount">${{ transaction.total|currency }}</div>
|
|
40
|
+
</div>
|
|
41
|
+
{% endif %}
|
|
42
|
+
|
|
43
|
+
<div id="receipt-card">
|
|
44
|
+
<div class="receipt-item">
|
|
45
|
+
<div class="receipt-key">Card:</div>
|
|
46
|
+
<div class="receipt-value">{{ transaction.statement.card.account.bank.bank_name }} ****-{{ transaction.statement.card.last_four_digits }}</div>
|
|
47
|
+
</div>
|
|
48
|
+
<div class="receipt-item">
|
|
49
|
+
<div class="receipt-key">Statement Date:</div>
|
|
50
|
+
<div class="receipt-value">{{ transaction.statement.issue_date }}</div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
</div>
|
|
62
56
|
|
|
63
57
|
{% if g.user %}
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
{% endwith %}
|
|
58
|
+
<div id="submission-actions">
|
|
59
|
+
<a class="submission button" href="{{ url_for('credit.update_transaction', transaction_id=transaction.id) }}">
|
|
60
|
+
Update this transaction
|
|
61
|
+
</a>
|
|
62
|
+
<a class="submission button" href="{{ url_for('credit.add_transaction') }}">
|
|
63
|
+
Create a new transaction
|
|
64
|
+
</a>
|
|
65
|
+
<a class="submission button" href="{{ url_for('credit.add_transaction', card_id=transaction.statement.card_id, statement_id=transaction.statement_id) }}">
|
|
66
|
+
Create a new transaction on this statement
|
|
67
|
+
</a>
|
|
68
|
+
<a class="submission button" href="{{ url_for('credit.load_statement_details', statement_id=transaction.statement_id) }}">
|
|
69
|
+
See the statement for this transaction
|
|
70
|
+
</a>
|
|
71
|
+
<a class="submission button" href="{{ url_for('credit.load_statements') }}">
|
|
72
|
+
See statement history
|
|
73
|
+
</a>
|
|
74
|
+
<a class="submission button" href="{{ url_for('credit.load_transactions') }}">
|
|
75
|
+
See transaction history
|
|
76
|
+
</a>
|
|
77
|
+
{% with reconciliation_info = session.get('reconciliation_info', None) %}
|
|
78
|
+
{% if reconciliation_info %}
|
|
79
|
+
<a class="submission button" href="{{ url_for('credit.load_statement_reconciliation_details', statement_id=reconciliation_info[0]) }}">
|
|
80
|
+
Return to the in-progress statement reconciliation
|
|
81
|
+
</a>
|
|
82
|
+
{% endif %}
|
|
83
|
+
{% endwith %}
|
|
84
|
+
</div>
|
|
92
85
|
{% endif %}
|
|
93
86
|
|
|
94
87
|
</div>
|
monopyly/templates/layout.html
CHANGED
|
@@ -91,8 +91,8 @@
|
|
|
91
91
|
{% block header %}{% endblock %}
|
|
92
92
|
</header>
|
|
93
93
|
|
|
94
|
-
{% for message in get_flashed_messages() %}
|
|
95
|
-
<div class="flash">{{ message }}</div>
|
|
94
|
+
{% for category, message in get_flashed_messages(with_categories=True) %}
|
|
95
|
+
<div class="flash {{ category }}">{{ message }}</div>
|
|
96
96
|
{% endfor %}
|
|
97
97
|
|
|
98
98
|
{% block content %}{% endblock %}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: monopyly
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.2
|
|
4
4
|
Summary: A homemade personal finance manager.
|
|
5
5
|
Project-URL: Download, https://pypi.org/project/monopyly
|
|
6
6
|
Project-URL: Homepage, http://monopyly.com
|
|
@@ -23,16 +23,15 @@ Classifier: Topic :: Office/Business :: Financial
|
|
|
23
23
|
Classifier: Topic :: Office/Business :: Financial :: Accounting
|
|
24
24
|
Classifier: Topic :: Office/Business :: Financial :: Spreadsheet
|
|
25
25
|
Requires-Python: <3.11,>=3.10
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist: flask-wtf==1.2.
|
|
28
|
-
Requires-Dist: flask==3.
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist:
|
|
32
|
-
Requires-Dist: nltk==3.8.1
|
|
26
|
+
Requires-Dist: dry-foundation==1.3.0
|
|
27
|
+
Requires-Dist: flask-wtf==1.2.2
|
|
28
|
+
Requires-Dist: flask==3.1.2
|
|
29
|
+
Requires-Dist: gunicorn==23.0.0
|
|
30
|
+
Requires-Dist: markdown==3.9
|
|
31
|
+
Requires-Dist: nltk==3.9.1
|
|
33
32
|
Requires-Dist: python-dateutil==2.9.0
|
|
34
|
-
Requires-Dist: rich==
|
|
35
|
-
Requires-Dist: sqlalchemy==2.0.
|
|
33
|
+
Requires-Dist: rich==14.1.0
|
|
34
|
+
Requires-Dist: sqlalchemy==2.0.43
|
|
36
35
|
Description-Content-Type: text/markdown
|
|
37
36
|
|
|
38
37
|
<div id="header">
|
|
@@ -64,10 +63,10 @@ The package requires a recent version of Python (3.10+).
|
|
|
64
63
|
|
|
65
64
|
## Getting started
|
|
66
65
|
|
|
67
|
-
Once the package is properly installed,
|
|
66
|
+
Once the package is properly installed, launch the app in local mode from the command line (the default options should be sensible, but you may customize the host and port if necessary):
|
|
68
67
|
|
|
69
68
|
```
|
|
70
|
-
$ monopyly local --browser [--host HOST] [--port PORT]
|
|
69
|
+
$ monopyly launch local --browser [--host HOST] [--port PORT]
|
|
71
70
|
```
|
|
72
71
|
|
|
73
72
|
Local mode indicates that the app is just going to be run using a locally hosted server, accessible to just your machine.
|