Add a bunch of fixes, categories

- Go through and update database
This commit is contained in:
Sara Montecino 2022-10-31 00:57:57 -07:00
parent 9e544ec64a
commit d986461019
8 changed files with 135 additions and 34 deletions

7
.vscode/launch.json vendored
View File

@ -11,7 +11,12 @@
"program": "main.py", "program": "main.py",
"console": "integratedTerminal", "console": "integratedTerminal",
"justMyCode": true, "justMyCode": true,
"args": ["C:\\Users\\saram\\Downloads\\Statement_072022_4653.pdf"] "args": [
// "C:\\Users\\saram\\Downloads\\Statement_072022_4653.pdf",
// "C:\\Users\\saram\\Downloads\\Statement_082022_4653.pdf",
"C:\\Users\\saram\\Downloads\\Statement_092022_4653.pdf",
"C:\\Users\\saram\\Downloads\\Statement_102022_4653.pdf",
]
}, },
{ {
"name": "Create Database", "name": "Create Database",

19
app.py
View File

@ -105,8 +105,9 @@ def transaction(uuid=None):
# Default if no method is hit # Default if no method is hit
abort(400) abort(400)
@app.route("/categories") @app.route("/categories", methods=["GET", "POST"])
def categories(): def categories():
if request.method == "GET":
try: try:
raw_categories = database.TransactionCategory.select() raw_categories = database.TransactionCategory.select()
categories = {} categories = {}
@ -123,5 +124,21 @@ def categories():
abort(404) abort(404)
except: except:
abort(500) abort(500)
if request.method == "POST":
body = request.get_json()
try:
if 'parent' in body:
parent = database.TransactionCategory.get(database.TransactionCategory.name == body['parent'])
database.TransactionCategory.create(name=body['name'], parent=parent)
else:
database.TransactionCategory.create(name=body['name'])
return ('', 200)
except peewee.DoesNotExist:
abort(404)
except:
abort(500)
# Should never get here.
abort(500)
app.run() app.run()

BIN
budget.db Executable file

Binary file not shown.

View File

@ -53,13 +53,16 @@ class Transactions(Regex):
date = result[0] date = result[0]
description = " ".join(result[1].split()) description = " ".join(result[1].split())
is_payment = '-' in result[2] is_credit = '-' in result[2]
amount = float(result[3].replace(',', '')) amount = float(result[3].replace(',', ''))
if is_payment: if is_credit:
if "AUTOPAY" in description:
print(f"Skipping payment: {amount}") print(f"Skipping payment: {amount}")
continue continue
amount *= -1
transactions.append([date, description, amount]) transactions.append([date, description, amount])
return transactions return transactions

View File

@ -41,6 +41,15 @@ def add_default_categories():
for child in children: for child in children:
TransactionCategory.create(name=child, parent=parent_db) TransactionCategory.create(name=child, parent=parent_db)
def delete_transactions():
instance.connect()
# august_2022 = datetime.datetime(2022, 8, 18, 0)
# delete_query = Transaction.delete().where(Transaction.transaction_date > august_2022)
delete_query = Transaction.delete().where(Transaction.primary_key == 83)
delete_query.execute()
instance.close()
class BaseModel(Model): class BaseModel(Model):
class Meta: class Meta:
database = instance database = instance

View File

@ -34,7 +34,7 @@ for f in args.files:
transaction_date=date, transaction_date=date,
description=description, description=description,
amount=amount, amount=amount,
source_filename=filename, source_file=filename,
type=file_parser.source type=file_parser.source
) )
database.instance.close() database.instance.close()

View File

