2017-03-21 11:26:25 +01:00
|
|
|
from datetime import datetime
|
2017-03-25 02:38:02 +01:00
|
|
|
from time import sleep
|
|
|
|
import escpos.printer
|
2017-03-21 11:26:25 +01:00
|
|
|
|
|
|
|
from flask import Flask, redirect, request, render_template, flash
|
|
|
|
from flask_login import LoginManager, login_user, logout_user, login_required
|
|
|
|
|
|
|
|
from pos.config import Config
|
|
|
|
from pos.logging import init_logging, get_logger
|
2017-03-22 17:12:15 +01:00
|
|
|
from pos.database import Database, User, Product, Event, Transaction, Order
|
2017-03-21 11:26:25 +01:00
|
|
|
|
|
|
|
|
|
|
|
config = Config()
|
|
|
|
debug = config.core['GENERAL'].getboolean('Debug', False)
|
|
|
|
conf_db = config.core['DATABASE']
|
2017-03-25 02:38:02 +01:00
|
|
|
conf_printer = config.core['PRINTER']
|
2017-03-21 11:26:25 +01:00
|
|
|
conf_flask = config.core['FLASK']
|
|
|
|
|
|
|
|
init_logging(config.logging)
|
|
|
|
log = get_logger('web')
|
|
|
|
|
2017-03-25 02:38:02 +01:00
|
|
|
printer = escpos.printer.Network(
|
|
|
|
conf_printer['Host'],
|
|
|
|
port=conf_printer.getint('Port'),
|
|
|
|
timeout=15)
|
|
|
|
|
|
|
|
|
|
|
|
db = Database(**conf_db)
|
|
|
|
|
2017-03-21 11:26:25 +01:00
|
|
|
app = Flask(__name__)
|
|
|
|
app.config.update(
|
|
|
|
debug=debug,
|
|
|
|
SECRET_KEY=conf_flask['SECRET_KEY']
|
|
|
|
)
|
|
|
|
|
|
|
|
login_manager = LoginManager()
|
|
|
|
login_manager.init_app(app)
|
|
|
|
login_manager.login_view = 'login'
|
|
|
|
login_manager.login_message_category = 'error'
|
|
|
|
|
|
|
|
|
|
|
|
@login_manager.user_loader
|
|
|
|
def load_user(uid):
|
|
|
|
user = None
|
|
|
|
with db.get_session() as session:
|
|
|
|
user = session.query(User).get(uid)
|
|
|
|
return user
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/')
|
|
|
|
def home():
|
|
|
|
return redirect('/sell')
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/login', methods=['GET'])
|
|
|
|
def login_page():
|
|
|
|
return render_template('login.html', title='Login')
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/login', methods=['POST'])
|
|
|
|
def login():
|
|
|
|
username = request.form['username']
|
|
|
|
password = request.form['password']
|
|
|
|
|
|
|
|
if not all([username, password]):
|
|
|
|
flash("Fill all fields.", 'error')
|
|
|
|
return login_page(), 400
|
|
|
|
|
|
|
|
with db.get_session() as session:
|
|
|
|
user = session.query(User)\
|
|
|
|
.filter(User.username == username)\
|
|
|
|
.filter(User.is_active == 1)\
|
|
|
|
.one_or_none()
|
|
|
|
|
|
|
|
if user is None:
|
|
|
|
flash("User not found.", 'error')
|
|
|
|
return login_page(), 400
|
|
|
|
|
|
|
|
if user.password == password:
|
|
|
|
login_user(user)
|
|
|
|
session.add(user)
|
|
|
|
user.is_authenticated = True
|
|
|
|
flash("Succesfully logged in.", 'success')
|
|
|
|
return redirect('/')
|
|
|
|
else:
|
|
|
|
flash("Wrong password.", 'error')
|
|
|
|
return login_page(), 400
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/logout')
|
|
|
|
def logout():
|
|
|
|
logout_user()
|
|
|
|
return redirect('/')
|
|
|
|
|
|
|
|
|
|
|
|
def get_products(session):
|
|
|
|
return session.query(Product)\
|
|
|
|
.filter(Product.is_active == 1)\
|
2017-03-24 19:23:37 +01:00
|
|
|
.order_by(Product.sort.asc())\
|
2017-03-21 11:26:25 +01:00
|
|
|
.all()
|
|
|
|
|
|
|
|
|
|
|
|
def get_event(session):
|
|
|
|
return session.query(Event)\
|
|
|
|
.filter(Event.starts_at < datetime.now())\
|
2017-03-24 23:03:13 +01:00
|
|
|
.filter((Event.ends_at.is_(None))
|
|
|
|
| (Event.ends_at > datetime.now()))\
|
2017-03-21 11:26:25 +01:00
|
|
|
.one_or_none()
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/sell', methods=['GET'])
|
2017-03-22 17:03:14 +01:00
|
|
|
@login_required
|
2017-03-21 11:26:25 +01:00
|
|
|
def sell_page():
|
|
|
|
with db.get_session() as session:
|
|
|
|
products = get_products(session)
|
|
|
|
event = get_event(session)
|
|
|
|
|
|
|
|
return render_template('sell.html',
|
|
|
|
title='Sell', event=event, products=products)
|
|
|
|
|
|
|
|
|
2017-03-25 02:38:02 +01:00
|
|
|
def print_orders(event, orders):
|
|
|
|
printer.open()
|
|
|
|
|
|
|
|
printer.set(align='CENTER')
|
|
|
|
printer.image('static/img/macao-logo-printer.png', impl='bitImageColumn')
|
|
|
|
|
|
|
|
printer.set(align='CENTER', text_type='B')
|
|
|
|
printer.text(event.name.upper())
|
|
|
|
printer.text("\n\n")
|
|
|
|
|
|
|
|
for o in orders:
|
|
|
|
printer.set(align='LEFT', width=2, height=2)
|
|
|
|
printer.text("{} x {}".format(o.quantity, o.product.name.upper()))
|
|
|
|
printer.text("\n")
|
|
|
|
|
|
|
|
printer.text("\n")
|
|
|
|
|
|
|
|
printer.cut()
|
|
|
|
printer.close()
|
|
|
|
sleep(0.7)
|
|
|
|
|
|
|
|
|
|
|
|
def print_transaction(transaction):
|
|
|
|
categorized_orders = {}
|
|
|
|
|
|
|
|
for o in transaction.orders:
|
|
|
|
uid = o.product.category_uid
|
|
|
|
|
|
|
|
if not categorized_orders.get(uid, False):
|
|
|
|
categorized_orders[uid] = []
|
|
|
|
|
|
|
|
categorized_orders[uid].append(o)
|
|
|
|
|
|
|
|
for cat, orders in categorized_orders.items():
|
|
|
|
print_orders(transaction.event, orders)
|
|
|
|
|
|
|
|
|
2017-03-21 11:26:25 +01:00
|
|
|
@app.route('/sell', methods=['POST'])
|
|
|
|
@login_required
|
|
|
|
def sell():
|
|
|
|
with db.get_session() as session:
|
|
|
|
event = get_event(session)
|
|
|
|
|
|
|
|
if event is None:
|
|
|
|
flash("Can't perform order without an ongoing event!", 'error')
|
|
|
|
return sell_page()
|
|
|
|
|
|
|
|
quantities = request.form.values()
|
|
|
|
if not any(int(qty) > 0 for qty in quantities):
|
|
|
|
flash("Can't perform empty order!", 'error')
|
|
|
|
return sell_page()
|
|
|
|
|
|
|
|
with db.get_session() as session:
|
|
|
|
items = request.form.items()
|
2017-03-22 17:12:15 +01:00
|
|
|
orders = [
|
|
|
|
Order(product_uid=uid, quantity=qty)
|
2017-03-21 11:26:25 +01:00
|
|
|
for uid, qty in items
|
|
|
|
if int(qty) > 0
|
|
|
|
]
|
|
|
|
|
2017-03-22 17:12:15 +01:00
|
|
|
transaction = Transaction(event_uid=event.uid, orders=orders)
|
|
|
|
session.add(transaction)
|
2017-03-25 02:38:02 +01:00
|
|
|
session.flush()
|
|
|
|
print_transaction(transaction)
|
2017-03-21 11:26:25 +01:00
|
|
|
|
|
|
|
flash("Success!", 'success')
|
|
|
|
return sell_page()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
app.run(host='0.0.0.0', port=8080, debug=debug)
|