summaryrefslogtreecommitdiff
path: root/app/modules
diff options
context:
space:
mode:
authorMarius Peter <marius.peter@tutanota.com>2022-05-15 13:17:35 +0200
committerMarius Peter <marius.peter@tutanota.com>2022-05-15 13:17:35 +0200
commite084f90c19e779592f6e3f14eb8f70a7287f0dad (patch)
tree1215177356105452c39a916fd050f79c9721f523 /app/modules
parent1dad22d3e45d6506c8624e3a7111240fcc4ab786 (diff)
Modularization.
Diffstat (limited to 'app/modules')
-rw-r--r--app/modules/__init__.py8
-rw-r--r--app/modules/auth/forms.py29
-rw-r--r--app/modules/auth/routes.py73
-rw-r--r--app/modules/common.py75
-rw-r--r--app/modules/customers/forms.py36
-rw-r--r--app/modules/customers/routes.py38
-rw-r--r--app/modules/ferti/forms.py47
-rw-r--r--app/modules/ferti/routes.py46
-rw-r--r--app/modules/forms.py6
-rw-r--r--app/modules/forms.py.bkp118
-rw-r--r--app/modules/invoices/forms.py33
-rw-r--r--app/modules/invoices/routes.py47
-rw-r--r--app/modules/modules.py.bkp136
-rw-r--r--app/modules/orders/forms.py35
-rw-r--r--app/modules/orders/routes.py30
-rw-r--r--app/modules/products/forms.py23
-rw-r--r--app/modules/products/routes.py26
17 files changed, 806 insertions, 0 deletions
diff --git a/app/modules/__init__.py b/app/modules/__init__.py
new file mode 100644
index 0000000..56f1d5a
--- /dev/null
+++ b/app/modules/__init__.py
@@ -0,0 +1,8 @@
+# -*- mode: python; -*-
+
+from .common import common
+from .auth.routes import auth
+from .products.routes import products
+from .customers.routes import customers
+from .ferti.routes import ferti
+from .invoices.routes import invoices
diff --git a/app/modules/auth/forms.py b/app/modules/auth/forms.py
new file mode 100644
index 0000000..c051133
--- /dev/null
+++ b/app/modules/auth/forms.py
@@ -0,0 +1,29 @@
+from flask_wtf import FlaskForm
+from wtforms import (
+ SubmitField,
+ SelectField,
+ HiddenField,
+ StringField,
+ PasswordField,
+ IntegerField,
+ FloatField,
+ BooleanField,
+ DateTimeField,
+)
+from wtforms.validators import InputRequired, Length, NumberRange
+
+
+class LoginForm(FlaskForm):
+ username = StringField("Username", validators=[InputRequired()])
+ password = PasswordField("Password", validators=[InputRequired()])
+ remember = BooleanField("Remember")
+ submit = SubmitField("Login")
+
+
+class RegisterForm(LoginForm):
+ name_first = StringField("First name")
+ name_last = StringField("Last name")
+ email = StringField("E-mail address")
+ phone_mobile = StringField("Phone number (mobile)")
+ phone_alternative = StringField("Phone number (alternative)")
+ submit = SubmitField("Register")
diff --git a/app/modules/auth/routes.py b/app/modules/auth/routes.py
new file mode 100644
index 0000000..dd9e396
--- /dev/null
+++ b/app/modules/auth/routes.py
@@ -0,0 +1,73 @@
+# -*- mode: python; -*-
+
+from flask import Blueprint, render_template, redirect, url_for, request, flash
+from flask_login import login_user, login_required, logout_user
+from werkzeug.security import generate_password_hash, check_password_hash
+
+from ... import db
+from ...models import User
+from .forms import LoginForm, RegisterForm
+
+
+auth = Blueprint("auth", __name__)
+
+
+@auth.route("/login", methods=["GET", "POST"])
+def login():
+ form = LoginForm()
+ if form.validate_on_submit():
+ req = request.form
+ # print(req["remember"])
+ remember = True if req.get("remember") else False
+ user = User.query.filter_by(username=req["username"]).first()
+ if user is None:
+ flash("User not registered.", "error")
+ return redirect(url_for("auth.register"))
+ if check_password_hash(user.hashed_password, req["password"]) is False:
+ flash("Wrong password.", "error")
+ return redirect(url_for("auth.login"))
+ login_user(user, remember=remember)
+ flash(
+ f"Logged in as user {user.username} successfully. "
+ + f"You will {'not' if remember is False else ''} be remembered next time!"
+ )
+ return redirect(url_for("main.home"))
+ return render_template("modules/login.html", form=form)
+
+
+@auth.route("/register", methods=["GET", "POST"])
+def register():
+ form = RegisterForm()
+ if form.validate_on_submit():
+ req = request.form
+ user_already_exists = User.query.filter_by(
+ name_first=req["name_first"],
+ name_last=req["name_last"],
+ ).first()
+ if user_already_exists:
+ flash(
+ f"User {req['name_first']} {req['name_last']} already exists.", "error"
+ )
+ return redirect(url_for("auth.login"))
+ new_user = User(
+ username=req["username"],
+ hashed_password=generate_password_hash(req["password"], method="sha256"),
+ name_first=req["name_first"],
+ name_last=req["name_last"],
+ email=req["email"],
+ phone_mobile=req["phone_mobile"],
+ phone_alternative=req["phone_alternative"],
+ )
+ db.session.add(new_user)
+ db.session.commit()
+ flash(f"Created user {req['name_first']} {req['name_last']} successfully.")
+ return redirect(url_for("main.home"))
+ return render_template("register.html", form=form)
+
+
+@auth.route("/logout")
+@login_required
+def logout():
+ logout_user()
+ flash(f"Logged out successfully.")
+ return redirect(url_for("main.home"))
diff --git a/app/modules/common.py b/app/modules/common.py
new file mode 100644
index 0000000..9e96f41
--- /dev/null
+++ b/app/modules/common.py
@@ -0,0 +1,75 @@
+# -*- mode: python; -*-
+
+import inspect
+from flask import Blueprint, request, render_template, redirect, flash, jsonify
+from flask_login import login_required, current_user
+
+from .. import db
+from .. import models
+from . import forms
+
+from wtforms import SelectField
+
+
+common = Blueprint("common", __name__)
+
+
+@common.route("/modules/<module>/add/<table>", methods=["GET", "POST"])
+@login_required
+def add_item(module, table):
+ """Add new item to table accessible via module."""
+ # print("db table keys are", db.metadata.tables.keys())
+ if table not in db.metadata.tables.keys():
+ return render_template("errors/item-not-found.html", table=table)
+ form = getattr(forms, f"Add{table}")()
+ if form.validate_on_submit():
+ model = getattr(models, table)
+ table_fields = inspect.signature(model).parameters
+ form_values = {key: request.form[key] for key in table_fields}
+ print(f"Ready to insert {form_values}")
+ record = model(**form_values)
+ db.session.add(record)
+ db.session.commit()
+ item_pk = model.query.order_by(model.primary_key.desc()).first().primary_key
+ flash(f"Successfully added item #{item_pk} to {table} table.", "info")
+ return redirect(f"/modules/{module}")
+ return render_template("modules/add-item.html", table=table, form=form)
+
+
+@common.route("/modules/<module>/edit/<table>/<int:pk>", methods=["GET", "POST"])
+@login_required
+def edit_item(module, table, pk):
+ """Edit existing item in table accessible via module."""
+ if table not in db.metadata.tables.keys():
+ return render_template("errors/item-not-found.html", table=table)
+ model = getattr(models, table)
+ item = model.query.filter_by(primary_key=pk).first()
+ # Instantiate form with selected item's field values.
+ form = getattr(forms, f"Add{table}")(**item.__dict__)
+ if form.validate_on_submit():
+ table_fields = inspect.signature(model).parameters
+ form_values = {key: request.form[key] for key in table_fields}
+ print(f"Ready to update {form_values}")
+ model.query.filter_by(primary_key=pk).update(form_values)
+ db.session.commit()
+ flash(f"Successfully edited item #{pk} in {table} table.", "info")
+ return redirect(f"/modules/{module}")
+ return render_template("modules/edit-item.html", table=table, pk=pk, form=form)
+
+
+@common.route("/modules/<module>/delete/<table>/<int:pk>", methods=["POST"])
+@login_required
+def delete_item(module, table, pk):
+ """Delete item with Primary Key = pk from table in module."""
+ model = getattr(models, table)
+ record = model.query.filter_by(primary_key=pk).first()
+ db.session.delete(record)
+ db.session.commit()
+ flash(f"Successfully removed item #{pk} from {table} table.", "info")
+ return redirect(f"/modules/{module}")
+
+
+@common.route("/modules/settings")
+@login_required
+def settings():
+ return render_template("modules/settings.html", user=current_user)
diff --git a/app/modules/customers/forms.py b/app/modules/customers/forms.py
new file mode 100644
index 0000000..2c5bcaa
--- /dev/null
+++ b/app/modules/customers/forms.py
@@ -0,0 +1,36 @@
+# -*- mode: python; -*-
+
+
+from flask_wtf import FlaskForm
+from wtforms import (
+ SubmitField,
+ SelectField,
+ HiddenField,
+ StringField,
+ PasswordField,
+ IntegerField,
+ FloatField,
+ BooleanField,
+ DateTimeField,
+)
+from wtforms.validators import InputRequired, Length, NumberRange
+
+
+class AddCustomer(FlaskForm):
+ name = StringField("Customer name", validators=[InputRequired()])
+ name_alternative = StringField("Alternative name")
+ # date_time_created = DateTimeField("Creation date")
+ code_customer = StringField("Customer code")
+ code_accounting = StringField("Accounting code")
+ address = StringField("Address")
+ postal_code = StringField("Postal Code")
+ city = StringField("City")
+ country = StringField("Country")
+ phone = StringField("Phone")
+ website = StringField("Website")
+ email = StringField("E-mail")
+ professional_id_1 = StringField("Professional ID 1")
+ professional_id_2 = StringField("Professional ID 2")
+ tax_id = StringField("Tax ID")
+ payment_terms = StringField("Payment Terms", default="Tu vas payer sale chien!")
+ submit = SubmitField("Add/Update Product")
diff --git a/app/modules/customers/routes.py b/app/modules/customers/routes.py
new file mode 100644
index 0000000..c8ae072
--- /dev/null
+++ b/app/modules/customers/routes.py
@@ -0,0 +1,38 @@
+# -*- mode: python; -*-
+
+
+from flask import (
+ Blueprint,
+ render_template,
+ send_file,
+ request,
+ redirect,
+ flash,
+ url_for,
+ jsonify,
+ abort,
+)
+from flask_login import login_required, current_user
+import inspect
+
+
+from ... import db
+from ...models import *
+from .forms import *
+
+customers = Blueprint("customers", __name__)
+
+
+@customers.route("/modules/customers")
+@login_required
+def view():
+ modules = Module.query.all()
+ cust = Customer.query.order_by(Customer.primary_key.desc())
+ module = "customers"
+ flash(f"Successfully accessed module {module}.", "info")
+ flash(f"Still fighting against styling in {module}.", "error")
+ return render_template(
+ f"modules/{module}.html",
+ modules=modules,
+ customers=cust,
+ )
diff --git a/app/modules/ferti/forms.py b/app/modules/ferti/forms.py
new file mode 100644
index 0000000..d926931
--- /dev/null
+++ b/app/modules/ferti/forms.py
@@ -0,0 +1,47 @@
+from flask_wtf import FlaskForm
+from wtforms import (
+ SubmitField,
+ SelectField,
+ HiddenField,
+ StringField,
+ PasswordField,
+ IntegerField,
+ FloatField,
+ BooleanField,
+ DateTimeField,
+)
+from wtforms.validators import InputRequired, Length, NumberRange
+
+
+class AddFertiLog(FlaskForm):
+ target = SelectField(
+ "Type",
+ choices=[("False", "Log"), ("True", "Target")],
+ validators=[InputRequired()],
+ )
+ nno3 = FloatField("NNO3", default=0)
+ p = FloatField("P", default=0)
+ k = FloatField("K", default=0)
+ ca = FloatField("Ca", default=0)
+ mg = FloatField("Mg", default=0)
+ s = FloatField("S", default=0)
+ na = FloatField("Na", default=0)
+ cl = FloatField("Cl", default=0)
+ fe = FloatField("Fe", default=0)
+ zn = FloatField("Zn", default=0)
+ b = FloatField("B", default=0)
+ mn = FloatField("Mn", default=0)
+ cu = FloatField("Cu", default=0)
+ mo = FloatField("Mo", default=0)
+ si = FloatField("Si", default=0)
+ nnh4 = FloatField("NNH4", default=0)
+ submit = SubmitField("Add/Update Log")
+
+
+class AddFertiTarget(AddFertiLog):
+ targeted_log = SelectField(
+ "Log to target",
+ choices=[("value1", "Last"), ("value2", "Named")],
+ validators=[InputRequired()],
+ )
+ submit = SubmitField("Add/Update Log")
diff --git a/app/modules/ferti/routes.py b/app/modules/ferti/routes.py
new file mode 100644
index 0000000..b3bb03f
--- /dev/null
+++ b/app/modules/ferti/routes.py
@@ -0,0 +1,46 @@
+# -*- mode: python; -*-
+
+
+from flask import (
+ Blueprint,
+ render_template,
+ send_file,
+ request,
+ redirect,
+ flash,
+ url_for,
+ jsonify,
+ abort,
+)
+from flask_login import login_required, current_user
+
+
+# from datetime import datetime
+import inspect
+
+
+
+
+from ... import db
+from ...models import *
+from .forms import *
+
+
+ferti = Blueprint("ferti", __name__)
+
+
+
+@ferti.route("/modules/ferti")
+@login_required
+def view():
+ modules = Module.query.all()
+ logs = Fertilog.query.order_by(Fertilog.primary_key.desc()).all()
+ targets = Fertitarget.query.all()
+ module = "ferti"
+ flash(f"Latest target is {targets}.", "info")
+ flash(f"Still fighting against styling in {module}.", "error")
+ return render_template(
+ f"modules/{module}.html",
+ modules=modules,
+ logs=logs,
+ )
diff --git a/app/modules/forms.py b/app/modules/forms.py
new file mode 100644
index 0000000..f98995d
--- /dev/null
+++ b/app/modules/forms.py
@@ -0,0 +1,6 @@
+# -*- mode: python; -*-
+
+from .customers.forms import AddCustomer
+from .ferti.forms import AddFertiLog, AddFertiTarget
+from .invoices.forms import AddInvoice
+from .products.forms import AddProduct
diff --git a/app/modules/forms.py.bkp b/app/modules/forms.py.bkp
new file mode 100644
index 0000000..f0f6bfb
--- /dev/null
+++ b/app/modules/forms.py.bkp
@@ -0,0 +1,118 @@
+# -*- mode: python; -*-
+
+from flask_wtf import FlaskForm
+from wtforms import (
+ SubmitField,
+ SelectField,
+ HiddenField,
+ StringField,
+ PasswordField,
+ IntegerField,
+ FloatField,
+ BooleanField,
+ DateTimeField,
+)
+from wtforms.validators import InputRequired, Length, NumberRange
+
+
+class LoginForm(FlaskForm):
+ username = StringField("Username", validators=[InputRequired()])
+ password = PasswordField("Password", validators=[InputRequired()])
+ remember = BooleanField("Remember")
+ submit = SubmitField("Login")
+
+
+class RegisterForm(LoginForm):
+ name_first = StringField("First name")
+ name_last = StringField("Last name")
+ email = StringField("E-mail address")
+ phone_mobile = StringField("Phone number (mobile)")
+ phone_alternative = StringField("Phone number (alternative)")
+ submit = SubmitField("Register")
+
+
+class AddCustomer(FlaskForm):
+ name = StringField("Customer name", validators=[InputRequired()])
+ name_alternative = StringField("Alternative name")
+ # date_time_created = DateTimeField("Creation date")
+ code_customer = StringField("Customer code")
+ code_accounting = StringField("Accounting code")
+ address = StringField("Address")
+ postal_code = StringField("Postal Code")
+ city = StringField("City")
+ country = StringField("Country")
+ phone = StringField("Phone")
+ website = StringField("Website")
+ email = StringField("E-mail")
+ professional_id_1 = StringField("Professional ID 1")
+ professional_id_2 = StringField("Professional ID 2")
+ tax_id = StringField("Tax ID")
+ payment_terms = StringField("Payment Terms", default="Tu vas payer sale chien!")
+ submit = SubmitField("Add/Update Product")
+
+
+class AddProduct(FlaskForm):
+ name = StringField("Product name", validators=[InputRequired()])
+ code_accounting = StringField("Accounting code", default=0)
+ unit_weight = FloatField("Unit weight", default=0)
+ price_net = FloatField("Price (net)", default=0)
+ price_gross = FloatField("Price (gross)", default=0)
+ tax_rate = FloatField("Tax rate", default=0)
+ submit = SubmitField("Add/Update Product")
+
+
+class AddFertilog(FlaskForm):
+ target = SelectField(
+ "Type",
+ choices=[("False", "Log"), ("True", "Target")],
+ validators=[InputRequired()],
+ )
+ nno3 = FloatField("NNO3", default=0)
+ p = FloatField("P", default=0)
+ k = FloatField("K", default=0)
+ ca = FloatField("Ca", default=0)
+ mg = FloatField("Mg", default=0)
+ s = FloatField("S", default=0)
+ na = FloatField("Na", default=0)
+ cl = FloatField("Cl", default=0)
+ fe = FloatField("Fe", default=0)
+ zn = FloatField("Zn", default=0)
+ b = FloatField("B", default=0)
+ mn = FloatField("Mn", default=0)
+ cu = FloatField("Cu", default=0)
+ mo = FloatField("Mo", default=0)
+ si = FloatField("Si", default=0)
+ nnh4 = FloatField("NNH4", default=0)
+ submit = SubmitField("Add/Update Log")
+
+
+class AddFertitarget(AddFertilog):
+ targeted_log = SelectField(
+ "Log to target",
+ choices=[("value1", "Last"), ("value2", "Named")],
+ validators=[InputRequired()],
+ )
+ submit = SubmitField("Add/Update Log")
+
+
+
+class AddOrder(FlaskForm): # TODO
+ name = StringField("Product name", validators=[InputRequired()])
+ code_accounting = StringField("Accounting code", default=0)
+ unit_weight = FloatField("Unit weight", default=0)
+ price_net = FloatField("Price (net)", default=0)
+ price_gross = FloatField("Price (gross)", default=0)
+ tax_rate = FloatField("Tax rate", default=0)
+ submit = SubmitField("Add/Update Product")
+
+
+class AddInvoice(FlaskForm):
+ invoice_id_alt = StringField("Alternative invoice ID")
+ customer_id = StringField("Customer ID")
+ customer_reference = StringField("Customer reference")
+ date_billed = StringField("Date billed")
+ date_due = StringField("Date due")
+ amount_net = FloatField("Amount without tax", default=0)
+ amount_gross = FloatField("Amount with tax", default=0)
+ amount_tax = FloatField("Amount of tax", default=0)
+ submit = SubmitField("Add new Invoice")
diff --git a/app/modules/invoices/forms.py b/app/modules/invoices/forms.py
new file mode 100644
index 0000000..8ef7bd0
--- /dev/null
+++ b/app/modules/invoices/forms.py
@@ -0,0 +1,33 @@
+from flask_wtf import FlaskForm
+from wtforms import (
+ SubmitField,
+ SelectField,
+ HiddenField,
+ StringField,
+ PasswordField,
+ IntegerField,
+ FloatField,
+ BooleanField,
+ DateTimeField,
+)
+from wtforms.validators import InputRequired, Length, NumberRange
+
+from ...models import Customer
+
+
+class AddInvoice(FlaskForm):
+ customer_id = SelectField("Customer", choices=[])
+ invoice_id_alt = StringField("Alternative invoice ID")
+ customer_reference = StringField("Customer reference")
+ date_billed = StringField("Date billed")
+ date_due = StringField("Date due")
+ amount_net = FloatField("Amount without tax", default=0)
+ amount_gross = FloatField("Amount with tax", default=0)
+ amount_tax = FloatField("Amount of tax", default=0)
+ submit = SubmitField("Add new Invoice")
+
+ def __init__(self, **kwargs):
+ super().__init__()
+ self.customer_id.choices = [
+ (cus.primary_key, cus.name) for cus in Customer.query.all()
+ ]
diff --git a/app/modules/invoices/routes.py b/app/modules/invoices/routes.py
new file mode 100644
index 0000000..b8a0a68
--- /dev/null
+++ b/app/modules/invoices/routes.py
@@ -0,0 +1,47 @@
+# -*- mode: python; -*-
+
+
+from flask import (
+ Blueprint,
+ render_template,
+ send_file,
+ request,
+ redirect,
+ flash,
+ url_for,
+ jsonify,
+ abort,
+)
+from flask_login import login_required, current_user
+
+
+from ... import db
+from ...models import *
+from .forms import *
+
+
+invoices = Blueprint("invoices", __name__)
+
+
+
+@invoices.route("/modules/invoices")
+@login_required
+def view():
+ modules = Module.query.all()
+ page = request.args.get('page', 1, type=int)
+ invoices = Invoice.query.order_by(Invoice.primary_key.desc()).paginate(page=page, per_page=5)
+ module = "invoices"
+ flash(f"Successfully accessed module {module}.", "info")
+ flash(f"Still fighting against styling in {module}.", "error")
+ return render_template(
+ f"modules/{module}.html",
+ modules=modules,
+ invoices=invoices,
+ )
+
+
+@invoices.route("/modules/invoices/preview/<int:pk>")
+@login_required
+def preview(pk):
+ invoice = Invoice.query.filter_by(primary_key=pk).first()
+ return render_template("modules/invoice-preview.html", invoice=invoice)
diff --git a/app/modules/modules.py.bkp b/app/modules/modules.py.bkp
new file mode 100644
index 0000000..b962a0f
--- /dev/null
+++ b/app/modules/modules.py.bkp
@@ -0,0 +1,136 @@
+# -*- mode: python; -*-
+
+
+from flask import (
+ Blueprint,
+ render_template,
+ send_file,
+ request,
+ redirect,
+ flash,
+ url_for,
+ jsonify,
+ abort,
+)
+from flask_login import login_required, current_user
+
+
+# from datetime import datetime
+import inspect
+
+from . import db
+
+modules = Blueprint("modules", __name__)
+
+
+from .models import *
+from .forms import *
+
+
+@modules.route("/modules")
+def modules_home():
+ return redirect("/index")
+
+
+@modules.route("/add-<item>", methods=["GET", "POST"])
+@login_required
+def add_item(item):
+ """Add a new item to a corresponding database table.
+
+ The item must match a database model class name (table). Then, we
+ match the model class attributes with request.form values.
+
+ """
+ print("db table keys are", db.metadata.tables.keys())
+ if item.capitalize() not in db.metadata.tables.keys():
+ return render_template("errors/item-not-found.html", item=item)
+ if request.method == "GET":
+ form = globals()[f"Add{item.capitalize()}"]()
+ return render_template("add-item.html", item=item, form=form)
+ if request.method == "POST":
+ table = globals()[item.capitalize()]
+ table_fields = inspect.signature(table).parameters
+ form_values = {key: request.form[key] for key in table_fields}
+ print(f"Ready to insert {form_values}")
+ record = table(**form_values)
+ db.session.add(record)
+ db.session.commit()
+ item_pk = table.query.order_by(table.primary_key.desc()).first().primary_key
+ flash(
+ f"Successfully added item #{item_pk} to {table.__table__.name.capitalize()} table.",
+ "info",
+ )
+ return redirect("/modules")
+
+
+@modules.route("/delete-<pk>-from-<table>", methods=["POST"])
+@login_required
+def delete_item(pk, table):
+ """Delete item with Primary Key = pk from corresponding database
+ table.
+ """
+ model = globals()[table]
+ record = model.query.filter_by(primary_key=pk).first()
+ db.session.delete(record)
+ db.session.commit()
+ flash(f"Successfully removed item #{pk} from {table} table.", "info")
+ return redirect("/modules")
+
+
+@modules.route("/modules/customers")
+@login_required
+def customers():
+ modules = Module.query.all()
+ customers = Customer.query.order_by(Customer.primary_key.desc())
+ module = "customers"
+ flash(f"Successfully accessed module {module}.", "info")
+ flash(f"Still fighting against styling in {module}.", "error")
+ return render_template(
+ f"modules/{module}.html",
+ modules=modules,
+ customers=customers,
+ )
+
+
+@modules.route("/modules/products")
+@login_required
+def products():
+ modules = Module.query.all()
+ products = Product.query.order_by(Product.primary_key.desc())
+ module = "products"
+ flash(f"Successfully accessed module {module}.", "info")
+ flash(f"Still fighting against styling in {module}.", "error")
+ return render_template(
+ f"modules/{module}.html",
+ modules=modules,
+ products=products,
+ )
+
+
+@modules.route("/modules/ferti")
+@login_required
+def ferti():
+ modules = Module.query.all()
+ logs = Fertilog.query.order_by(Fertilog.primary_key.desc()).all()
+ targets = Fertitarget.query.all()
+ module = "ferti"
+ flash(f"Latest target is {targets}.", "info")
+ flash(f"Still fighting against styling in {module}.", "error")
+ return render_template(
+ f"modules/{module}.html",
+ modules=modules,
+ logs=logs,
+ )
+
+
+# @main.route("/add-invoice", methods=["GET", "POST"])
+# def add_invoice():
+# form = AddInvoice()
+# if request.method == "GET":
+# return render_template("add-invoice.html")
+
+
+# @main.route("/preview-invoice", methods=["GET", "POST"])
+# def preview_invoice():
+# if request.method == "GET":
+# return render_template("preview-invoice.html")
diff --git a/app/modules/orders/forms.py b/app/modules/orders/forms.py
new file mode 100644
index 0000000..66ab47b
--- /dev/null
+++ b/app/modules/orders/forms.py
@@ -0,0 +1,35 @@
+from flask_wtf import FlaskForm
+from wtforms import (
+ SubmitField,
+ SelectField,
+ HiddenField,
+ StringField,
+ PasswordField,
+ IntegerField,
+ FloatField,
+ BooleanField,
+ DateTimeField,
+)
+from wtforms.validators import InputRequired, Length, NumberRange
+
+
+class AddOrder(FlaskForm): # TODO
+ name = StringField("Product name", validators=[InputRequired()])
+ code_accounting = StringField("Accounting code", default=0)
+ unit_weight = FloatField("Unit weight", default=0)
+ price_net = FloatField("Price (net)", default=0)
+ price_gross = FloatField("Price (gross)", default=0)
+ tax_rate = FloatField("Tax rate", default=0)
+ submit = SubmitField("Add/Update Product")
+
+
+class AddInvoice(FlaskForm):
+ invoice_id_alt = StringField("Alternative invoice ID")
+ customer_id = StringField("Customer ID")
+ customer_reference = StringField("Customer reference")
+ date_billed = StringField("Date billed")
+ date_due = StringField("Date due")
+ amount_net = FloatField("Amount without tax", default=0)
+ amount_gross = FloatField("Amount with tax", default=0)
+ amount_tax = FloatField("Amount of tax", default=0)
+ submit = SubmitField("Add new Invoice")
diff --git a/app/modules/orders/routes.py b/app/modules/orders/routes.py
new file mode 100644
index 0000000..4027a44
--- /dev/null
+++ b/app/modules/orders/routes.py
@@ -0,0 +1,30 @@
+# -*- mode: python; -*-
+
+
+from flask import (
+ Blueprint,
+ render_template,
+ send_file,
+ request,
+ redirect,
+ flash,
+ url_for,
+ jsonify,
+ abort,
+)
+from flask_login import login_required, current_user
+
+
+# from datetime import datetime
+import inspect
+
+
+
+from ... import db
+from ...models import *
+from .forms import *
+
+
+orders = Blueprint("orders", __name__)
+
+
diff --git a/app/modules/products/forms.py b/app/modules/products/forms.py
new file mode 100644
index 0000000..f00441f
--- /dev/null
+++ b/app/modules/products/forms.py
@@ -0,0 +1,23 @@
+from flask_wtf import FlaskForm
+from wtforms import (
+ SubmitField,
+ SelectField,
+ HiddenField,
+ StringField,
+ PasswordField,
+ IntegerField,
+ FloatField,
+ BooleanField,
+ DateTimeField,
+)
+from wtforms.validators import InputRequired, Length, NumberRange
+
+
+class AddProduct(FlaskForm):
+ name = StringField("Product name", validators=[InputRequired()])
+ code_accounting = StringField("Accounting code", default=0)
+ unit_weight = FloatField("Unit weight", default=0)
+ price_net = FloatField("Price (net)", default=0)
+ price_gross = FloatField("Price (gross)", default=0)
+ tax_rate = FloatField("Tax rate", default=0)
+ submit = SubmitField("Add/Update Product")
diff --git a/app/modules/products/routes.py b/app/modules/products/routes.py
new file mode 100644
index 0000000..735fef9
--- /dev/null
+++ b/app/modules/products/routes.py
@@ -0,0 +1,26 @@
+# -*- mode: python; -*-
+
+
+from flask import Blueprint, render_template, request, redirect, flash
+from flask_login import login_required
+
+from ... import db
+from ...models import Module, Product
+from .forms import *
+
+products = Blueprint("products", __name__)
+
+
+@products.route("/modules/products")
+@login_required
+def list():
+ modules = Module.query.all()
+ prods = Product.query.order_by(Product.primary_key.desc())
+ module = "products"
+ flash(f"Successfully accessed module {module}.", "info")
+ flash(f"Still fighting against styling in {module}.", "error")
+ return render_template(
+ f"modules/{module}.html",
+ modules=modules,
+ products=prods,
+ )
Copyright 2019--2024 Marius PETER