diff options
Diffstat (limited to 'app/modules')
-rw-r--r-- | app/modules/__init__.py | 8 | ||||
-rw-r--r-- | app/modules/auth/forms.py | 29 | ||||
-rw-r--r-- | app/modules/auth/routes.py | 73 | ||||
-rw-r--r-- | app/modules/common.py | 75 | ||||
-rw-r--r-- | app/modules/customers/forms.py | 36 | ||||
-rw-r--r-- | app/modules/customers/routes.py | 38 | ||||
-rw-r--r-- | app/modules/ferti/forms.py | 47 | ||||
-rw-r--r-- | app/modules/ferti/routes.py | 46 | ||||
-rw-r--r-- | app/modules/forms.py | 6 | ||||
-rw-r--r-- | app/modules/forms.py.bkp | 118 | ||||
-rw-r--r-- | app/modules/invoices/forms.py | 33 | ||||
-rw-r--r-- | app/modules/invoices/routes.py | 47 | ||||
-rw-r--r-- | app/modules/modules.py.bkp | 136 | ||||
-rw-r--r-- | app/modules/orders/forms.py | 35 | ||||
-rw-r--r-- | app/modules/orders/routes.py | 30 | ||||
-rw-r--r-- | app/modules/products/forms.py | 23 | ||||
-rw-r--r-- | app/modules/products/routes.py | 26 |
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, + ) |