def messageFunction():

    if request.method == "POST":

        # Get variables for email to send to Glenn
        subject1 = "Message from " + getUserName()
        html = request.form.get("ckeditor")
        text = html2text.html2text(html)
        body1 = "Username: "******"\nEmail: " + getUserEmail(
        ) + "\n\nMessage: " + text
        email1 = os.environ["EMAIL_SEND"]

        # Send email to Glenn
        sendMail(subject1, email1, body1)

        # Get variables for email to send to user
        subject2 = "Copy of your message"
        body2 = "You wrote: " + text
        email2 = getUserEmail()

        # Send copy to user
        sendMail(subject2, email2, body2)

        flash("Message sent", "success")
        return redirect("/")

    else:

        return render_template("message.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole())
Beispiel #2
0
def addNewsFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Get variable
        title = request.form.get("title")
        body = request.form.get("ckeditor")

        # Insert title and body into the table
        db.session.add(News(title=title, body=body))
        db.session.commit()

        # Flash result & redirect
        flash("News created", "success")
        return redirect("/communication")

    else:

        return render_template("addNews.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole())
Beispiel #3
0
def historyFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # Get variable
    user_id = session["user_id"]

    # Query database for orders
    orders = Orders.query.filter_by(user_id=user_id).all()

    # Make array of arrays of plants in Orders
    plants = []
    for order in orders:
        plants.extend([eval(order.plants)])

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        print("History")

    else:

        return render_template("history.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole(),
                               zip=zip(orders, plants))
def editNewsFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Get variable
        news_id = request.form.get("news_id")
        title = request.form.get("title")
        html = request.form.get("ckeditor")
        body = html2text.html2text(html)

        # Update plant name, stock, price, description and show status into the table
        query = News.query.filter_by(id=news_id).first()
        query.title = title
        query.body = body
        db.session.commit()

        # Flash result & redirect
        flash("News edited", "success")
        return redirect("/communication")

    else:

        # Get arguments from url_for in administration
        thisNews = request.args.getlist("news")

        return render_template("editNews.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole(),
                               news=thisNews)
def emailFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Get variable
        user_id = session["user_id"]

        # Delete row in DB
        Users.query.filter_by(id=user_id).delete()
        db.session.commit()

        # Clear session
        session.clear()

        # Flash result & redirect
        flash("Account deleted", "warning")
        return redirect("/signin")

    else:

        return render_template("delete.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole())
def communicationFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # Query database for news to display them
    news = News.query.all()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        if "erase" in request.form:

            # Loop through the record list to match plant ID when delete button is pressed
            index = 0
            while index < len(news):

                if int(request.form["erase"]) == int(news[index].id):

                    # Query database for plant id to delete row
                    News.query.filter(News.id == news[index].id).delete()
                    db.session.commit()

                    # Flash result & redirect
                    flash("News deleted", "success")
                    return redirect("/communication")

                else:

                    index += 1

        if "change" in request.form:

            # Loop through the record list to match plant ID when edit button is pressed
            index = 0
            while index < len(news):

                if int(request.form["change"]) == int(news[index].id):

                    # Create a list with values of DB and append them
                    thisNews = []
                    thisNews.extend(
                        [news[index].id, news[index].title, news[index].body])

                    return redirect(
                        url_for("change.changeFunction", news=thisNews))

                else:

                    index += 1

    else:

        return render_template("communication.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole(),
                               news=news)
Beispiel #7
0
def aboutFunction():

    if request.method == "POST":

        print("about")

    return render_template("about.html",
                           name=getUserName(),
                           picture=getUserPicture(),
                           role=getUserRole())
Beispiel #8
0
def newsletterFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    if request.method == "POST":

        # Get variable
        subject = request.form.get("subject")
        html = request.form.get("ckeditor")
        text = html2text.html2text(html)
        address = request.form.get("address")
        newsletter = request.form.get("newsletter")

        # Query database for user emails for newsletter
        query = Users.query.filter_by(newsletter="True").all()
        if query == None:
            flash("No email in DB", "warning")
            return redirect("/newsletter")

        if address != "" and newsletter == None:

            # Send email (subject, email, body)
            sendMail(subject, address, text)
            flash("Single email sent", "success")

        elif address == "" and newsletter == newsletter:

            # Loop through email list and send
            index = 0
            while index < len(query):
                sendMail(subject, query[index].email, text)
                index += 1

            # Send a copy to Glenn
            sendMail(subject, os.environ["EMAIL_SEND"], text)
            flash("Group email sent", "success")

        else:

            # Flash result & redirect
            flash(
                "Send to one address or select Send Newsletter and leave address blank",
                "danger")
            return redirect("/newsletter")

        return redirect("/")

    else:

        return render_template("newsletter.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole())
Beispiel #9
0
def unconfirmedFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # Get variable
    email = getUserEmail()
    now = int(time())
    date = getUserTime()
    pin = getUserPin()
    sample = request.form.get("pin")
    user_id = session["user_id"]

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # User is confirming
        if request.form.get("confirm"):

            # Check if PIN has less than 10min
            if int(sample) == int(pin) and int(now - date) < 600:

                # Update database with confirmation
                query = Users.query.filter_by(id=user_id).first()
                query.confirmed = "True"
                db.session.commit()

                # Flash result & redirect
                flash("You are now confirmed", "success")
                return redirect("/")

            else:

                # Flash result & redirect
                flash("Wrong PIN entered and/or PIN timed out. (10min)",
                      "danger")
                return redirect("/unconfirmed")

        # User is requesting a new PIN
        if request.form.get("send"):

            # Send new PIN
            sendPin(email)

            # Flash result & redirect
            flash("An new activation PIN has been sent to your email",
                  "success")
            return redirect("/unconfirmed")

    else:

        return render_template("unconfirmed.html",
                               name=getUserName(),
                               picture=getUserPicture())
def articleFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()  


    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        return redirect("/")

    else:
        
        news = News.query.all()
    
        return render_template("article.html", name=getUserName(), picture=getUserPicture(), role=getUserRole(), news=news)
Beispiel #11
0
def usernameFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()


    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Get variable
        username = request.form.get("username")
        user_id = session["user_id"]


        # Ensure username was submitted
        if not username:
            flash("Must provide username", "warning")
            return redirect("/username")


        # Ensure username fits server-side
        if not re.search("^[a-zA-Z0-9]{2,20}$", username):
            flash("Invalid username", "danger")
            return redirect("/username")


        # Query database for username if already exists
        query = Users.query.filter_by(username=username).all()
        if len(query) != 0:
            flash("Username already taken", "danger")
            return redirect("/username")


        # Update database with username
        query = Users.query.filter_by(id=user_id).first()
        query.username = username
        db.session.commit()


        # Flash result & redirect
        flash("Username updated", "success")
        return redirect("/profile")

    
    else:

        return render_template("username.html", name=getUserName(), picture=getUserPicture(), role=getUserRole())
Beispiel #12
0
def emailFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Get variable
        email = request.form.get("email")
        user_id = session["user_id"]

        # Ensure email was submitted
        if not email:
            flash("Must provide email", "warning")
            return redirect("/email")

        # Ensure email fits server-side
        if not re.search(r"[^@]+@[^@]+\.[^@]+", email):
            flash("Invalid email", "danger")
            return redirect("/email")

        # Query database for email if already exists
        query = Users.query.filter_by(email=email).all()
        if len(query) != 0:
            flash("Email already taken", "warning")
            return redirect("/username")

        # Update database with email
        query = Users.query.filter_by(id=user_id).first()
        query.email = email
        db.session.commit()

        # Flash result & redirect
        flash("Email address updated", "success")
        return redirect("/profile")

    else:

        return render_template("email.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole())
def mailingFunction():   

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages() 


    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Get variable
        user_id = session["user_id"]


        # Activate newsletter and update DB
        if request.form.get('activate'):

            newsletter = "True"
            query = Users.query.filter_by(id=user_id).first()
            query.newsletter = newsletter
            db.session.commit()


        # Deactivate newsletter and update DB
        if request.form.get('deactivate'):

            newsletter = "False"
            query = Users.query.filter_by(id=user_id).first()
            query.newsletter = newsletter
            db.session.commit()


        # Flash result & redirect    
        flash("Newsletter updated", "success")
        return redirect("/profile")


    else:
    
        return render_template("mailing.html", name=getUserName(), picture=getUserPicture(), role=getUserRole())
def passwordFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Get variable
        password = request.form.get("password")
        user_id = session["user_id"]

        # Ensure password was submitted
        if not password:
            flash("Must provide password", "warning")
            return redirect("/password")

        # Query database for hash if already exists
        query = Users.query.filter_by(id=user_id).first()
        if check_password_hash(query.hash, password):
            flash("Password must be new", "danger")
            return redirect("/password")

        # Update database with password hash
        query = Users.query.filter_by(id=user_id).first()
        query.hash = generate_password_hash(password)
        db.session.commit()

        # Flash result & redirect
        flash("Password updated", "success")
        return redirect("/profile")

    else:

        return render_template("password.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole())
def pictureFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()


    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Get variable
        user_id = session["user_id"]


        # Save, upload and delete picture file
        file = request.files["picture"]
        if file and allowed_file(file.filename):

            filename = secure_filename(file.filename)
            file.save(os.path.join("./static", filename))
            upload = uploadPicture("./static/" + filename)
            os.remove("./static/" + filename)


            # Update database with new image url 
            query = Users.query.filter_by(id=user_id).first()
            query.picture = upload
            db.session.commit()     


        # Flash result & redirect
        flash("Profile picture updated", "success")
        return redirect("/")


    else:

        return render_template("picture.html", name=getUserName(), picture=getUserPicture(), role=getUserRole())
Beispiel #16
0
def administrationFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # Query database for plants
    plants = Plants.query.all()

    # Query database for boxes
    boxes = Boxes.query.all()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Plants table section
        if "delete_plant" in request.form:

            # Loop through the record list to match plant ID when delete button is pressed
            index = 0
            while index < len(plants):

                if int(request.form["delete_plant"]) == int(plants[index].id):

                    # Query database for plant id to delete row
                    Plants.query.filter(Plants.id == plants[index].id).delete()
                    db.session.commit()

                    # Flash result & redirect
                    flash("Plant deleted", "success")
                    return redirect("/administration")

                else:

                    index += 1

        if "edit_plant" in request.form:

            # Loop through the record list to match plant ID when edit button is pressed
            index = 0
            while index < len(plants):

                if int(request.form["edit_plant"]) == int(plants[index].id):

                    # Create a list with values of DB and append them
                    thisPlant = []
                    thisPlant.extend([
                        plants[index].id, plants[index].name,
                        plants[index].stock, plants[index].price,
                        plants[index].offer, plants[index].length,
                        plants[index].width, plants[index].height,
                        plants[index].weight, plants[index].picture,
                        plants[index].description, plants[index].express,
                        plants[index].reduced, plants[index].show
                    ])

                    return redirect(
                        url_for("editPlant.editPlantFunction",
                                plants=thisPlant))

                else:

                    index += 1

        # Boxes table section
        if "delete_box" in request.form:

            # Loop through the record list to match plant ID when delete button is pressed
            index = 0
            while index < len(boxes):

                if int(request.form["delete_box"]) == int(boxes[index].id):

                    # Query database for plant id to delete row
                    Boxes.query.filter(Boxes.id == boxes[index].id).delete()
                    db.session.commit()

                    # Flash result & redirect
                    flash("Box deleted", "success")
                    return redirect("/administration")

                else:

                    index += 1

        if "edit_box" in request.form:

            # Loop through the record list to match plant ID when edit button is pressed
            index = 0
            while index < len(boxes):

                if int(request.form["edit_box"]) == int(boxes[index].id):

                    # Create a list with values of DB and append them
                    thisBox = []
                    thisBox.extend([
                        boxes[index].id, boxes[index].name,
                        boxes[index].length, boxes[index].width,
                        boxes[index].height, boxes[index].price_de,
                        boxes[index].price_eu, boxes[index].price_ex
                    ])

                    return redirect(
                        url_for("editBox.editBoxFunction", boxes=thisBox))

                else:

                    index += 1

    else:

        return render_template("administration.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole(),
                               plants=plants,
                               boxes=boxes)
Beispiel #17
0
def indexFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Get variable
        plant_id = request.form.get("plant_id")
        user_id = session["user_id"]
        quantity = request.form.get("quantity")

        # Query database for plants name, picture, price and stock
        query = Plants.query.filter_by(id=plant_id).first()
        name = query.name
        picture = query.picture
        price = query.price
        existingStock = query.stock

        # Check if the price is reduced
        if query.reduced == "Yes":
            price = query.offer

        # Avoid going to negative stocks
        if int(existingStock) - int(quantity) < 0:
            flash("Not enough in stock", "warning")
            return redirect("/")

        # Check for existing stock in the basket
        query = Baskets.query.filter_by(plant_id=plant_id,
                                        user_id=user_id).first()
        if query != None:
            existingQuantity = query.quantity
        else:
            existingQuantity = 0

        # If there is already some plant in the basket
        if existingQuantity > 0:

            # Sum up the quantities
            newQuantity = existingQuantity + int(quantity)
            user_id = session["user_id"]
            subtotal = int(newQuantity) * float(price)

            # Update database with quantity and subtotal
            query = Baskets.query.filter_by(plant_id=plant_id).filter_by(
                user_id=user_id).first()
            query.quantity = newQuantity
            query.subtotal = subtotal
            db.session.commit()

        # First time the user has put this plant in the basket
        else:

            user_id = session["user_id"]
            subtotal = int(quantity) * float(price)

            # Add quantity to database
            db.session.add(
                Baskets(plant_id=plant_id,
                        user_id=user_id,
                        quantity=quantity,
                        name=name,
                        picture=picture,
                        price=price,
                        subtotal=subtotal))
            db.session.commit()

        # Flash result & redirect
        flash("Added to basket", "success")
        return redirect("/")

    else:

        # Query database for plants to display them
        show = "Yes"
        plants = Plants.query.filter_by(show=show).all()

        return render_template("index.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole(),
                               plants=plants)
Beispiel #18
0
def addPlantFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Get variable
        name = request.form.get("name")
        stock = request.form.get("stock")
        price = request.form.get("price")
        offer = request.form.get("offer")
        length = request.form.get("length")
        width = request.form.get("width")
        height = request.form.get("height")
        weight = request.form.get("weight")
        description = request.form.get("ckeditor")
        express = request.form.get("express")
        reduced = request.form.get("reduced")
        show = request.form.get("show")

        # Check length
        getInputLength(name, 100, "Name is too long (100)", "danger",
                       "/addPlant")
        getInputLength(stock, 6, "Stock is too big (6)", "danger", "/addPlant")
        getInputLength(price, 6, "Price is too big (6)", "danger", "/addPlant")
        getInputLength(offer, 6, "Offer is too big (6)", "danger", "/addPlant")
        getInputLength(length, 6, "Length is too big (6)", "danger",
                       "/addPlant")
        getInputLength(width, 6, "Width is too big (6)", "danger", "/addPlant")
        getInputLength(height, 6, "Height is too big (6)", "danger",
                       "/addPlant")
        getInputLength(weight, 6, "Weight is too big (6)", "danger",
                       "/addPlant")
        getInputLength(description, 300, "Description is too long (300)",
                       "danger", "/addPlant")

        # Convert offer value to integer
        if offer == "":
            offer = 0

        # Convert express value to string
        if express == None:
            express = "No"
        if express == "express":
            express = "Yes"

        # Convert show value to string
        if show == None:
            show = "No"
        if show == "show":
            show = "Yes"

        # Convert reduced value to string
        if reduced == None:
            reduced = "No"
        if reduced == "reduced":
            reduced = "Yes"

        # Ensure the plant name was submitted
        if not name:
            flash("must provide plant name", "warning")
            return redirect("/addPlant")

        # Ensure the plant name fits server-side
        if not re.search("^[a-zA-Z 0-9]{1,100}$", name):
            flash("Invalid plant name", "danger")
            return redirect("/addPlant")

        # Ensure the plant stock was submitted
        if not stock:
            flash("must provide plant stock", "warning")
            return redirect("/addPlant")

        # Ensure the plant stock fits server-side
        if not re.search("^[0-9]+$", stock):
            flash("Invalid plant stock", "danger")
            return redirect("/addPlant")

        # Ensure the plant price was submitted
        if not price:
            flash("must provide plant price", "warning")
            return redirect("/addPlant")

        # Ensure the plant price fits server-side
        if not re.search("^[0-9]+\.?[0-9]+$", format(float(price), ".2f")):
            flash("Invalid plant price", "danger")
            return redirect("/addPlant")

        # Ensure the plant offer fits server-side
        if offer != 0:
            if not re.search("^[0-9]+\.?[0-9]+$", format(float(offer), ".2f")):
                flash("Invalid plant offer", "danger")
                return redirect("/addPlant")

        # Ensure the plant length was submitted
        if not length:
            flash("must provide plant length", "warning")
            return redirect("/addPlant")

        # Ensure the plant length fits server-side
        if not re.search("^[0-9]+$", length):
            flash("Invalid plant length", "danger")
            return redirect("/addPlant")

        # Ensure the plant width was submitted
        if not width:
            flash("must provide plant width", "warning")
            return redirect("/addPlant")

        # Ensure the plant width fits server-side
        if not re.search("^[0-9]+$", width):
            flash("Invalid plant width", "danger")
            return redirect("/addPlant")

        # Ensure the plant height was submitted
        if not height:
            flash("must provide plant height", "warning")
            return redirect("/addPlant")

        # Ensure the plant height fits server-side
        if not re.search("^[0-9]+$", height):
            flash("Invalid plant height", "danger")
            return redirect("/addPlant")

        # Ensure the plant weight was submitted
        if not weight:
            flash("must provide plant weight", "warning")
            return redirect("/addPlant")

        # Ensure the plant weight fits server-side
        if not re.search("^[0-9]+$", weight):
            flash("Invalid plant weight", "danger")
            return redirect("/addPlant")

        # Ensure the plant description was submitted
        if not description:
            flash("must provide plant description", "warning")
            return redirect("/addPlant")

        # Ensure the plant description fits server-side
        if not re.search("^(?!;).+", description):
            flash("Invalid plant description", "danger")
            return redirect("/addPlant")

        # Insert plant name, stock, price, description and show status into the table
        db.session.add(
            Plants(name=name,
                   stock=stock,
                   price=price,
                   offer=offer,
                   length=length,
                   width=width,
                   height=height,
                   weight=weight,
                   description=description,
                   express=express,
                   reduced=reduced,
                   show=show))
        db.session.commit()

        # Query database for id of the last entered plant
        query = Plants.query.all()
        plant_id = query[-1].id

        # Save, upload and delete picture file
        file1 = request.files["picture"]
        if file1 and allowed_file(file1.filename):

            filename = secure_filename(file1.filename)
            file1.save(os.path.join("./static", filename))
            upload = uploadPicture("./static/" + filename)
            os.remove("./static/" + filename)

            # Update database with new image url
            query = Plants.query.filter_by(id=plant_id).first()
            query.picture = upload
            db.session.commit()

        # Save, upload and delete first thumbnail file
        file2 = request.files["thumbnail1"]
        if file2 and allowed_file(file2.filename):

            filename = secure_filename(file2.filename)
            file2.save(os.path.join("./static", filename))
            upload = uploadPicture("./static/" + filename)
            os.remove("./static/" + filename)

            # Update database with new image url
            query = Plants.query.filter_by(id=plant_id).first()
            query.thumbnail1 = upload
            db.session.commit()

        # Save, upload and delete second thumbnail file
        file3 = request.files["thumbnail2"]
        if file3 and allowed_file(file3.filename):

            filename = secure_filename(file3.filename)
            file3.save(os.path.join("./static", filename))
            upload = uploadPicture("./static/" + filename)
            os.remove("./static/" + filename)

            # Update database with new image url
            query = Plants.query.filter_by(id=plant_id).first()
            query.thumbnail2 = upload
            db.session.commit()

        # Flash result & redirect
        flash("Plant added", "success")
        return redirect("/administration")

    else:

        return render_template("addPlant.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole())
Beispiel #19
0
def addBoxFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Get variable
        name = request.form.get("name")
        length = request.form.get("length")
        width = request.form.get("width")
        height = request.form.get("height")
        weight_ne = request.form.get("weight_ne")
        weight_ex = request.form.get("weight_ex")
        price_de = request.form.get("price_de")
        price_eu = request.form.get("price_eu")
        price_ex = request.form.get("price_ex")

        # Check length
        getInputLength(name, 100, "Name is too long (100)", "danger",
                       "/addBox")
        getInputLength(length, 6, "Length is too big (6)", "danger", "/addBox")
        getInputLength(width, 6, "Width is too big (6)", "danger", "/addBox")
        getInputLength(height, 6, "Height is too big (6)", "danger", "/addBox")
        getInputLength(weight_ne, 6, "Weight non-express is too big (6)",
                       "danger", "/addBox")
        getInputLength(weight_ex, 6, "Weight express is too big (6)", "danger",
                       "/addBox")
        getInputLength(price_de, 6, "Price for DE is too big (6)", "danger",
                       "/addBox")
        getInputLength(price_eu, 6, "Price for EU is too big (6)", "danger",
                       "/addBox")
        getInputLength(price_ex, 6, "Price for Express is too big (6)",
                       "danger", "/addBox")

        # Ensure the box name was submitted
        if not name:
            flash("must provide box name", "warning")
            return redirect("/addBox")

        # Ensure the box name fits server-side
        if not re.search("^[a-zA-Z 0-9]{1,100}$", name):
            flash("Invalid box name", "danger")
            return redirect("/addBox")

        # Ensure the box length was submitted
        if not length:
            flash("must provide box length", "warning")
            return redirect("/addBox")

        # Ensure the box length fits server-side
        if not re.search("^[0-9]+$", length):
            flash("Invalid box length", "danger")
            return redirect("/addBox")

        # Ensure the box width was submitted
        if not width:
            flash("must provide box width", "warning")
            return redirect("/addBox")

        # Ensure the box width fits server-side
        if not re.search("^[0-9]+$", width):
            flash("Invalid box width", "danger")
            return redirect("/addBox")

        # Ensure the box height was submitted
        if not height:
            flash("must provide box height", "warning")
            return redirect("/addBox")

        # Ensure the box height fits server-side
        if not re.search("^[0-9]+$", height):
            flash("Invalid box height", "danger")
            return redirect("/addBox")

        # Ensure the box weight_ne was submitted
        if not weight_ne:
            flash("must provide box weight non-express", "warning")
            return redirect("/addBox")

        # Ensure the box weight_ne fits server-side
        if not re.search("^[0-9]+$", weight_ne):
            flash("Invalid box weight non-express", "danger")
            return redirect("/addBox")

        # Ensure the box weight_ex was submitted
        if not weight_ex:
            flash("must provide box weight express", "warning")
            return redirect("/addBox")

        # Ensure the box weight_ex fits server-side
        if not re.search("^[0-9]+$", weight_ex):
            flash("Invalid box weight express", "danger")
            return redirect("/addBox")

        # Ensure the box price in DE was submitted
        if not price_de:
            flash("must provide box price in DE", "warning")
            return redirect("/addBox")

        # Ensure the box price in DE fits server-side
        if not re.search("^[0-9]+\.?[0-9]+$", format(float(price_de), ".2f")):
            flash("Invalid box price in DE", "danger")
            return redirect("/addBox")

        # Ensure the box price in EU was submitted
        if not price_eu:
            flash("must provide box price in EU", "warning")
            return redirect("/addBox")

        # Ensure the box price in EU fits server-side
        if not re.search("^[0-9]+\.?[0-9]+$", format(float(price_eu), ".2f")):
            flash("Invalid box price in EU", "danger")
            return redirect("/addBox")

        # Ensure the box express price was submitted
        if not price_ex:
            flash("must provide box express price", "warning")
            return redirect("/addBox")

        # Ensure the box express price fits server-side
        if not re.search("^[0-9]+\.?[0-9]+$", format(float(price_ex), ".2f")):
            flash("Invalid box express price", "danger")
            return redirect("/addBox")

        # Insert box name, length, width, height, price DE, price EU and price EX into the table
        db.session.add(
            Boxes(name=name,
                  length=length,
                  width=width,
                  height=height,
                  weight_ne=weight_ne,
                  weight_ex=weight_ex,
                  price_de=price_de,
                  price_eu=price_eu,
                  price_ex=price_ex))
        db.session.commit()

        # Flash result & redirect
        flash("Box added", "success")
        return redirect("/administration")

    else:

        return render_template("addBox.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole())
def basketFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # Get variable
    user_id = session["user_id"]
    thisBasketItems = []

    # Query database for plants
    thisBasket = Baskets.query.filter_by(user_id=user_id).all()

    # Query database for plants
    baskets = Baskets.query.all()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Check if user deletes an item in the basket
        if "delete" in request.form:

            # Loop through the record list to match plant ID when delete button is pressed
            index = 0
            while index < len(baskets):

                if int(request.form["delete"]) == int(baskets[index].id):

                    # Query database for plant id to delete row
                    Baskets.query.filter(
                        Baskets.id == baskets[index].id).delete()
                    db.session.commit()

                    # Flash result & redirect
                    flash("Item deleted", "success")
                    return redirect("/basket")

                else:

                    index += 1

        # Check for available quantities
        if "pay" in request.form:

            # Check if there are plants in the basket
            for item in thisBasket:
                thisBasketItems.append(item.name)

            if len(thisBasketItems) == 0:

                # Flash result & redirect
                flash("There are no plants to order", "danger")
                return redirect("/basket")

            # Set flag
            flag = False

            # Loop through the user basket
            for item in thisBasket:

                # Check with respective id's against Plants
                query = Plants.query.filter_by(id=item.plant_id).first()

                # If user orders too much
                if item.quantity > query.stock:

                    # Set flag to True
                    flag = True

                    # Adapting basket to stock quantity and correct basket subtotal
                    item.quantity = query.stock
                    item.subtotal = int(query.stock) * float(item.price)
                    db.session.commit()

                    # Flash result & redirect
                    flash("Not enough stock of: " + str(item.name), "warning")
                    flash("Adapting, only " + str(query.stock) + " available",
                          "warning")

                else:
                    flag = False

            # Check for flag status
            if flag == True:
                return redirect("/basket")

            else:
                return redirect("/pay")

    else:

        # Get total price
        total = 0
        for element in thisBasket:

            total += element.subtotal

        return render_template("basket.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole(),
                               baskets=thisBasket,
                               total=total)
Beispiel #21
0
def confirmationFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Fake pay varibale
        pay = request.form.get("pay")

        # Get variable
        user_id = session["user_id"]
        date = ctime(time())
        plants = []
        items = []
        addresses = []
        total = 0

        # Convert pay value to string
        if pay == None:
            pay = "No"
        if pay == "pay":
            pay = "Yes"

        if pay == "Yes":

            # Update pay variable
            query = Orders.query.filter_by(user_id=user_id).all()
            query[-1].pay = "Yes"
            total = query[-1].total
            db.session.commit()

            # Make plants array from basket
            query = Baskets.query.filter_by(user_id=user_id)
            for element in query:
                plants.append([
                    str(element.plant_id),
                    str(element.name),
                    str(element.quantity),
                    str(element.price)
                ])

            # Add to plants array the plants features
            index = 0
            while index < len(plants):
                query = Plants.query.filter_by(id=plants[index][0])
                for element in query:
                    plants[index].extend([
                        str(element.length),
                        str(element.width),
                        str(element.height),
                        str(element.weight),
                        str(element.express)
                    ])
                index += 1

            # Make array with all the plants side-by-side and sort them
            for plant in plants:
                index = int(plant[2])
                while index > 0:
                    items.extend([plant])
                    index -= 1

            # Make address array
            query = Users.query.filter_by(id=user_id).first()
            addresses.extend([
                query.first, query.last, query.caresof, query.street,
                query.house, query.zipcode, query.city, query.country,
                query.additional
            ])

            # Delete basket in DB
            Baskets.query.filter_by(user_id=user_id).delete()
            db.session.commit()

            # Update stock in Plants
            for item in items:

                # Query for plant stock of corresponding id
                query = Plants.query.filter_by(id=item[0]).first()

                # Check if there is still at least one unit
                if query.stock >= 1:

                    # decrement by one & commit
                    query.stock -= 1
                    db.session.commit()

                else:

                    # Flash result & redirect
                    flash("Not enough stock of " + str(itemCopy[1]), "danger")
                    return redirect("/basket")

            # Send order confirmation email to client
            subject = "Your order from the Crazy Plant Crew"
            query = Users.query.filter_by(id=user_id).first()
            email = query.email
            body = render_template('order.html',
                                   name=getUserName(),
                                   addresses=addresses,
                                   plants=plants,
                                   total=total,
                                   date=date)
            sendMail(subject, email, body)

            # Send closed deal email to Glenn
            subject = "You closed a deal!"
            email = os.environ["EMAIL_SEND"]
            body = render_template('deal.html',
                                   name=getUserName(),
                                   addresses=addresses,
                                   total=total,
                                   date=date)
            sendMail(subject, email, body)

            # Flash result & redirect
            flash("Plant(s) ordered", "success")
            return redirect("/history")

        if pay != "Yes":

            # Flash result & redirect
            flash("Payment not completed ", "warning")
            return redirect("/confirmation")

    else:

        # Get variable
        user_id = session["user_id"]
        date = ctime(time())
        pay = "No"
        subtotal = 0
        shipping = 0
        total = 0
        cost = []
        addresses = []
        plants = []
        items = []
        boxesNE = []
        boxesEX = []
        boxes = []
        packaging = []
        weight = []

        # Make plants array from basket
        query = Baskets.query.filter_by(user_id=user_id)
        for element in query:
            plants.append([
                str(element.plant_id),
                str(element.name),
                str(element.quantity),
                str(element.price)
            ])
            subtotal += element.subtotal

        # Add to plants array the plants features
        index = 0
        while index < len(plants):
            query = Plants.query.filter_by(id=plants[index][0])
            for element in query:
                plants[index].extend([
                    str(element.length),
                    str(element.width),
                    str(element.height),
                    str(element.weight),
                    str(element.express)
                ])
            index += 1

        # Make address array
        query = Users.query.filter_by(id=user_id).first()
        addresses.extend([
            query.first, query.last, query.caresof, query.street, query.house,
            query.zipcode, query.city, query.country, query.additional
        ])

        # Make express variable
        express = query.express

        # Make array with available boxes
        query = Boxes.query.all()
        for element in query:
            packaging.append([
                str(element.name),
                str(element.length),
                str(element.width),
                str(element.height),
                str(element.weight_ne),
                str(element.weight_ex),
                str(element.price_de),
                str(element.price_eu),
                str(element.price_ex)
            ])

        # Check if boxes are in the system
        if len(packaging) == 0:

            # Flash result & redirect
            flash("There are no box available", "danger")
            return redirect("/basket")

        # Checking plants sizes and weight against boxes sizes and capacity, if it fits, append adapted box to array of possible needed box
        for plant in plants:
            for package in packaging:

                # Express only works in Germany
                if addresses[7] == "Germany":

                    # Check if express is needed for the whole
                    if express == "No":

                        # Check if express is needed on one plant
                        if plant[8] == "No":
                            if int(plant[4]) < int(package[1]) and int(
                                    plant[5]) < int(package[2]) and int(
                                        plant[6]) < int(package[3]) and int(
                                            plant[7]) < int(package[4]):
                                boxesNE.append([package, plant])
                                break

                        # Check if express is needed on one plant
                        if plant[8] == "Yes":
                            if int(plant[4]) < int(package[1]) and int(
                                    plant[5]) < int(package[2]) and int(
                                        plant[6]) < int(package[3]) and int(
                                            plant[7]) < int(package[5]):
                                boxesEX.append([package, plant])
                                break

                    # Check if express is needed for the whole
                    if express == "Yes":

                        if int(plant[4]) < int(package[1]) and int(
                                plant[5]) < int(package[2]) and int(
                                    plant[6]) < int(package[3]) and int(
                                        plant[7]) < int(package[5]):
                            boxesEX.append([package, plant])
                            break

                # Express only works in Germany
                if addresses[7] != "Germany":

                    if int(plant[4]) < int(package[1]) and int(plant[5]) < int(
                            package[2]) and int(plant[6]) < int(
                                package[3]) and int(plant[7]) < int(
                                    package[4]):
                        boxesNE.append([package, plant])
                        break

        # Sort arrays boxes NE & RE
        boxesNE = sorted(boxesNE,
                         key=lambda x:
                         (int(x[1][4]), int(x[1][5]), int(x[1][6])),
                         reverse=True)
        boxesEX = sorted(boxesEX,
                         key=lambda x:
                         (int(x[1][4]), int(x[1][5]), int(x[1][6])),
                         reverse=True)

        # Make array with all the plants side-by-side and sort them
        for plant in plants:
            index = int(plant[2])
            while index > 0:
                items.extend([plant])
                index -= 1

        items = sorted(items,
                       key=lambda x: (int(x[4]), int(x[5]), int(x[6])),
                       reverse=True)

        # Function to take the biggest box needed from the express group first, then from the non express group. Increment sending costs.
        def plantLoop(thisPlant):

            # Express only can only be in Germany - Append needed box - Append to cost
            if len(boxesEX
                   ) > 0 and express == "Yes" and addresses[7] == "Germany":
                for boxEX in boxesEX:
                    if int(thisPlant[0]) == int(boxEX[1][0]):
                        cost.append(float(boxEX[0][8]))
                        boxes.extend([boxEX[0]])
                        weight.append(int(boxEX[0][5]))
                        return

            # Express only can only be in Germany - Append needed box - Append to cost
            if len(boxesEX) > 0 and express == "No" and thisPlant[
                    8] == "Yes" and addresses[7] == "Germany":
                for boxEX in boxesEX:
                    if int(thisPlant[0]) == int(boxEX[1][0]):
                        boxes.extend([boxEX[0]])
                        cost.append(float(boxEX[0][8]))
                        weight.append(int(boxEX[0][5]))
                        return

            # Non express but in Germany - Append needed box - Append to cost
            elif len(boxesNE) > 0 and express == "No" and thisPlant[
                    8] == "No" and addresses[7] == "Germany":
                for boxNE in boxesNE:
                    if int(thisPlant[0]) == int(boxNE[1][0]):
                        boxes.extend([boxNE[0]])
                        cost.append(float(boxNE[0][6]))
                        weight.append(int(boxNE[0][4]))
                        return

            # Non express in the EU - Append needed box - Append to cost
            elif len(boxesNE
                     ) > 0 and express == "No" and addresses[7] != "Germany":
                for boxNE in boxesNE:
                    if int(thisPlant[0]) == int(boxNE[1][0]):
                        boxes.extend([boxNE[0]])
                        cost.append(float(boxNE[0][7]))
                        weight.append(int(boxNE[0][4]))
                        return

            # Return False if there are no more plant to cover
            else:
                return False

        # Make a grid from the last needed box to represent its bottom
        def makeGrid():
            if len(boxes) > 0:
                thisBox = [["0" for row in range(int(boxes[-1][1]))]
                           for row in range(int(boxes[-1][2]))]
                return thisBox

            else:
                return False

        # Take plants length and width
        def getAttributes(thisPlant):
            if len(items) > 0:
                length = thisPlant[4]
                width = thisPlant[5]
                mass = thisPlant[7]
                return length, width, mass

            else:
                return False

        # Filler function
        def drawLoop(x, y, length, width, rotation, thisBox):

            # Fill up horizontally
            def drawHorizon(row):
                drawIndexH = 0
                while drawIndexH < len(row):

                    if rotation == False and drawIndexH >= x and drawIndexH < x + int(
                            length):
                        row[drawIndexH] = "1"
                        drawIndexH += 1

                    elif rotation == True and drawIndexH >= x and drawIndexH < x + int(
                            width):
                        row[drawIndexH] = "1"
                        drawIndexH += 1

                    else:
                        drawIndexH += 1

            # Fill up vertically
            drawIndexV = 0
            while drawIndexV < len(thisBox):

                if rotation == False and drawIndexV >= y and drawIndexV < y + int(
                        width):
                    drawHorizon(thisBox[drawIndexV])
                    drawIndexV += 1

                elif rotation == True and drawIndexV >= x and drawIndexV < x + int(
                        width):
                    drawHorizon(thisBox[drawIndexV])
                    drawIndexV += 1

                else:
                    drawIndexV += 1

        # Grid looper
        def gridLoop(length, width, thisBox):

            # Horizontal checker for free space
            def gridHorizon(row):
                gridIndexH = 0
                while gridIndexH < len(row):

                    # Search of a "0"
                    if row[gridIndexH] == "0":

                        # Return first available "0"
                        return gridIndexH

                    else:
                        gridIndexH += 1

            # Vertical checker for free space
            gridIndexV = 0
            while gridIndexV < len(thisBox):

                # Get free space horizontally
                x = gridHorizon(thisBox[gridIndexV])

                # X must exist otherwise the plant never fits
                if x != None:

                    # Check if fits with the length horizontally
                    if x <= int(len(thisBox[gridIndexV]) - int(length)):

                        # Check if fits with width vertically
                        if gridIndexV + int(width) < len(thisBox):

                            # Check if we find a "0" to be sure there is enough space
                            if thisBox[gridIndexV + int(width)][x] == "0":

                                # Set roation flag
                                rotation = False

                                # Set the y axis
                                y = gridIndexV

                                # Start drawing
                                return drawLoop(x, y, length, width, rotation,
                                                thisBox)

                            else:
                                gridIndexV += 1

                        else:
                            return False

                    # Check if fits with width horizontally (flipped)
                    elif x <= int(len(thisBox[gridIndexV]) - int(width)):

                        # Check if fits with length vertically
                        if gridIndexV + int(length) < len(thisBox):

                            # Check if we find a "0" to be sure there is enough space
                            if thisBox[gridIndexV + int(length)][x] == "0":

                                # Set rotation flag
                                rotation = True

                                # Set the y axis
                                y = gridIndexV

                                # Start drawing
                                return drawLoop(x, y, length, width, rotation,
                                                thisBox)

                            else:
                                gridIndexV += 1

                        else:
                            gridIndexV += 1

                    else:
                        gridIndexV += 1

                else:
                    return False

        # Delete dealt plants and update corresponding stock
        def deleteLoop(thisPlant):
            if len(items) > 0:

                return items.remove(thisPlant)

            else:
                return False

        # Master loop
        def masterLoop():

            # Check for other plants to fit present box
            def slaveLoop(thisBox):
                if len(items) > 0:
                    for item in items:

                        # Get needed attributes
                        length, width, mass = getAttributes(item)

                        # Check if there is enough available weight
                        if weight[-1] - int(mass) > 0:

                            # Update available weight
                            weight[-1] -= int(mass)

                            # Check if possible to draw an other plant in the grid
                            if gridLoop(length, width, thisBox) != False:

                                # Delete dealt plant
                                deleteLoop(item)

                                # Recursively try again
                                slaveLoop(thisBox)

                            else:
                                masterLoop()

                        else:
                            masterLoop()

                else:
                    return

            # Start dealing with every plants
            if len(items) > 0:
                for item in items:

                    # Take needed box
                    plantLoop(item)

                    # Make a grid and get needed attributes
                    thisBox = makeGrid()
                    length, width, mass = getAttributes(item)

                    # Check if there is enough available weight
                    if weight[-1] - int(mass) > 0:

                        # Update available weight
                        weight[-1] -= int(mass)

                        # Fill up grid
                        gridLoop(length, width, thisBox)

                        # Delete dealt plants
                        deleteLoop(item)

                        # Start slaveLoop to check if other plants can fit in that box
                        slaveLoop(thisBox)

                    else:
                        return

            return

        # Start main loop
        masterLoop()

        # Get total shipping cost
        for element in cost:
            shipping += element

        total = shipping + subtotal

        # Insert order informations into the orders table
        db.session.add(
            Orders(user_id=user_id,
                   date=date,
                   plants=str(plants),
                   boxes=str(boxes),
                   addresses=str(addresses),
                   express=express,
                   pay=pay,
                   shipping=shipping,
                   subtotal=subtotal,
                   total=total))
        db.session.commit()

        return render_template("confirmation.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole(),
                               subtotal=subtotal,
                               shipping=shipping,
                               total=total)
Beispiel #22
0
def profileFunction():
    
    return render_template("profile.html", name=getUserName(), picture=getUserPicture(), role=getUserRole())
def loggedFunction():

    # Force flash() to get the messages on the same page as the redirect.
    get_flashed_messages()

    # User reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # Get variable
        remove = request.form.get("remove")
        promote = request.form.get("promote")
        demote = request.form.get("demote")

        if request.form.get("remove"):

            # Check if field is not empty
            if remove == "":
                flash("Must provide name REMOVE", "warning")
                return redirect("/logged")

            # Check if it is root
            if remove == os.environ.get("USERNAME"):
                flash("Can't remove this user", "warning")
                return redirect("/logged")

            # Check if the name matches
            if Users.query.filter_by(username=remove).first() == None:
                flash("No matching name", "warning")
                return redirect("/logged")

            # Check if it is the user itself
            if Users.query.filter_by(username=remove).first() == getUserName():
                flash("Can't remove yourself", "warning")
                return redirect("/logged")

            # Check if it is the user is an admin
            query = Users.query.filter_by(username=remove).first()
            if query.role == "admin":
                flash("Can't remove admin", "warning")
                return redirect("/logged")

            # Update database by removing user
            else:
                Users.query.filter(Users.username == remove).delete()
                db.session.commit()
                flash("User deleted", "success")
                return redirect("/logged")

        if request.form.get("promote"):

            # Check if field is not empty
            if promote == "":
                flash("Must provide name", "warning")
                return redirect("/logged")

            # Check if the name matches
            if Users.query.filter_by(username=promote).first() == None:
                flash("No matching name", "warning")
                return redirect("/logged")

            # Check if it is the user is an admin
            query = Users.query.filter_by(username=promote).first()
            if query.role == "admin":
                flash("Already admin", "warning")
                return redirect("/logged")

            # Update database by promoting user
            else:
                query = Users.query.filter_by(username=promote).first()
                query.role = "admin"
                db.session.commit()
                flash("User promoted", "success")
                return redirect("/logged")

        if request.form.get("demote"):

            # Check if field is not empty
            if demote == "":
                flash("Must provide name", "warning")
                return redirect("/logged")

            # Check if it is root
            if demote == os.environ.get("USERNAME"):
                flash("Can't demote this user", "warning")
                return redirect("/logged")

            # Check if the name matches
            if Users.query.filter_by(username=demote).first() == None:
                flash("No matching name", "warning")
                return redirect("/logged")

            # Check if it is the user itself
            if Users.query.filter_by(username=demote).first() == getUserName():
                flash("Can't demote yourself", "warning")
                return redirect("/logged")

            # Update database by demoting user
            else:
                query = Users.query.filter_by(username=demote).first()
                query.role = "user"
                db.session.commit()
                flash("Admin demoted", "success")
                return redirect("/logged")

    else:

        # Set variable
        users = []
        admins = []
        unconfirmeds = []
        index = 0

        # Query DB for all users
        query = Users.query.all()

        # Loop through the DB query
        while index < len(query):

            # Users list
            if query[index].role == "user":
                users.extend([[query[index].username, query[index].email]])

            # Admins list
            if query[index].role == "admin":
                admins.extend([query[index].username])

            # Unconfirmeds list
            if query[index].confirmed == "False":
                unconfirmeds.extend([query[index].username])

            index += 1

        return render_template("logged.html",
                               name=getUserName(),
                               picture=getUserPicture(),
                               role=getUserRole(),
                               users=users,
                               admins=admins,
                               unconfirmeds=unconfirmeds)