too much to enumerate, too little time, have to push
This commit is contained in:
parent
9f90d357fd
commit
a8f0deab28
14 changed files with 567 additions and 17 deletions
|
|
@ -16,6 +16,3 @@ migrate.init_app(app,db)
|
|||
from app import models #.models import Vendor, LineItem, BudgetCategory
|
||||
from app import routes
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
|
|
|
|||
|
|
@ -3,18 +3,18 @@ from sqlalchemy import Column, INTEGER, String
|
|||
|
||||
class Vendor(db.Model):
|
||||
__tablename__ = 'vendor'
|
||||
id = Column('id', INTEGER(), primary_key=True)
|
||||
id = Column('id', INTEGER(), primary_key=True, autoincrement=True)
|
||||
name = Column('name', String(), nullable=False)
|
||||
bc_id = Column('bc_id', INTEGER(), nullable=True)
|
||||
|
||||
class BudgetCategory(db.Model):
|
||||
__tablename__ = 'budget_category'
|
||||
id = Column('id', INTEGER(), primary_key=True)
|
||||
id = Column('id', INTEGER(), primary_key=True, autoincrement=True)
|
||||
name = Column('name', String(), nullable=False)
|
||||
|
||||
class LineItem(db.Model):
|
||||
__tablename__ = 'line_item'
|
||||
id = Column('id', INTEGER(), primary_key=True)
|
||||
id = Column('id', INTEGER(), primary_key=True, autoincrement=True)
|
||||
parent_line_item_id = Column('parent_line_item_id', INTEGER(), nullable=True)
|
||||
amount = Column('amount', INTEGER(), nullable=False)
|
||||
currency_type = Column('currency_type', String(), default='shekel')
|
||||
|
|
|
|||
|
|
@ -1,8 +1,99 @@
|
|||
from app import app
|
||||
from flask import render_template
|
||||
|
||||
from app import app, db
|
||||
from flask import render_template, redirect, url_for, request
|
||||
from sqlalchemy import select, delete, update
|
||||
from app.models import LineItem, BudgetCategory, Vendor
|
||||
import datetime
|
||||
import os
|
||||
import openpyxl
|
||||
import time
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def home():
|
||||
return render_template('index.html')
|
||||
this_year = datetime.datetime.now().date().year
|
||||
this_month = datetime.datetime.now().date().month
|
||||
# line_item_dates = db.session.query(select(LineItem.date).order_by(LineItem.date))
|
||||
notes = db.session.execute(select(LineItem.note)).all()
|
||||
vendors = db.session.execute(select(Vendor)).all()
|
||||
budget_categories = db.session.execute(select(BudgetCategory)).all()
|
||||
files = os.listdir('C:/Users/Lenovo/Desktop/BudgetingApp/app/static/uploadable')
|
||||
return render_template('index.html',
|
||||
files=files,
|
||||
notes=notes,
|
||||
vendors=vendors,
|
||||
budget_categories=budget_categories)
|
||||
|
||||
@app.route('/upload_file/<filename>')
|
||||
def upload_file(filename):
|
||||
|
||||
file_path = 'C:/Users/Lenovo/Desktop/BudgetingApp/app/static/uploadable/' + filename
|
||||
xl = openpyxl.load_workbook(file_path, read_only=True)
|
||||
wb = xl.worksheets[0]
|
||||
|
||||
items_to_add = []
|
||||
|
||||
vendors = db.session.execute(select(Vendor.name)).all()
|
||||
vendors_added = [vendor[0] for vendor in vendors]
|
||||
|
||||
for line, row in enumerate(wb.rows):
|
||||
row = [x.value for x in row]
|
||||
if line == 0:
|
||||
columns = {x: i for i,x in enumerate(row)}
|
||||
continue
|
||||
if row[columns['Charge']]:
|
||||
amount=row[columns['Charge']] * -1
|
||||
else:
|
||||
amount=row[columns['Deposit']]
|
||||
|
||||
date = row[0]
|
||||
date = time.mktime(date.timetuple())
|
||||
|
||||
if not row[columns['Vendor']] in vendors_added:
|
||||
vendors_added.append(row[columns['Vendor']])
|
||||
vendor = Vendor(
|
||||
name=row[columns['Vendor']]
|
||||
)
|
||||
db.session.add(vendor)
|
||||
db.session.commit()
|
||||
|
||||
line_item = LineItem(
|
||||
parent_line_item_id=None,
|
||||
amount=amount,
|
||||
currency_type='shekel',
|
||||
vendor_id=None,
|
||||
date=date,
|
||||
confirmation_code=row[columns['Confirmation Code']],
|
||||
note=row[columns['Note']]
|
||||
)
|
||||
items_to_add.append(line_item)
|
||||
|
||||
xl.close()
|
||||
|
||||
db.session.add_all(items_to_add)
|
||||
db.session.commit()
|
||||
|
||||
# os.remove(file_path)
|
||||
return redirect(url_for('home'))
|
||||
|
||||
@app.route('/view_month/<year>/<month>')
|
||||
def view_month(year, month):
|
||||
return render_template('view_month.html',
|
||||
month=month,
|
||||
year=year)
|
||||
|
||||
@app.route('/add_budget_category', methods=['POST'])
|
||||
def add_budget_category():
|
||||
if request.method == 'POST':
|
||||
|
||||
category_name = request.form['category_name']
|
||||
bc = BudgetCategory(name=category_name)
|
||||
db.session.add(bc)
|
||||
db.session.commit()
|
||||
return redirect(url_for('home'))
|
||||
|
||||
@app.route('/delete_budget_category/<id>', methods=['POST'])
|
||||
def delete_budget_category(id):
|
||||
db.session.execute(update(Vendor).where(Vendor.bc_id==id).values(bc_id=None))
|
||||
db.session.execute(delete(BudgetCategory).where(BudgetCategory.id==id))
|
||||
db.session.commit()
|
||||
return {"status":'success'}
|
||||
|
|
@ -1,11 +1,127 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Budgeting</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Budgeting</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container mt-5">
|
||||
{% if files %}
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
File available in static folder for upload
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Filename</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for file in files %}
|
||||
<tr>
|
||||
<th scope="row"><a href="{{url_for('upload_file', filename=file)}}">{{file}}</a></th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
No files in the upload folder
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
Budget Categories
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<form action="{{ url_for('add_budget_category') }}" method="POST">
|
||||
<div class="mb-3">
|
||||
<label for="categoryName" class="form-label">Add Budget Category</label>
|
||||
<input type="text" class="form-control" id="categoryName" name="category_name" placeholder="Enter category name" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</form>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for bc in budget_categories %}
|
||||
<tr id="{{bc[0].id}}-row">
|
||||
<th scope="row">{{bc[0].id}}</th>
|
||||
<th scope="row">{{bc[0].name}}</th>
|
||||
<th scope="row"><button class="btn btn-danger del-button" id="{{bc[0].id}}">Delete</button></th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
Vendors
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for vendor in vendors %}
|
||||
<tr>
|
||||
<th scope="row">{{vendor[0].id}}</th>
|
||||
<th scope="row">{{vendor[0].name}}</th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
Notes
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<tbody>
|
||||
{% for note in notes %}
|
||||
{% if note[0] %}
|
||||
<tr>
|
||||
<th scope="row">{{note[0]}}</th>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="{{url_for('.static', filename='index.js')}}"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
37
app/templates/view_month.html
Normal file
37
app/templates/view_month.html
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Budgeting</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-5">
|
||||
{% if files %}
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
{{month}} - {{year}}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Line</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap JS and dependencies -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue