Basic app.

Commit
ce73f10a4aaa717de025fd2dc591294fea0db8de
Author
Marius Peter <marius.peter@tutanota.com>
Author date
Committer
Marius Peter <marius.peter@tutanota.com>
Committer date
Changed files
app/database.py
index e69de29b..00000000 100644..000000
app/forms.py
index daa394b8..302db586 100644..100644
@@ -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
index fa4e00a5..1cf59d80 100644..100644
@@ -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
index a2360b41..00000000 100644..000000
@@ -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
index d2bd3f0d..11cd3c2f 100644..100644
@@ -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")