From ce847d9be687cbaee4c7055e1b414c7491153a6c Mon Sep 17 00:00:00 2001 From: flifloo Date: Sat, 1 Feb 2020 16:43:22 +0100 Subject: [PATCH] DB integration part 1 --- app/models.py | 101 ++++++++++++++++++++++++++- app/routes.py | 150 +++++++++++++++++++++++++++------------- app/static/css/main.css | 4 ++ app/static/js/pc.js | 17 +++++ 4 files changed, 222 insertions(+), 50 deletions(-) diff --git a/app/models.py b/app/models.py index ec0484b..4790062 100644 --- a/app/models.py +++ b/app/models.py @@ -1,14 +1,23 @@ +import datetime + +from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash from app import db -from flask_login import UserMixin from app import login class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) + username = db.Column(db.String, index=True, unique=True) password_hash = db.Column(db.String) + firstname = db.Column(db.String, nullable=False) + lastname = db.Column(db.String, nullable=False) + + command = db.relationship("Command", backref="client", lazy="dynamic", foreign_keys="Command.client_id") + pc_command = db.relationship("Command", backref="pc", lazy="dynamic", foreign_keys="Command.pc_id") + sandwitch_command = db.relationship("Command", backref="sandwitch", lazy="dynamic", foreign_keys="Command.sandwitch_id") def set_password(self, password): self.password_hash = generate_password_hash(password) @@ -23,3 +32,93 @@ class User(UserMixin, db.Model): @login.user_loader def load_user(id): return User.query.get(int(id)) + + +class Command(db.Model): + id = db.Column(db.Integer, primary_key=True) + number = db.Column(db.Integer, nullable=False) + + pc_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False) + sandwitch_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False) + client_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False) + + date = db.Column(db.Date, default=datetime.datetime.now().date) + take = db.Column(db.Time, default=datetime.datetime.now().time) + done = db.Column(db.Time) + give = db.Column(db.Time) + error = db.Column(db.Boolean, default=False) + + plate_id = db.Column(db.String, db.ForeignKey("plate.id")) + content = db.relationship("Ingredient", secondary="get") + sauce = db.relationship("Sauce", secondary="cover") + drink_id = db.Column(db.String, db.ForeignKey("drink.id")) + dessert_id = db.Column(db.String, db.ForeignKey("dessert.id")) + + def __repr__(self): + return f"" + + +class Plate(db.Model): + id = db.Column(db.String, primary_key=True) + name = db.Column(db.String, nullable=False) + + command = db.relationship("Command", backref="plate", lazy="dynamic") + + def __repr__(self): + return f"" + + +class Ingredient(db.Model): + id = db.Column(db.String, primary_key=True) + name = db.Column(db.String, nullable=False) + + command = db.relationship("Command", secondary="get") + + def __repr__(self): + return f"" + + +class Get(db.Model): + command_id = db.Column(db.Integer, db.ForeignKey("command.id"), primary_key=True) + ingredient_id = db.Column(db.String, db.ForeignKey("ingredient.id"), primary_key=True) + + command = db.relationship("Command", backref="get") + content = db.relationship("Ingredient", backref="get") + + +class Sauce(db.Model): + id = db.Column(db.String, primary_key=True) + name = db.Column(db.String, nullable=False) + + command = db.relationship("Command", secondary="cover") + + def __repr__(self): + return f"" + + +class Cover(db.Model): + command_id = db.Column(db.Integer, db.ForeignKey("command.id"), primary_key=True) + sauce_id = db.Column(db.String, db.ForeignKey("sauce.id"), primary_key=True) + + command = db.relationship("Command", backref="cover") + sauce = db.relationship("Sauce", backref="cover") + + +class Drink(db.Model): + id = db.Column(db.String, primary_key=True) + name = db.Column(db.String, nullable=False) + + command = db.relationship("Command", backref="drink", lazy="dynamic") + + def __repr__(self): + return f"" + + +class Dessert(db.Model): + id = db.Column(db.String, primary_key=True) + name = db.Column(db.String, nullable=False) + + command = db.relationship("Command", backref="dessert", lazy="dynamic") + + def __repr__(self): + return f"" diff --git a/app/routes.py b/app/routes.py index 5c6b12f..58cd5e9 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,3 +1,4 @@ +import datetime import functools from flask import render_template, redirect, url_for, flash, request @@ -5,9 +6,9 @@ from flask_login import current_user, login_user, logout_user, login_required from flask_socketio import emit, disconnect from werkzeug.urls import url_parse -from app import app, socketio +from app import app, socketio, db from app.forms import LoginForm -from app.models import User +from app.models import User, Command, Plate, Ingredient, Sauce, Drink, Dessert def authenticated_only(f): @@ -68,35 +69,20 @@ def menu(): return render_template("menu.html") -commands = [ - { - "id": 1, - "plate": "sanddwitch", - "content": "Jambon - Tomate - Brie", - "sauce": "curry", - "drink": "Boisson surprise", - "dessert": "Panini nutella", - "state": "waiting" - }, - { - "id": 2, - "plate": "sanddwitch", - "content": "Jambon - Tomate - Brie", - "sauce": "bbc", - "drink": "Boisson surprise", - "dessert": "Panini nutella", - "state": "gave" - }, - { - "id": 3, - "plate": "sanddwitch", - "content": "Jambon - Tomate - Brie", - "sauce": "mayo", - "drink": "Boisson surprise", - "dessert": "Panini nutella", - "state": "error" - } -] +def command_json(c): + content = " - ".join([s.id for s in c.content]) + sauces = " - ".join([s.id for s in c.sauce]) + if c.error: + state = "error" + elif c.give: + state = "gave" + elif c.done: + state = "done" + elif c.take: + state = "waiting" + else: + state = "unknown" + return {"id": c.number, "plate": c.plate_id, "content": content, "sauce": sauces, "drink": c.drink_id, "dessert": c.dessert_id, "state": state} @socketio.on("connect") @@ -109,41 +95,107 @@ def connect(): @socketio.on("list command") @authenticated_only def lscmd(): - emit("list command", {"list": commands, "idcom": len(commands)}) + commands = [] + for c in Command.query.filter_by(date=datetime.datetime.now().date()).all(): + commands.append(command_json(c)) + + emit("list command", {"list": commands}) + # TODO: add auto disable checkbox when no plate selected or specific plate @socketio.on("add command") @authenticated_only def addcmd(json): - commands.append({"id": len(commands)+1, "plate": json["plate"], "content": json["content"], "sauce": json["sauce"], "drink": json["drink"], "dessert": json["dessert"], "state": "waiting"}) - emit("new command", commands[-1], broadcast=True) + c = Command() + try: + c.number = Command.query.filter_by(date=datetime.datetime.now().date()).order_by(Command.number.desc()).first().number+1 + except AttributeError: + c.number = 1 + + if "pc" in json: + try: + c.pc_id = User.query.get(json["pc"]).id + except AttributeError: + c.pc_id = 0 + if "sandwitch" in json: + try: + c.sandwitch_id = User.query.get(json["sandwitch"]).id + except AttributeError: + c.sandwitch_id = 0 + if "client" in json: + try: + c.client_id = User.query.get(json["client"]).id + except AttributeError: + c.client_id = 0 + if "plate" in json: + try: + c.plate_id = Plate.query.get(json["plate"]).id + except AttributeError: + pass + if "content" in json: + for i in json["content"]: + try: + c.content.append(Ingredient.query.get(i)) + except AttributeError: + pass + if "sauce" in json: + for s in json["sauce"]: + try: + c.sauce.append(Sauce.guery.get(s)) + except AttributeError: + pass + if "drink" in json: + try: + c.drink_id = Drink.query.get(json["drink"]).id + except AttributeError: + pass + if "dessert" in json: + try: + c.dessert_id = Dessert.query.get(json["dessert"]).id + except AttributeError: + pass + db.session.add(c) + db.session.commit() + emit("new command", command_json(c), broadcast=True) @socketio.on("clear command") @authenticated_only def rmcmd(json): - for i, c in enumerate(commands): - if c["id"] == json["id"]: - c["state"] = "waiting" - break - emit("cleared command", {"id": json["id"]}, broadcast=True) + c = Command.query.get(json["id"]) + if c: + c.done = None + c.give = None + c.error = False + db.session.commit() + emit("cleared command", {"id": json["id"]}, broadcast=True) + + +@socketio.on("done command") +@authenticated_only +def donecmd(json): + c = Command.query.get(json["id"]) + if c: + c.done = datetime.datetime.now().time() + db.session.commit() + emit("finish command", {"id": json["id"]}, broadcast=True) @socketio.on("give command") @authenticated_only def givecmd(json): - for i, c in enumerate(commands): - if c["id"] == json["id"]: - c["state"] = "gave" - break - emit("gave command", {"id": json["id"]}, broadcast=True) + c = Command.query.get(json["id"]) + if c: + c.give = datetime.datetime.now().time() + db.session.commit() + emit("gave command", {"id": json["id"]}, broadcast=True) @socketio.on("error command") @authenticated_only def errcmd(json): - for i, c in enumerate(commands): - if c["id"] == json["id"]: - c["state"] = "error" - break - emit("glitched command", {"id": json["id"]}, broadcast=True) + c = Command.query.get(json["id"]) + if c: + c.error = True + db.session.commit() + emit("glitched command", {"id": json["id"]}, broadcast=True) diff --git a/app/static/css/main.css b/app/static/css/main.css index 055ebca..047e7d5 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -516,6 +516,10 @@ textarea.input2 + .focus-input2::after { display: none; } +.liste .finis { + background-color: rgb(185, 176, 30); +} + .liste .donnee { background-color: rgb(0, 185, 0); } diff --git a/app/static/js/pc.js b/app/static/js/pc.js index 40885f7..903596c 100644 --- a/app/static/js/pc.js +++ b/app/static/js/pc.js @@ -12,6 +12,9 @@ function addcmd(id, plate, content, sauce, drink, dessert, state) { e.classList.toggle("show-spec"); }); switch (state) { + case "done": + done(e); + break; case "gave": give(e); break; @@ -23,12 +26,18 @@ function addcmd(id, plate, content, sauce, drink, dessert, state) { } function clear(e) { + e.classList.remove('finis'); e.classList.remove('donnee'); e.classList.remove('probleme'); e.classList.remove('show-spec'); list.prepend(e); } +function done(e) { + e.classList.remove('show-spec'); + e.classList.add('finis'); +} + function give(e) { e.classList.remove('show-spec'); e.classList.add('donnee'); @@ -80,6 +89,10 @@ socket.on("cleared command", function (data) { clear(document.querySelector(`.liste #cmd${data.id}`)); }); +socket.on("finish command", function (data) { + done(document.querySelector(`.liste #cmd${data.id}`)); +}); + socket.on("gave command", function (data) { give(document.querySelector(`.liste #cmd${data.id}`)); }); @@ -189,6 +202,10 @@ document.querySelectorAll("input[name=dessert]").forEach( function (e) { document.querySelector('.validation').addEventListener('click', ev => { ev.stopPropagation(); + current["pc"] = 1; + current["sandwitch"] = 1; + current["client"] = 1; + socket.emit("add command", current); current = {"plate": null, "content": [], "sauce": [], "drink": null, "dessert": null}; document.querySelectorAll("input").forEach( e => {