[Flask] Simple ERP for a farm.
Basic app.
Changed files
app/database.py
app/forms.py
@@ -1,24 +1,93 @@
1
Added:
"""
2
Added:
Form classes must be named 'Add{Item}', Item referring to the
3
Added:
model concerned.
4
Added:
"""
5
Added:
1
6
from flask_wtf import FlaskForm
2
Removed:
from wtforms import StringField, PasswordField, SubmitField, BooleanField
3
Removed:
from wtforms.validators import DataRequired, Length, EqualTo
7
Added:
from wtforms import (
8
Added:
SubmitField,
9
Added:
SelectField,
10
Added:
RadioField,
11
Added:
HiddenField,
12
Added:
StringField,
13
Added:
PasswordField,
14
Added:
IntegerField,
15
Added:
FloatField,
16
Added:
DateTimeField,
17
Added:
)
18
Added:
from wtforms.validators import InputRequired, Length, NumberRange
4
19
5
20
6
Removed:
class RegistrationForm(FlaskForm):
7
Removed:
alias = StringField("Alias", validators=[DataRequired(), Length(min=2, max=20)])
8
Removed:
password = PasswordField("Password", validators=[DataRequired()])
9
Removed:
password_confirm = PasswordField(
10
Removed:
"Confirm Password", validators=[DataRequired(), EqualTo("password")]
21
Added:
class AddCustomer(FlaskForm):
22
Added:
name = StringField("Customer name", validators=[InputRequired()])
23
Added:
name_alternative = StringField("Alternative name")
24
Added:
# date_time_created = DateTimeField("Creation date")
25
Added:
code_customer = StringField("Customer code")
26
Added:
code_accounting = StringField("Accounting code")
27
Added:
address = StringField("Address")
28
Added:
postal_code = StringField("Postal Code")
29
Added:
city = StringField("City")
30
Added:
country = StringField("Country")
31
Added:
phone = StringField("Phone")
32
Added:
website = StringField("Website")
33
Added:
email = StringField("E-mail")
34
Added:
professional_id_1 = StringField("Professional ID 1")
35
Added:
professional_id_2 = StringField("Professional ID 2")
36
Added:
tax_id = StringField("Tax ID")
37
Added:
payment_terms = StringField("Payment Terms", default="Tu vas payer sale chien!")
38
Added:
submit = SubmitField("Add/Update Product")
39
Added:
40
Added:
41
Added:
class AddProduct(FlaskForm):
42
Added:
name = StringField("Product name", validators=[InputRequired()])
43
Added:
code_accounting = StringField("Accounting code", default=0)
44
Added:
unit_weight = FloatField("Unit weight", default=0)
45
Added:
price_net = FloatField("Price (net)", default=0)
46
Added:
price_gross = FloatField("Price (gross)", default=0)
47
Added:
tax_rate = FloatField("Tax rate", default=0)
48
Added:
submit = SubmitField("Add/Update Product")
49
Added:
50
Added:
51
Added:
class AddLog(FlaskForm):
52
Added:
target = SelectField(
53
Added:
"Type",
54
Added:
choices=[("False", "Log"), ("True", "Target")],
55
Added:
validators=[InputRequired()],
11
56
)
12
Removed:
submit = SubmitField("Create Alias")
57
Added:
nno3 = FloatField("NNO3", default=0)
58
Added:
p = FloatField("P", default=0)
59
Added:
k = FloatField("K", default=0)
60
Added:
ca = FloatField("Ca", default=0)
61
Added:
mg = FloatField("Mg", default=0)
62
Added:
s = FloatField("S", default=0)
63
Added:
na = FloatField("Na", default=0)
64
Added:
cl = FloatField("Cl", default=0)
65
Added:
fe = FloatField("Fe", default=0)
66
Added:
zn = FloatField("Zn", default=0)
67
Added:
b = FloatField("B", default=0)
68
Added:
mn = FloatField("Mn", default=0)
69
Added:
cu = FloatField("Cu", default=0)
70
Added:
mo = FloatField("Mo", default=0)
71
Added:
si = FloatField("Si", default=0)
72
Added:
nnh4 = FloatField("NNH4", default=0)
73
Added:
submit = SubmitField("Add/Update Log")
13
74
14
75
15
Removed:
class LoginForm(FlaskForm):
16
Removed:
alias = StringField("Alias", validators=[DataRequired(), Length(min=2, max=20)])
17
Removed:
password = PasswordField("Password", validators=[DataRequired()])
18
Removed:
remember = BooleanField("Remember Alias")
19
Removed:
submit = SubmitField("Login Alias")
76
Added:
class AddOrder(FlaskForm): # TODO
77
Added:
name = StringField("Product name", validators=[InputRequired()])
78
Added:
code_accounting = StringField("Accounting code", default=0)
79
Added:
unit_weight = FloatField("Unit weight", default=0)
80
Added:
price_net = FloatField("Price (net)", default=0)
81
Added:
price_gross = FloatField("Price (gross)", default=0)
82
Added:
tax_rate = FloatField("Tax rate", default=0)
83
Added:
submit = SubmitField("Add/Update Product")
20
84
21
85
22
Removed:
class NewMessage(FlaskForm):
23
Removed:
recipient = StringField("Recipient", validators=[DataRequired()])
24
Removed:
message = StringField("message", validators=[DataRequired()])
86
Added:
class AddInvoice(FlaskForm):
87
Added:
name = StringField("Product name", validators=[InputRequired()])
88
Added:
code_accounting = StringField("Accounting code", default=0)
89
Added:
unit_weight = FloatField("Unit weight", default=0)
90
Added:
price_net = FloatField("Price (net)", default=0)
91
Added:
price_gross = FloatField("Price (gross)", default=0)
92
Added:
tax_rate = FloatField("Tax rate", default=0)
93
Added:
submit = SubmitField("Add/Update Product")
app/model.py
@@ -1,39 +1,161 @@
1
Removed:
import SQAlchemy
1
Added:
# import SQLAlchemy
2
Added:
from flask_sqlalchemy import SQLAlchemy
3
Added:
from datetime import datetime
2
4
3
Removed:
class Users(db.Model):
4
Removed:
id = db.Column(db.Integer, primary_key=True)
5
Removed:
name_first = db.Column(db.String(20), nullable=False)
6
Removed:
name_last = db.Column(db.String(20), nullable=False)
5
Added:
db = SQLAlchemy()
7
6
7
Added:
8
Added:
class Module(db.Model):
9
Added:
name = db.Column(
10
Added:
"Name", db.String(20), unique=True, nullable=False, primary_key=True
11
Added:
)
12
Added:
description = db.Column("Description", db.String(50), nullable=False)
13
Added:
8
14
def __repr__(self):
9
Removed:
return f"<User {self.name_first} {self.name_last}>"
15
Added:
return f"<Module {self.name}>"
10
16
11
17
12
Removed:
class Projects(db.Model):
13
Removed:
id = db.Column(db.Integer, primary_key=True)
14
Removed:
name = db.Column(db.String(20), nullable=False)
15
Removed:
name_full = db.Column(db.String(20), nullable=False)
16
Removed:
nickname = db.Column(db.String(20), nullable=False)
17
Removed:
city = db.Column(db.String(20), nullable=False)
18
Added:
class Customer(db.Model):
19
Added:
primary_key = db.Column("CustomerId", db.Integer, nullable=False, primary_key=True)
20
Added:
name = db.Column("Name", db.String(20), nullable=False)
21
Added:
name_alternative = db.Column("NameAlternative", db.String(20))
22
Added:
date_time_created = db.Column("DateTimeCreated", db.String(20), nullable=False)
23
Added:
date_time_updated = db.Column("DateTimeUpdated", db.String(20), nullable=False)
24
Added:
code_customer = db.Column("CodeCustomer", db.String(20), unique=True)
25
Added:
code_accounting = db.Column("CodeAccounting", db.String(20), unique=True)
26
Added:
address = db.Column("Address", db.String(20))
27
Added:
postal_code = db.Column("PostalCode", db.Integer)
28
Added:
city = db.Column("City", db.String(20))
29
Added:
country = db.Column("Country", db.String(20))
30
Added:
phone = db.Column("Phone", db.String(20))
31
Added:
website = db.Column("Website", db.String(20))
32
Added:
email = db.Column("Email", db.String(20))
33
Added:
professional_id_1 = db.Column("ProfessionalId1", db.String(20), unique=True)
34
Added:
professional_id_2 = db.Column("ProfessionalId2", db.String(20), unique=True)
35
Added:
tax_id = db.Column("TaxId", db.String(20), unique=True)
36
Added:
payment_terms = db.Column("PaymentTerms", db.String(20), unique=True)
18
37
19
38
def __repr__(self):
20
Removed:
return f"<Project {self.name}>"
39
Added:
return f"<Customer {self.name}>"
21
40
22
41
23
Removed:
class Modules(db.Model):
42
Added:
class Product(db.Model):
43
Added:
primary_key = db.Column("ProductId", db.Integer, primary_key=True)
44
Added:
name = db.Column("Name", db.String(20), nullable=False, unique=True)
45
Added:
code_accounting = db.Column("CodeAccounting", db.String(20))
46
Added:
unit_weight = db.Column("UnitWeight", db.Float)
47
Added:
price_net = db.Column("PriceNet", db.Float)
48
Added:
price_gross = db.Column("PriceGross", db.Float)
49
Added:
tax_rate = db.Column("TaxRate", db.Float)
50
Added:
date_time_created = db.Column(
51
Added:
"DateTimeCreated",
52
Added:
db.String,
53
Added:
default=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
54
Added:
)
55
Added:
date_time_updated = db.Column(
56
Added:
"DateTimeUpdated",
57
Added:
db.String,
58
Added:
default=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
59
Added:
)
60
Added:
61
Added:
def __init__(
62
Added:
self,
63
Added:
name,
64
Added:
code_accounting,
65
Added:
unit_weight,
66
Added:
price_net,
67
Added:
price_gross,
68
Added:
tax_rate,
69
Added:
):
70
Added:
self.name = name
71
Added:
self.code_accounting = code_accounting
72
Added:
self.unit_weight = unit_weight
73
Added:
self.price_net = price_net
74
Added:
self.price_gross = price_gross
75
Added:
self.tax_rate = tax_rate
76
Added:
77
Added:
def __repr__(self):
78
Added:
return f"<Product {self.name}>"
79
Added:
80
Added:
81
Added:
class Log(db.Model):
82
Added:
primary_key = db.Column("LogId", db.Integer, primary_key=True)
83
Added:
target = db.Column("Target", db.String, default="False")
84
Added:
nno3 = db.Column("NNO3", db.Float, default=0)
85
Added:
p = db.Column("P", db.Float, default=0)
86
Added:
k = db.Column("K", db.Float, default=0)
87
Added:
ca = db.Column("Ca", db.Float, default=0)
88
Added:
mg = db.Column("Mg", db.Float, default=0)
89
Added:
s = db.Column("S", db.Float, default=0)
90
Added:
na = db.Column("Na", db.Float, default=0)
91
Added:
cl = db.Column("Cl", db.Float, default=0)
92
Added:
fe = db.Column("Fe", db.Float, default=0)
93
Added:
zn = db.Column("Zn", db.Float, default=0)
94
Added:
b = db.Column("B", db.Float, default=0)
95
Added:
mn = db.Column("Mn", db.Float, default=0)
96
Added:
cu = db.Column("Cu", db.Float, default=0)
97
Added:
mo = db.Column("Mo", db.Float, default=0)
98
Added:
si = db.Column("Si", db.Float, default=0)
99
Added:
nnh4 = db.Column("NNH4", db.Float, default=0)
100
Added:
date_time_created = db.Column(
101
Added:
"DateTimeCreated",
102
Added:
db.String,
103
Added:
default=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
104
Added:
)
105
Added:
date_time_updated = db.Column(
106
Added:
"DateTimeUpdated",
107
Added:
db.String,
108
Added:
default=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
109
Added:
)
110
Added:
111
Added:
def __init__(
112
Added:
self, target, nno3, p, k, ca, mg, s, na, cl, fe, zn, b, mn, cu, mo, si, nnh4
113
Added:
):
114
Added:
self.target = target
115
Added:
self.nno3 = nno3
116
Added:
self.p = p
117
Added:
self.k = k
118
Added:
self.ca = ca
119
Added:
self.mg = mg
120
Added:
self.s = s
121
Added:
self.na = na
122
Added:
self.cl = cl
123
Added:
self.fe = fe
124
Added:
self.zn = zn
125
Added:
self.b = b
126
Added:
self.mn = mn
127
Added:
self.cu = cu
128
Added:
self.mo = mo
129
Added:
self.si = si
130
Added:
self.nnh4 = nnh4
131
Added:
self.date_time_created = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
132
Added:
133
Added:
def __repr__(self):
134
Added:
return f"<Log from {self.date_time_created} updated {self.date_time_updated}>"
135
Added:
136
Added:
137
Added:
# Everything after here is garbage
138
Added:
139
Added:
140
Added:
class User(db.Model):
24
141
id = db.Column(db.Integer, primary_key=True)
25
Removed:
name = db.Column(db.String(20), unique=True, nullable=False)
26
Removed:
description = db.Column(db.String(50), nullable=False)
142
Added:
name_first = db.Column(db.String(20), nullable=False)
143
Added:
name_last = db.Column(db.String(20), nullable=False)
144
Added:
email = db.Column(db.String(20), nullable=False)
145
Added:
phone_mobile = db.Column(db.Integer, nullable=False)
146
Added:
phone_alternative = db.Column(db.Integer)
147
Added:
updated = db.Column(db.String)
27
148
28
149
def __repr__(self):
29
Removed:
return f"<Module {self.name}>"
150
Added:
return f"<User {self.name_first} {self.name_last}>"
30
151
31
152
32
Removed:
class Doobie:
33
Removed:
def __init__(self, name, prices, quantity):
34
Removed:
self.name = name
35
Removed:
self.prices = prices
36
Removed:
self.quantity = quantity
153
Added:
class Order(db.Model): # TODO
154
Added:
id = db.Column(db.Integer, primary_key=True)
155
Added:
date = db.Column(db.String(20), nullable=False)
156
Added:
customer = db.Column(db.String(20), nullable=False)
157
Added:
content = db.Column(db.String(10), nullable=False)
158
Added:
updated = db.Column(db.String)
37
159
38
160
def __repr__(self):
39
Removed:
return self.name
161
Added:
return f"<Order {self.name} at {self.updated}>"
app/placeholders.py
@@ -1,7 +0,0 @@
1
Removed:
modules = [
2
Removed:
"catalog",
3
Removed:
"creator",
4
Removed:
"logger",
5
Removed:
"calculator",
6
Removed:
"stock",
7
Removed:
]
app/routes.py
@@ -19,161 +19,26 @@
19
19
20
20
21
21
from flask import Flask, render_template, request, redirect, flash, url_for, jsonify
22
Removed:
from flask_sqlalchemy import SQLAlchemy
23
22
from flask_bootstrap import Bootstrap
24
23
25
Removed:
from flask_wtf import FlaskForm
26
Removed:
from wtforms import (
27
Removed:
SubmitField,
28
Removed:
SelectField,
29
Removed:
RadioField,
30
Removed:
HiddenField,
31
Removed:
StringField,
32
Removed:
IntegerField,
33
Removed:
FloatField,
34
Removed:
)
35
Removed:
from wtforms.validators import InputRequired, Length, Regexp, NumberRange
36
24
from datetime import datetime
25
Added:
import inspect
37
26
38
Removed:
import placeholders as p
27
Added:
from model import *
28
Added:
from forms import *
39
29
40
30
app = Flask(__name__)
41
31
42
Removed:
# Flask-Bootstrap requires this line
43
Removed:
Bootstrap(app)
44
32
33
Added:
app.config.from_pyfile("../config.py")
34
Added:
db.init_app(app)
45
35
46
Removed:
# Flask-WTF encryption key
47
Removed:
app.config["SECRET_KEY"] = "Scooby_Lu,_where_are_you?"
48
36
49
Removed:
# Our database name
50
Removed:
db_name = "fapg.db"
51
Removed:
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + db_name
52
Removed:
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
53
Removed:
db = SQLAlchemy(app)
54
Removed:
55
Removed:
56
Removed:
class Users(db.Model):
57
Removed:
id = db.Column(db.Integer, primary_key=True)
58
Removed:
name_first = db.Column(db.String(20), nullable=False)
59
Removed:
name_last = db.Column(db.String(20), nullable=False)
60
Removed:
email = db.Column(db.String(20), nullable=False)
61
Removed:
phone_mobile = db.Column(db.Integer, nullable=False)
62
Removed:
phone_alternative = db.Column(db.Integer)
63
Removed:
updated = db.Column(db.String)
64
Removed:
65
Removed:
def __init__(
66
Removed:
self, name_first, name_last, email, phone_mobile, phone_alternative, updated
67
Removed:
):
68
Removed:
self.name_first = name_first
69
Removed:
self.name_last = name_last
70
Removed:
self.email = email
71
Removed:
self.phone_mobile = phone_mobile
72
Removed:
self.phone_alternative = phone_alternative
73
Removed:
self.updated = updated
74
Removed:
75
Removed:
def __repr__(self):
76
Removed:
return f"<User {self.name_first} {self.name_last}>"
77
Removed:
78
Removed:
79
Removed:
class Products(db.Model):
80
Removed:
id = db.Column(db.Integer, primary_key=True)
81
Removed:
name = db.Column(db.String(20), nullable=False)
82
Removed:
supplier = db.Column(db.String(20), nullable=False)
83
Removed:
price = db.Column(db.Float(10), nullable=False)
84
Removed:
updated = db.Column(db.String)
85
Removed:
86
Removed:
def __init__(self, name, supplier, price, updated):
87
Removed:
self.name = name
88
Removed:
self.supplier = supplier
89
Removed:
self.price = price
90
Removed:
self.updated = updated
91
Removed:
92
Removed:
def __repr__(self):
93
Removed:
return f"<Product {self.name} by {self.supplier}>"
94
Removed:
95
Removed:
96
Removed:
class Projects(db.Model):
97
Removed:
id = db.Column(db.Integer, primary_key=True)
98
Removed:
name = db.Column(db.String(20), nullable=False)
99
Removed:
name_full = db.Column(db.String(20), nullable=False)
100
Removed:
nickname = db.Column(db.String(20), nullable=False)
101
Removed:
city = db.Column(db.String(20), nullable=False)
102
Removed:
103
Removed:
def __repr__(self):
104
Removed:
return f"<Project {self.name}>"
105
Removed:
106
Removed:
107
Removed:
class Modules(db.Model):
108
Removed:
id = db.Column(db.Integer, primary_key=True)
109
Removed:
name = db.Column(db.String(20), unique=True, nullable=False)
110
Removed:
description = db.Column(db.String(50), nullable=False)
111
Removed:
112
Removed:
def __init__(self, name, description, updated):
113
Removed:
self.name = name
114
Removed:
self.description = description
115
Removed:
self.updated = updated
116
Removed:
117
Removed:
def __repr__(self):
118
Removed:
return f"<Module {self.name}>"
119
Removed:
120
Removed:
121
Removed:
class AddProduct(FlaskForm):
122
Removed:
# id used only by update/edit
123
Removed:
id = HiddenField()
124
Removed:
name = StringField("Product name", validators=[InputRequired()])
125
Removed:
supplier = SelectField(
126
Removed:
"Choose a supplier",
127
Removed:
choices=[
128
Removed:
("", ""),
129
Removed:
("Mister Brown", "Mister Brown"),
130
Removed:
("Madame Cerise", "Madame Cerise"),
131
Removed:
("Biton la Malice", "G. Biton la Malice"),
132
Removed:
("Leroy Merlin", "Leroy Merlin"),
133
Removed:
("other", "Other"),
134
Removed:
],
135
Removed:
)
136
Removed:
price = FloatField("Retail price per unit")
137
Removed:
# updated - date - handled in the route function
138
Removed:
updated = HiddenField()
139
Removed:
submit = SubmitField("Add/Update Product")
140
Removed:
141
Removed:
142
Removed:
# add a new product to the database
143
Removed:
@app.route("/add_product", methods=["GET", "POST"])
144
Removed:
def add_product():
145
Removed:
form = AddProduct()
146
Removed:
if form.validate_on_submit():
147
Removed:
name = request.form["name"]
148
Removed:
supplier = request.form["supplier"]
149
Removed:
price = request.form["price"]
150
Removed:
# get today's date from function, above all the routes
151
Removed:
updated = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
152
Removed:
# the data to be inserted into FAPG model - the table, products
153
Removed:
record = Products(name, supplier, price, updated)
154
Removed:
# Flask-SQLAlchemy magic adds record to database
155
Removed:
db.session.add(record)
156
Removed:
db.session.commit()
157
Removed:
# create a message to send to the template
158
Removed:
message = f"The data for product {name} has been submitted."
159
Removed:
return render_template("add_product.html", message=message)
160
Removed:
else:
161
Removed:
# show validaton errors
162
Removed:
# see https://pythonprogramming.net/flash-flask-tutorial/
163
Removed:
for field, errors in form.errors.items():
164
Removed:
for error in errors:
165
Removed:
flash(
166
Removed:
"Error in {}: {}".format(getattr(form, field).label.text, error),
167
Removed:
"error",
168
Removed:
)
169
Removed:
return render_template("add_product.html", form=form)
170
Removed:
171
Removed:
172
37
@app.route("/")
173
38
@app.route("/fapg/home")
174
39
def project():
175
40
"""This is our project welcome page."""
176
Removed:
michel = Users(
41
Added:
michel = User(
177
42
name_first="Michel",
178
43
name_last="Peter",
179
44
email="le-boss@fapg.com",
@@ -181,35 +46,90 @@
181
46
phone_alternative="0000000000",
182
47
updated="2022-04-21",
183
48
)
184
Removed:
modules = Modules.query.all()
49
Added:
modules = Module.query.all()
185
50
print(module.name for module in modules)
186
Removed:
return render_template("home.html", user=michel, project=fapg, modules=modules)
51
Added:
return render_template("home.html", user=michel, project="fapg", modules=modules)
187
52
188
53
189
Removed:
@app.route("/module/<module>")
54
Added:
@app.route("/modules")
55
Added:
def all_modules():
56
Added:
return redirect("/")
57
Added:
58
Added:
59
Added:
@app.route("/modules/<module>")
190
60
def render_module(module):
191
Removed:
modules = Modules.query.all()
192
Removed:
catalog = Products.query.all()
193
Removed:
user_modules = [module.name for module in modules]
194
Removed:
print(user_modules)
195
Removed:
# If a module was purchased by a user and added to their database,
196
Removed:
# they have access to the corresponding module route.
197
Removed:
if module in user_modules:
198
Removed:
return render_template(
199
Removed:
f"modules/{module}.html",
200
Removed:
modules=modules,
201
Removed:
catalog=catalog,
202
Removed:
)
203
Removed:
else:
61
Added:
modules = Module.query.all()
62
Added:
if module not in [mod.name for mod in modules]:
204
63
return render_template("errors/module-not-found.html", module=module)
64
Added:
customers = Customer.query.order_by(Customer.primary_key.desc())
65
Added:
products = Product.query.order_by(Product.primary_key.desc())
66
Added:
logs = Log.query.order_by(Log.primary_key.desc())
67
Added:
latest_target = (
68
Added:
Log.query.filter_by(target="True").order_by(Log.primary_key.desc()).first()
69
Added:
)
70
Added:
flash(f"Successfully accessed module {module}.", "info")
71
Added:
flash(f"Still fighting against styling in {module}.", "error")
72
Added:
return render_template(
73
Added:
f"modules/{module}.html",
74
Added:
module=module,
75
Added:
modules=modules,
76
Added:
customers=customers,
77
Added:
products=products,
78
Added:
logs=logs,
79
Added:
target=latest_target,
80
Added:
)
205
81
206
82
207
Removed:
# If this file is executed as a script (i.e. double-clicked),
208
Removed:
# the Python interpreter will run the Flask process and begin serving
209
Removed:
# the web pages on the standard localhost address (127.0.0.1).
210
Removed:
# But if this file is called as a module by another Python script, it will not
211
Removed:
# serve content to the web pages, but the function definitions contained in
212
Removed:
# this file will be available to the calling script.
213
Removed:
# E.g. calling script will know what the yes() function is.
214
Removed:
if __name__ == "__main__":
215
Removed:
app.run(debug=True)
83
Added:
@app.route("/delete-<pk>-from-<table>", methods=["POST"])
84
Added:
def delete_item(pk, table):
85
Added:
"""Delete item with Primary Key = pk from corresponding database
86
Added:
table.
87
Added:
"""
88
Added:
model = globals()[table]
89
Added:
record = model.query.filter_by(primary_key=pk).first()
90
Added:
db.session.delete(record)
91
Added:
db.session.commit()
92
Added:
flash(f"Successfully removed item #{pk} from {table} table.", "info")
93
Added:
return redirect("/modules")
94
Added:
95
Added:
96
Added:
@app.route("/add-<item>", methods=["GET", "POST"])
97
Added:
def add_item(item):
98
Added:
"""Add a new item to a corresponding database table.
99
Added:
100
Added:
The item must match a database model class name (table). Then, we
101
Added:
match the model class attributes with request.form values.
102
Added:
103
Added:
"""
104
Added:
if item not in db.metadata.tables.keys():
105
Added:
return render_template("errors/item-not-found.html", item=item)
106
Added:
if request.method == "GET":
107
Added:
form = globals()[f"Add{item.capitalize()}"]()
108
Added:
return render_template("add-item.html", item=item, form=form)
109
Added:
if request.method == "POST":
110
Added:
table = globals()[item.capitalize()]
111
Added:
table_fields = inspect.signature(table).parameters
112
Added:
form_values = [request.form[key] for key in table_fields]
113
Added:
debug = f"Ready to insert {form_values}"
114
Added:
record = table(*form_values)
115
Added:
db.session.add(record)
116
Added:
db.session.commit()
117
Added:
item_pk = table.query.order_by(table.primary_key.desc()).first().primary_key
118
Added:
flash(
119
Added:
f"Successfully added item #{item_pk} to {table.__table__.name.capitalize()} table.",
120
Added:
"info",
121
Added:
)
122
Added:
return redirect(f"/modules")
123
Added:
124
Added:
125
Added:
@app.route("/add-invoice", methods=["GET", "POST"])
126
Added:
def add_invoice():
127
Added:
form = AddInvoice()
128
Added:
if request.method == "GET":
129
Added:
return render_template("add-invoice.html")
130
Added:
131
Added:
132
Added:
@app.route("/preview-invoice", methods=["GET", "POST"])
133
Added:
def preview_invoice():
134
Added:
if request.method == "GET":
135
Added:
return render_template("preview-invoice.html")