diff --git a/app.py b/app.py new file mode 100644 index 0000000..2eda104 --- /dev/null +++ b/app.py @@ -0,0 +1,160 @@ +from pygrocy import Grocy +from pygrocy.data_models.generic import EntityType +from flask import Flask, render_template, request, redirect +from datetime import datetime +from werkzeug.middleware.proxy_fix import ProxyFix + +from pprint import pprint + +#Global variables +DEFAULT_AMOUNT = 1 +CASHBOX_USERID = 3 + +error_messages = { + 'item_not_found': 'Tenhle produkt nemůžeme najít ve skladu. Zkus to prosím znovu a pokud to nepůjde, řekni někomu z Trhliny.', + 'item_not_available': 'Podle kompjůtru ne! Náš systém říká že tuhle věc nemáme na skladu. Asi chyba u nás...', + 'user_not_found': 'Tenhle účet neexistuje nebo nemá povolený kredit. Můžeš věc naskenovat znovu a hodit prachy do kasičky', +} + + + +g = Grocy("http://localhost", "BZzLkorATL66hSbKwIERoesALcIqNUPW91zONNNTHP0r9N6vk2", port=8080) + + +# Write money movement into the ledger (transaction log in Grocy). +def write_ledger(prod, userid, transaction_type, end_balance): + entity_id = { "userentity_id": 1 } + record_id = g.add_generic(EntityType.USER_OBJECTS, entity_id)['created_object_id'] + + account = userid + amount = prod['price'] + balance = end_balance + item = prod['id'] + time_grocy = g.get_system_time().time_local + time = time_grocy.strftime("%Y-%m-%d, %H:%M:%S") + + g.set_userfields('userentity-accounting', record_id, 'account', account) + g.set_userfields('userentity-accounting', record_id, 'amount', amount) + g.set_userfields('userentity-accounting', record_id, 'balance', balance) + g.set_userfields('userentity-accounting', record_id, 'item', item) + g.set_userfields('userentity-accounting', record_id, 'type', transaction_type) + g.set_userfields('userentity-accounting', record_id, 'datetime', time) + + + +# Subtract the price from user account or add it to the cashier. Also write it to ledger. +def prod_bill_user(prod, user): + start_balance = user['balance'] + end_balance = start_balance - prod['price'] + g.set_userfields('users', user['id'], 'balance', end_balance) + write_ledger(prod, user['id'], 'bar-bill-user', end_balance) + return(end_balance) + +# Add money paid for the product to the cashbox. +def prod_bill_cash(prod): + for user in g.users(): + if user.id == CASHBOX_USERID: + cashbox = user + break + + start_balance = float(g.get_userfields('users', cashbox.id)['balance']) + end_balance = start_balance + prod['price'] + g.set_userfields('users', cashbox.id, 'balance', end_balance) + write_ledger(prod, 3, 'bar-cash-payment', end_balance) + + +# Receive barcode and user code from website and process it. +def prod_consume(prod): + g.consume_product(product_id = prod['id'], amount = DEFAULT_AMOUNT) + +# Find user by custom variable barid - code for credit payments +def user_by_barid(user_barid): + users = g.users() + users_data = [] + # Get all users and their custom fields + for user in users: + user_fields = g.get_userfields('users', user.id) + if user_fields['accountingenabled']: + user_data = { + 'accounting_enabled': user_fields['accountingenabled'], + 'balance': float(user_fields['balance']), + 'barid': user_fields['barid'], + 'name': user.display_name, + 'id': user.id + } + users_data.append(user_data) + + # Find user with selected barID + for user in users_data: + if user['barid'] == str(user_barid): + return user + + # If no user with this barID and enabled accounting is found, return false + return False + + +# Get data about product and price by barcode +def prod_by_barcode(barcode): + prod = g.product_by_barcode(barcode) + sell_price = g.get_userfields('products', prod.id)['sellprice'] + prod_data = { + 'id': prod.id, + 'name': prod.name, + 'available': prod.available_amount, + 'price': float(sell_price), + 'barcode': barcode + } + return prod_data + + + +app = Flask(__name__) + +@app.route('/') +def index(): + return render_template('index.html') + +@app.route('/checkout/', methods=['POST']) +def scan(): + barcode = request.form.get('barcode') + try: + prod = prod_by_barcode(barcode) + + except: + return redirect('/error/item_not_found') + + if int(prod['available']) > 0: + return render_template('checkout.html', prod = prod) + else: + return redirect('/error/item_not_available') + +@app.route('/cash-payment/', methods=['POST']) +def cash_payment(): + barcode = request.form.get('barcode') + prod = prod_by_barcode(barcode) + prod_consume(prod) + prod_bill_cash(prod) + return render_template('cash-payment.html', prod = prod) + +@app.route('/account-payment/', methods=['POST']) +def account_payment(): + user_barid = request.form.get('barid') + barcode = request.form.get('barcode') + prod = prod_by_barcode(barcode) + user = user_by_barid(user_barid) + if user: + prod_consume(prod) + end_balance = prod_bill_user(prod, user) + return render_template('account-payment.html', prod = prod, user = user, balance = end_balance) + else: + return redirect('/error/user_not_found') + + +@app.route('/error/') +def error_send(err): + return render_template('error.html', msg = error_messages[err]) + + +if __name__ == '__main__': + app.run(host="0.0.0.0") + app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1) \ No newline at end of file diff --git a/app/app.py b/app/app.py index deb2ad7..2eda104 100644 --- a/app/app.py +++ b/app/app.py @@ -2,6 +2,7 @@ from pygrocy import Grocy from pygrocy.data_models.generic import EntityType from flask import Flask, render_template, request, redirect from datetime import datetime +from werkzeug.middleware.proxy_fix import ProxyFix from pprint import pprint @@ -155,4 +156,5 @@ def error_send(err): if __name__ == '__main__': - app.run(host="0.0.0.0") \ No newline at end of file + app.run(host="0.0.0.0") + app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1) \ No newline at end of file diff --git a/app/requirements.txt b/requirements.txt similarity index 100% rename from app/requirements.txt rename to requirements.txt diff --git a/app/templates/account-payment.html b/templates/account-payment.html similarity index 100% rename from app/templates/account-payment.html rename to templates/account-payment.html diff --git a/app/templates/base.html b/templates/base.html similarity index 100% rename from app/templates/base.html rename to templates/base.html diff --git a/app/templates/cash-payment.html b/templates/cash-payment.html similarity index 100% rename from app/templates/cash-payment.html rename to templates/cash-payment.html diff --git a/app/templates/checkout.html b/templates/checkout.html similarity index 100% rename from app/templates/checkout.html rename to templates/checkout.html diff --git a/app/templates/error.html b/templates/error.html similarity index 100% rename from app/templates/error.html rename to templates/error.html diff --git a/app/templates/index.html b/templates/index.html similarity index 100% rename from app/templates/index.html rename to templates/index.html