Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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'])
Example #5
0
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
Example #6
0
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
Example #7
0
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()
Example #8
0
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"
Example #9
0
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"