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)