Compare commits
4 Commits
94f4108a3e
...
e104dd8270
| Author | SHA1 | Date | |
|---|---|---|---|
| e104dd8270 | |||
| a46b8f895a | |||
| 09de41e093 | |||
| 9c02bc94ff |
2
BUGS
2
BUGS
@@ -2,3 +2,5 @@
|
||||
|
||||
* added an electricity bill by accident for 2018, that kills lots :(
|
||||
- something to do with missing year of data in quarterly bills - still an issue
|
||||
|
||||
* if change a bill (like Amazon), then its future estimates don't update
|
||||
|
||||
5
TODO
5
TODO
@@ -13,9 +13,4 @@ CALC:
|
||||
* still get double health insurance bills sometimes (just viewing a new date might trigger this??? or at least when I changed years)
|
||||
|
||||
UI:
|
||||
* add FIXED Annotations:
|
||||
* historical annotations (at least M_quit_date, Trip_date, school_fees in 25)
|
||||
* should try AI with how to distribute annotations better
|
||||
* make bills tabs a vertical navbar instead of horizontal
|
||||
|
||||
* make FIRST_YEAR dynamic, and maybe just WARN if next pay is > FIRST_YEAR (let me sort if by hand - probably non-issue as unlikely to be working in late Dec 26)
|
||||
|
||||
2
calc.py
2
calc.py
@@ -34,7 +34,7 @@ def bill_amount_today(finance, day, bill_data, bt_id_name, total ):
|
||||
|
||||
def add_annotation(finance, dt, total, delta, text):
|
||||
tm = dt.timestamp() * 1000
|
||||
if delta > 0:
|
||||
if delta >= 0:
|
||||
text += f": ${int(abs(delta))}"
|
||||
else:
|
||||
text += f": -${int(abs(delta))}"
|
||||
|
||||
2
main.py
2
main.py
@@ -33,6 +33,8 @@ def index():
|
||||
bill_types = get_bill_types()
|
||||
depletion_date, savings_per_fortnight, final_savings = calculate_savings_depletion(finance_data, bill_data, bill_types)
|
||||
add_historical_annotations( finance_data )
|
||||
# now sort this by X, then Y, to get the historical ones in the right order
|
||||
finance_data['annotations'].sort(key=lambda item: (item['x'], item['y']))
|
||||
BUDGET=get_budget_data(finance_data)
|
||||
|
||||
if depletion_date:
|
||||
|
||||
11
static/favicon.svg
Normal file
11
static/favicon.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="16" cy="16" r="16" fill="#1B2E3C"/>
|
||||
|
||||
<rect x="9" y="17" width="4" height="7" rx="1" fill="white"/>
|
||||
<rect x="15" y="14" width="4" height="10" rx="1" fill="white"/>
|
||||
<rect x="21" y="10" width="4" height="14" rx="1" fill="white"/>
|
||||
|
||||
<path d="M8 14L14 9L18 11L25 4" stroke="lightblue" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M21 4H25V8" stroke="lightblue" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 585 B |
@@ -14,7 +14,8 @@
|
||||
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
|
||||
<style>
|
||||
.col-form-label { width:140px; }
|
||||
html { font-size: 80%; }
|
||||
html { font-size: 75% !important; }
|
||||
@media (max-width: 2000px) { html { font-size: 70% !important; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -193,15 +194,17 @@
|
||||
<span class="bi bi-x"> Cancel</span> </button>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="d-flex align-items-start">
|
||||
<!-- create tabbed view for each bill type -->
|
||||
<nav id="bills-nav" class="nav nav-tabs">
|
||||
<nav id="bills-nav" class="nav flex-column nav-pills me-3">
|
||||
{% for bt in bill_types %}
|
||||
<button class="nav-link" id="tab-but-{{bt.id}}" data-bs-toggle="tab" data-bs-target="#tab-{{bt.id}}" type="button" role="tab" aria-controls="tab1" aria-selected="true" onClick="SaveTab('{{bt.id}}')">{{bt.name}}</button>
|
||||
<button class="nav-link w-100 text-end col px-1 py-2" id="tab-but-{{bt.id}}" data-bs-toggle="tab" data-bs-target="#tab-{{bt.id}}" type="button" role="tab" aria-controls="tab1" aria-selected="true" onClick="SaveTab('{{bt.id}}')">{{bt.name}}</button>
|
||||
{% endfor %}
|
||||
</nav>
|
||||
|
||||
<div class="tab-content">
|
||||
<div class="col-2 form-check form-switch form-check-inline">
|
||||
<div class="col form-check form-switch form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" value="" id="showEstimated" onChange="ToggleEstimated()">
|
||||
<label class="form-check-label" for="flexCheckDefault">Show Estimates</label>
|
||||
</div>
|
||||
@@ -214,8 +217,7 @@
|
||||
{% for bd in bill_data %}
|
||||
{% if loop.first %}
|
||||
<div class="row pt-2">
|
||||
<div class="p-0 col-2"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Name</ ></div>
|
||||
<div class="p-0 col-2"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Date</ ></div>
|
||||
<div class="p-0 col"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Date</ ></div>
|
||||
<div class="p-0 col"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Amount</ ></div>
|
||||
<div class="px-0 col"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0">Actions</ ></div>
|
||||
<div class="px-0 col"><label class="form-control text-center border-0 fw-bold bg-body-tertiary rounded-0 h-100"></ ></div>
|
||||
@@ -229,11 +231,11 @@
|
||||
<div class="row">
|
||||
{% set classes="form-control text-center" %}
|
||||
{% endif %}
|
||||
<div class="px-0 col-2"> <input type="text" class="{{classes}}" id="bill-data-type-{{bd.id}}" value="{{ bd.name }}" disabled> </div>
|
||||
<input type="hidden" id="bill-data-type-{{bd.id}}" value="{{ bd.name }}"> </input>
|
||||
{% if bd.bill_date == 'future' %}
|
||||
<div class="px-0 col-2"> <input type="text" class="{{classes}}" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
|
||||
<div class="px-0 col"> <input type="text" class="{{classes}}" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
|
||||
{% else %}
|
||||
<div class="px-0 col-2"> <input type="date" class="{{classes}}" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
|
||||
<div class="px-0 col"> <input type="date" class="{{classes}}" id="bill-data-date-{{bd.id}}" value="{{ bd.bill_date }}" disabled> </div>
|
||||
<script>
|
||||
if( typeof future_id !== 'undefined' && future_id>0) {
|
||||
first_col_id={{bd.id}}
|
||||
@@ -259,6 +261,7 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function ToggleEstimated()
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
|
||||
<style>
|
||||
.col-form-label { width:140px; }
|
||||
html { font-size: 80%; }
|
||||
html { font-size: 75% !important; }
|
||||
@media (max-width: 2000px) { html { font-size: 70% !important; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
|
||||
|
||||
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='favicon.svg') }}">
|
||||
|
||||
<title>Finance Form</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
@@ -17,7 +17,7 @@
|
||||
<style>
|
||||
.col-form-label { width:140px; }
|
||||
html { font-size: 75% !important; }
|
||||
@media (max-width: 2000px) { html { font-size: 70% !important; } }
|
||||
@media (max-width: 2000px) { html { font-size: 69% !important; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -302,11 +302,42 @@
|
||||
});
|
||||
|
||||
const annotations = [];
|
||||
// offset is used to make the next annotation be on slightly different vertical offsets (size is based on $'s)
|
||||
// HACK: start at 13, later we adjust in steps of 50s allowing 4 steps, then we go back to top
|
||||
var offset=13
|
||||
// this annotation stuff is painful, its in y-coords for the point
|
||||
// (based on graphs y-axis, but then needs an offset in absolute pixels) so this two coord systems makes it hard to keep the labels going, there
|
||||
// are a few hacks below that probably will break if the data changes too much
|
||||
var last_y = {{finance['annotations'][0]['y']}}
|
||||
var how_many_up = 0
|
||||
var how_many_down = 0
|
||||
var offset_y = 0
|
||||
var offset_x = 0
|
||||
|
||||
// Add annotations for changes greater than 5000
|
||||
{% for a in finance['annotations'] %}
|
||||
{% if '-$' in a['label'] %}
|
||||
how_many_down += 1
|
||||
offset_y = ({{a['y']}} - last_y)/650 + 25*how_many_down
|
||||
offset_x = -60-10*how_many_down
|
||||
if( how_many_down > 12 )
|
||||
how_many_down =0
|
||||
// console.log( "{{a['label']}} U:" + how_many_up + ", D: " + how_many_down + ", last_y=" + last_y + ", y={{a['y']}}, offset_y=" + offset_y + ", offset_x=" + offset_x )
|
||||
last_y = {{a['y']}}
|
||||
{% else %}
|
||||
how_many_up += 1
|
||||
offset_y = -25
|
||||
{% if a['y'] > 400000 %}
|
||||
offset_x = -80 -30*(6-how_many_up)
|
||||
console.log('do the hack')
|
||||
{% else %}
|
||||
offset_x = -50 -10*how_many_up
|
||||
console.log('not hack')
|
||||
{% endif %}
|
||||
if( how_many_up > 3 )
|
||||
how_many_up=0
|
||||
{% endif %}
|
||||
|
||||
{% if a['y'] < 210000 %}
|
||||
offset_y -= 300
|
||||
{% endif %}
|
||||
annotations.push({
|
||||
labels: [{
|
||||
point: {
|
||||
@@ -316,20 +347,11 @@
|
||||
xAxis: 0,
|
||||
yAxis: 0
|
||||
},
|
||||
x: -70,
|
||||
{% if '-$' in a['label'] %}
|
||||
y: offset,
|
||||
{% else %}
|
||||
y: -20,
|
||||
{% endif %}
|
||||
x: offset_x,
|
||||
y: offset_y,
|
||||
text: '{{a['label']}}'
|
||||
}], labelOptions: { allowOverlap: true }
|
||||
});
|
||||
{% if a['y'] > 200000 %}
|
||||
offset = ({{loop.index}} * 50 % 200) +50
|
||||
{% else %}
|
||||
offset = -100
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
document.keep = annotations
|
||||
|
||||
|
||||
Reference in New Issue
Block a user