def borrel_mode(drink_id=None): global borrel_mode_enabled, borrel_mode_drinks # Get the user that is paying for everything in borrel mode borrel_mode_user = int(settings['borrel_mode_user']) # If the user is -1, borrel mode is disabled so we do not have to execute anything if borrel_mode_enabled: # If the current drink is in the products... if drink_id is None or drink_id in borrel_mode_drinks: total_bought = 0 # We count the total amount of borrel mode products bought (also before the borrel started) for p1 in borrel_mode_drinks: for p in Purchase.query.filter(Purchase.user_id == borrel_mode_user, Purchase.product_id == p1, Purchase.price > 0).all(): total_bought += p.amount total_bought = round_up(total_bought) # Calculate how many products are left left_over = round_up(float(settings['borrel_mode_amount']), 2) + round_up(float(settings['borrel_mode_start_amount']), 2) - total_bought # If it is zero or less... if left_over <= 0: # We disable borrel mode by changing some settings and variables update_settings('borrel_mode_user', -1) borrel_mode_enabled = False return None # If borrel mode is on, we set the boolean and return how many is left and who is paying borrel_mode_enabled = True return {'left': round_down(left_over, 0), 'user': User.query.get(borrel_mode_user).name} return None
def create_purchases_shared(orders, product, total_bought, r, price, initial_amount): success_messages = {} for o in orders: amount = round_up(o['amount'] * initial_amount / total_bought) return_message = dbhandler.addpurchase(product.id, o['user_id'], amount, r, price) process_alert(return_message, success_messages) return success_messages
def admin_transactions_delete(tranid): check_if_local_machine() check_if_not_view_only() transaction = Transaction.query.get(tranid) u = User.query.get(transaction.user_id) if transaction.purchase_id is not None: purchase = Purchase.query.get(transaction.purchase_id) product = Product.query.get(purchase.product_id) message = "transactie met ID " + "{} ({}x {} voor {})".format( str(transaction.id), str(round_up(purchase.amount)), product.name, u.name) + " wilt verwijderen?" else: upgr = Upgrade.query.get(transaction.upgrade_id) message = "transactie met ID " + "{} ({} € {} voor {})".format( str(transaction.id), upgr.description, round_up(upgr.amount), u.name) + " wilt verwijderen?" agree_url = url_for("admin_transactions_delete_exec", tranid=tranid) return_url = url_for("admin_transactions") return render_template("verify.html", title="Bevestigen", message=message, agree_url=agree_url, return_url=return_url), 200
def upcoming_birthdays(): today = datetime.today() birthday_groups = json.loads(settings['birthday_groups']) days_in_year = 365.2425 birthdays = [] for u in User.query.all(): if u.usergroup_id in birthday_groups: bday = datetime(today.year, u.birthday.month, u.birthday.day) new_age = int(round_up((today - u.birthday).days / days_in_year, 0)) if bday < today: bday = datetime(today.year + 1, u.birthday.month, u.birthday.day) diff = (bday - today).days + 1 birthdays.append({'user': u.name, 'birthday': bday, 'age': new_age, 'days': diff}) return sorted(birthdays, key=lambda i: i['birthday'])
def calculate_pagination_with_basequery(query, request_obj): # If no page id is provided... if request_obj.args.get('page') is None: # We set it to 1 page = 1 else: # Otherwise, we get it from the parameters and transform it into an integer page = int(request_obj.args.get('page')) # Get the total amount of rows for this table total_amount_of_entries = query.count() # Calculate the total amount of pages total_amount_of_pages = int(round_up(total_amount_of_entries / page_size, 0)) # Calculate the offset in number of rows in a page offset_difference = total_amount_of_entries % page_size # Calculate the offset in number of pages offset = max(0, total_amount_of_pages - page) # Calculate the real offset in number of rows real_offset = offset * page_size - (page_size - offset_difference) # The offset cannot be negative, so if this is the case, we need to decrease the page size if real_offset < 0: real_page_size = page_size + real_offset real_offset = 0 # If the offset is not negative, we simply copy the page size else: real_page_size = page_size # Create the data object that contains all necessary information pagination = {'pages': total_amount_of_pages, 'currentPage': page, 'minPage': max(1, int(page - pagination_range)), 'maxPage': min(total_amount_of_pages, page + pagination_range), 'offset': real_offset, 'pageSize': real_page_size, 'records': '{} ... {} van de {}'.format(page_size * (page - 1) + 1, page_size * (page - 1) + real_page_size, total_amount_of_entries), } # Return this object return pagination
def set_borrel_mode(products, user_id, amount): global borrel_mode_drinks, borrel_mode_enabled # The products variable is a list of strings, so we convert each string to an integer and add it to the list borrel_mode_drinks = [] for p in products: borrel_mode_drinks.append(int(p)) total_bought = 0 # We count the total amount of borrel mode products bought (also before the borrel started) for p1 in products: for p in Purchase.query.filter(Purchase.user_id == user_id, Purchase.product_id == p1, Purchase.price > 0).all(): total_bought += p.amount total_bought = round_up(total_bought) # Update the database update_settings('borrel_mode_start_amount', str(total_bought)) update_settings('borrel_mode_amount', str(amount)) update_settings('borrel_mode_user', str(user_id)) update_settings('borrel_mode_drinks', str(borrel_mode_drinks)) borrel_mode_enabled = True
def purchase_dinner(cart, total_costs, comments): # Parse the raw cart string into something readable parsed_cart = parse_cart_string(cart, -1) # Get the dinner ID dinner_id = dbhandler.settings['dinner_product_id'] # If the dinner ID is None, return an error, as we should not have entered this method if dinner_id is None: raise ValueError("Dinner ID is None") # Get the product object product = Product.query.get(dinner_id) # Determine the price for one dinner price_pp = round_up(float(total_costs) / parsed_cart['total_bought']) # Add this to the inventory, so it can remain zero after purchasing dbhandler.add_inventory(dinner_id, parsed_cart['total_bought'], price_pp, comments) # Create the purchases for every order success_messages = create_purchases(parsed_cart['orders'], product, False, price_pp) # Create the final alert for both Tikker and Tikker BigScreen create_and_send_final_flash(success_messages) # Update the stats on BigScreen socket.update_stats()
def addpurchase(drink_id, user_id, quantity, rondje, price_per_one): # Round quantity to at most two decimals quantity = round_up(quantity) # Get drink and user objects from database drink = Product.query.get(drink_id) user = User.query.get(user_id) # If the price is zero, we do not have to take any inventory if price_per_one > 0: # If we product is not a mix, we can simply take it from inventory if drink.recipe_input is None: inventory = take_from_inventory(user, drink_id, quantity) # However, if the product is a mix... else: inventory = {'costs': 0, 'inventory_usage': []} # For every ingredient of the mix... for r in Recipe.query.filter(Recipe.product_id == drink.id).all(): # Take the respective quantity from inventory result = take_from_inventory(user, r.ingredient_id, round_up(r.quantity * quantity)) # Add the costs of the ingredient to the total costs inventory['costs'] = inventory['costs'] + result['costs'] # Add the inventory usage inventory['inventory_usage'] = inventory['inventory_usage'] + result['inventory_usage'] else: # We take no inventory if the price is zero, so the costs are zero inventory = {'costs': 0, 'inventory_usage': []} # Get the profitgroup of the user profitgroup = Usergroup.query.get(user.profitgroup_id) # Calculate the profit prof = round_down((price_per_one * quantity - inventory['costs']) * app.config['PROFIT_PERCENTAGE']) # Add the profit to the group profitgroup.profit = profitgroup.profit + prof # Create a row object for the profit table profit_obj = Profit(profitgroup_id=profitgroup.id, timestamp=datetime.now(), percentage=app.config['PROFIT_PERCENTAGE'], change=prof, new=profitgroup.profit) db.session.add(profit_obj) # Save to database db.session.commit() # Calculate the new user balance user.balance = user.balance - round_up(float(price_per_one) * quantity) # Create a purchase entry in the table, so we can use its purchase ID to create the transaction purchase = Purchase(user_id=user.id, timestamp=datetime.now(), product_id=drink.id, price=price_per_one, amount=quantity, round=rondje) db.session.add(purchase) db.session.commit() # Create all inventory usage entries for x in inventory['inventory_usage']: i_u = Inventory_usage(purchase_id=purchase.id, inventory_id=x['id'], quantity=x['quantity']) db.session.add(i_u) db.session.commit() # Set the object to None to clean up after creation i_u = None # Calculate the change in balance balchange = round_down(-price_per_one * quantity) # Create a transaction entry and add it to the database transaction = Transaction(user_id=user.id, timestamp=datetime.now(), purchase_id=purchase.id, profit_id=profit_obj.id, balchange=balchange, newbal=user.balance) db.session.add(transaction) db.session.commit() # Update the daily stats with the new purchase statshandler.update_daily_stats('euros', balchange) statshandler.update_daily_stats_purchase(user_id, drink_id, quantity, rondje, price_per_one) return quantity, drink.name, user.name, "success"
def correct_inventory(json): # Create a list of all groups that will participate in this inventory correction all_groups = set() for i in json: s = set(i['groups']) all_groups.update(s) all_groups = list(all_groups) per_group_costs = [0] * len(all_groups) total_costs = 0 # Create a document for the overview of this correction now = datetime.now() document = Document() document.add_heading('Inventaris Correctie', 0) document.add_paragraph("Op {} om {} is er een inventariscorrectie uitgevoerd. Hierbij zijn de volgende wijzigingen " "doorgevoerd in de inventaris.".format(now.strftime("%Y-%m-%d"), now.strftime("%H:%M:%S"))) # Table layout: Product name | Inventory in Tikker | Real inventory | Difference | Costs | <per group its costs or # profit table = document.add_table(rows=1, cols=5 + len(all_groups)) header_cells = table.rows[0].cells header_cells[0].text = "Productnaam" header_cells[1].text = "Inv in Tikker" header_cells[2].text = "Echte inv" header_cells[3].text = "Verschil" header_cells[4].text = "Kosten" for i in range(0, len(all_groups)): header_cells[5 + i].text = "Kosten {}".format(Usergroup.query.get(all_groups[i]).name) for i in json: # Get the product object p = Product.query.get(i['product_id']) # Calculate the inventory difference tikker_inv = calcStock(p.id) diff = int(i['stock']) - int(tikker_inv) # Create a new row for the document table row_cells = table.add_row().cells row_cells[0].text = p.name row_cells[1].text = str(tikker_inv) row_cells[2].text = str(i['stock']) row_cells[3].text = str(diff) if diff < 0: row_cells[4].text = '-€ %.2f' % round_up(-diff * p.price) total_costs += round_up(-diff * p.price) elif diff > 0: row_cells[4].text = '€ %.2f' % round_down(diff * p.price) total_costs += round_down(diff * p.price) # If the difference is less than 0, we have lost some inventory, which costs money if diff < 0: take_from_inventory(None, p.id, -diff) for g_id in i['groups']: # Get the group object g = Usergroup.query.get(g_id) # Calculate the costs for this group cost = round_down(diff * p.price / len(i['groups'])) # Change its profit g.profit = g.profit + cost profit = Profit(profitgroup_id=g_id, timestamp=datetime.now(), percentage=1.0, change=cost, new=g.profit, description="{} {} inventariscorrectie".format(str(diff), p.name)) db.session.add(profit) db.session.commit() # Now, take it from inventory # Add it to the row in the table and to the cumulative costs index = all_groups.index(g_id) per_group_costs[index] += cost row_cells[5 + index].text = '-€ %.2f' % -cost # Reset the group object g = None elif diff > 0: new_price = find_newest_product_price(p.id) add_inventory(p.id, diff, new_price, "Inventariscorrectie") for g_id in i['groups']: g = Usergroup.query.get(g_id) profit_for_group = round_down(diff * new_price / len(i['groups'])) g.profit = g.profit + profit_for_group profit = Profit(profitgroup_id=g_id, timestamp=datetime.now(), percentage=1.0, change=profit_for_group, new=g.profit, description="{} {} inventariscorrectie".format(str(diff), p.name)) db.session.add(profit) db.session.commit() # Add it to the row in the table and to the cumulative costs index = all_groups.index(g_id) per_group_costs[index] += profit_for_group row_cells[5 + index].text = '€ %.2f' % profit_for_group # Reset the group object g = None row_cells = table.add_row().cells if total_costs < 0: row_cells[4].text = '-€ %.2f' % -total_costs else: row_cells[4].text = '€ %.2f' % total_costs for i in range(0, len(per_group_costs)): if per_group_costs[i] < 0: row_cells[5 + i].text = '-€ %.2f' % -per_group_costs[i] else: row_cells[5 + i].text = '€ %.2f' % per_group_costs[i] # Try to save the file # If it is not possible because the file is locked, try it again with a different filename until it works count = 0 while True: filename = os.path.join(app.config['DOCUMENT_FOLDER'], 'inventariscorrectie_{}_{}.docx' .format(now.strftime("%Y%m%d"), count)) # If the file exists, raise the file name and try again if os.path.exists(filename): count += 1 continue try: # If saving the file is successful, escape the loop and finish document.save(filename) break # If the file is opened, catch the error and try again except PermissionError: count += 1 return "Inventaris correctie succesvol doorgevoerd! Het rapport is opgeslagen in {}".format(filename), "success"