@ -100,6 +100,12 @@
<button id="modal_next" class="next">Submit</button> <button id="modal_next" class="next">Submit</button>
</div> </div>
</div> </div>
<h2>Add category</h2>
<label for="category_parent">Parent: </label>
<select id="category_parent"></select>
<label for="category_name">Name: </label>
<input id="category_name">
<button id="category_add">Add</button>
<!-- Transaction Modal End --> <!-- Transaction Modal End -->
</body> </body>
<script> <script>
@ -142,6 +148,13 @@
}, },
}; };
const category =
{
name_input: document.getElementById('category_name'),
parent_select: document.getElementById('category_parent'),
add_button: document.getElementById('category_add'),
};
// Global variables. // Global variables.
const global_data = const global_data =
{ {
@ -153,7 +166,8 @@
process_index: 0, process_index: 0,
unprocessed_cnt: function() unprocessed_cnt: function()
{ {
return this.unprocessed_indices.length; const diff = this.unprocessed_indices.length - 1 - this.process_index
return diff >= 0 ? diff : 0;
}, },
get_current: function() get_current: function()
{ {
@ -303,7 +317,7 @@
{ {
x_action.split.container.style.display = 'block'; x_action.split.container.style.display = 'block';
const transaction = global_data.transaction.get_current(); const transaction = global_data.transaction.get_current();
x_action.split.amount.value = transaction.amount / 2; x_action.split.type.onchange();
} }
else else
{ {
@ -315,11 +329,11 @@
{ {
const selected = x_action.split.type.value; const selected = x_action.split.type.value;
const transaction = global_data.transaction.get_current(); const transaction = global_data.transaction.get_current();
if (selected == "Splitwise") if (selected == 2) // Splitwise
{ {
x_action.split.amount.value = transaction.amount / 2; x_action.split.amount.value = transaction.amount / 2;
} }
else else if (selected == 3) //SpaceX
{ {
x_action.split.amount.value = transaction.amount; x_action.split.amount.value = transaction.amount;
} }
@ -346,9 +360,43 @@
x_action.subcategory.appendChild(opt); x_action.subcategory.appendChild(opt);
} }
} }
} }
category.add_button.onclick = function()
{
const body = {};
body.name = category.name_input.value;
const selected = category.parent_select.value;
if (selected != "none" )
{
body.parent = selected;
}
const url = "/categories";
const handler =
{
success: function()
{
get_categories();
},
error: function()
{
alert("Failed to add category");
}
}
http_request(url, handler, "POST", body);
category.parent_select.value = "none";
category.name_input.value = "";
}
category.name_input.onkeypress = function(event) {
if (event.key === "Enter")
{
event.preventDefault();
category.add_button.click();
}
};
function reset_transaction_ui(close_modal=true) function reset_transaction_ui(close_modal=true)
{ {
// Reset all stateful inputs. // Reset all stateful inputs.
@ -359,11 +407,13 @@
x_action.split.container.style.display = 'none'; x_action.split.container.style.display = 'none';
x_action.split.enabled.checked = false; x_action.split.enabled.checked = false;
x_action.split.notes.value = "";
x_action.category.innerHTML = ""; x_action.category.innerHTML = "";
x_action.subcategory.innerHTML = ""; x_action.subcategory.innerHTML = "";
x_action.subcategory.disabled = "true"; x_action.subcategory.disabled = "true";
x_action.notes.value = ""; x_action.notes.value = "";
} }
function update_transaction_ui(transaction) function update_transaction_ui(transaction)
{ {
// Reset old state. // Reset old state.
@ -408,6 +458,7 @@
{ {
success: function(data) { success: function(data) {
global_data.categories = data global_data.categories = data
update_category_ui();
}, },
error: function() { error: function() {
console.error("Failed to get categories"); console.error("Failed to get categories");
@ -416,6 +467,22 @@
http_request(request_url, handler); http_request(request_url, handler);
} }
function update_category_ui()
{
function add_opt(key)
{
const opt = document.createElement("option");
opt.value = key;
opt.innerText = key;
category.parent_select.appendChild(opt);
}
category.parent_select.innerHTML = "";
add_opt("none");
for (key in global_data.categories) add_opt(key);
}
function http_request(url, response_handler, method="GET", body=null) function http_request(url, response_handler, method="GET", body=null)
{ {
let request = new XMLHttpRequest(); let request = new XMLHttpRequest();

View File

@ -4,11 +4,11 @@ Every week, I need to:
2. Update SplitWise for shared purchases 2. Update SplitWise for shared purchases
# Tasks # Tasks
xParse capital one statement
## Parse capital one statement x Given a PDF bank statement from capital one, extract the transaction date, description, and amount from each transaction
x Given a PDF bank statement from capital one, extract the transaction date, description, and amount from each transaction xStore the data in a SQL lite database
xStore the data in a SQL lite database
x Create database schema x Create database schema
x Automatically add capital one transactions to database x Automatically add capital one transactions to database
Add web page to categorize transactions xAdd web page to categorize transactions
Add web page to add categories xAdd web page to add categories
Visualize spend for each month