grocy-cli/grocy/table.py

210 lines
9.3 KiB
Python
Raw Normal View History

2019-06-16 23:54:10 -05:00
from grocy.entity import Entity
import re
from grocy.conf import Configuration
import logging
2019-06-16 23:54:10 -05:00
from tabulate import tabulate
class Table(object):
NOT_ENOUGH_IN_STOCK_MSG = '{glyph} Not enough in stock, {missing_amount} ingredient{s} missing'
ENOUGH_IN_STOCK_MSG = '{glyph} Enough in stock'
NOT_ENOUGH_BUT_IN_SHOPPING_LIST_MSG = '{not_enough}, but already on list'.format(not_enough=NOT_ENOUGH_IN_STOCK_MSG)
def __init__(self, **entries):
self.__dict__.update(entries)
self.conf = Configuration()
self.conf.load()
@property
def product(self):
if not self.entry:
raise Exception('Missing product')
loaded_template = self.conf.templates('product/view')
return loaded_template.render(self.entry)
@property
def products(self):
if not self.entries:
raise Exception('Missing entries')
product_groups_map = {product_group['id']: product_group['name']
for product_group in self.entries['product_groups']}
location_map = {location['id']: location['name']
for location in self.entries['locations']}
quantity_unit_map = {quantity_unit['id']: quantity_unit['name']
for quantity_unit in self.entries['quantity_units']}
table_entries = []
try:
for entry in self.entries['products']:
table_entry = []
product_group_name = 'N/A' if entry['product_group_id'] == '' else product_groups_map[entry['product_group_id']]
mini_stock_amount = entry['mini_stock_amount'] if 'mini_stock_amount' in entry else 'N/A'
qu_factor_purchase_to_stock = entry['qu_factor_purchase_to_stock'] if 'qu_factor_purchase_to_stock' in entry else 'N/A'
location_name = location_map[entry['location_id']] if 'location_id' in entry else 'N/A'
quantity_unit_purchase_name = quantity_unit_map[entry['qu_id_purchase']] if 'qu_id_purchase' in entry else 'N/A'
quantity_unit_stock_name = quantity_unit_map[entry['qu_id_stock']] if 'qu_id_stock' in entry else 'N/A'
table_entry.append(entry['id'])
table_entry.append(entry['name'])
table_entry.append(location_name)
table_entry.append(quantity_unit_purchase_name)
table_entry.append(quantity_unit_stock_name)
table_entry.append(product_group_name)
table_entry.append(mini_stock_amount)
table_entry.append(quantity_unit_stock_name)
table_entries.append(table_entry)
table_headers = ['ID', 'Name', 'Location', 'Min\nStock Amount',
'QU\nPurchase', 'QU\nStock', 'QU\nFactor', 'Product\nGroup']
return tabulate(table_entries, headers=table_headers)
except Exception as e:
raise e
2019-06-16 23:54:10 -05:00
@property
def stock(self):
logger = logging.getLogger('table.stock')
entity = Entity(name='products')
products = entity.get()
products_map = {product['id']: product for product in products}
try:
# Get product names from ids and replace
table_entries = []
try:
for item in self.stocks:
product = products_map[item['product_id']]
item['product_id'] = product['name']
table_entry = list(dict.values(item))
table_entries.append(table_entry)
except Exception as e:
logger.error(e)
raise e
# Generate stock overview table
table_headers = ['Product', 'Amount', 'Best Before Date', 'Amount Opened']
return tabulate(table_entries, headers=table_headers)
except Exception as e:
logger.error(e)
raise e
@property
def recipe(self):
checkmark_glyph = ''
times_glyph = ''
exclamation_glyph = ''
logger = logging.getLogger('table.recipe')
normal_recipes = [recipe for recipe in self.recipes if re.search(r'^normal', recipe['type'])]
recipes_req_map = {recipe_reqs['recipe_id']: recipe_reqs for recipe_reqs in self.recipes_reqs}
try:
table_entries = []
try:
for item in normal_recipes:
table_entry = []
table_entry.append(item['id'])
table_entry.append(item['name'])
table_entry.append(item['base_servings'])
recipe_reqs = recipes_req_map[item['id']]
missing_amount = int(recipe_reqs['missing_products_count'])
number_of_ingredients = 's' if missing_amount > 1 else ''
if recipe_reqs['need_fulfilled'] == '1':
table_entry.append(self.ENOUGH_IN_STOCK_MSG.format(glyph=checkmark_glyph))
elif recipe_reqs['need_fulfilled_with_shopping_list'] == '1':
missing_amount = recipe_reqs['missing_products_count']
table_entry.append(self.NOT_ENOUGH_BUT_IN_SHOPPING_LIST_MSG.format(glyph=exclamation_glyph,
missing_amount=missing_amount, s=number_of_ingredients))
else:
table_entry.append(self.NOT_ENOUGH_IN_STOCK_MSG.format(glyph=times_glyph,
missing_amount=missing_amount, s=number_of_ingredients))
table_entries.append(table_entry)
except Exception as e:
logger.error(e)
raise e
# Generate recipes overview table
table_headers = ['Id', 'Name', 'Servings', 'Requirements Fulfilled']
return tabulate(table_entries, headers=table_headers)
except Exception as e:
logger.error(e)
raise e
@property
def recipes(self):
checkmark_glyph = ''
times_glyph = ''
exclamation_glyph = ''
logger = logging.getLogger('table.recipe')
2019-06-16 23:54:10 -05:00
normal_recipes = [recipe for recipe in self.recipes if re.search(r'^normal', recipe['type'])]
recipes_req_map = {recipe_reqs['recipe_id']: recipe_reqs for recipe_reqs in self.recipes_reqs}
try:
table_entries = []
try:
for item in normal_recipes:
table_entry = []
table_entry.append(item['id'])
table_entry.append(item['name'])
table_entry.append(item['base_servings'])
recipe_reqs = recipes_req_map[item['id']]
missing_amount = int(recipe_reqs['missing_products_count'])
number_of_ingredients = 's' if missing_amount > 1 else ''
if recipe_reqs['need_fulfilled'] == '1':
table_entry.append(self.ENOUGH_IN_STOCK_MSG.format(glyph=checkmark_glyph))
elif recipe_reqs['need_fulfilled_with_shopping_list'] == '1':
missing_amount = recipe_reqs['missing_products_count']
table_entry.append(self.NOT_ENOUGH_BUT_IN_SHOPPING_LIST_MSG.format(glyph=exclamation_glyph,
missing_amount=missing_amount, s=number_of_ingredients))
else:
table_entry.append(self.NOT_ENOUGH_IN_STOCK_MSG.format(glyph=times_glyph,
missing_amount=missing_amount, s=number_of_ingredients))
table_entries.append(table_entry)
except Exception as e:
logger.error(e)
raise e
# Generate recipes overview table
table_headers = ['Id', 'Name', 'Servings', 'Requirements Fulfilled']
return tabulate(table_entries, headers=table_headers)
except Exception as e:
logger.error(e)
raise e
@property
def shopping_list(self):
logger = logging.getLogger('table.shopping_list')
try:
table_headers = ['Group', 'Product', 'Amount']
# Get product names and location from ids and replace
product_ids = [entry['product_id'] for entry in self.shopping_list]
products = []
location_ids = []
table_entries = []
for index in range(len(product_ids)):
product_id = product_ids[index]
entity = Entity(name='products')
product = entity.get(id=product_id)
entity = Entity(name='quantity_units')
quantity_unit = entity.get(product['qu_id_purchase'])
min_amount = '{} {}'.format(product['min_stock_amount'], quantity_unit['name'])
if product['product_group_id'] == '':
product_group_name = 'Uncategorized'
else:
entity = Entity(name='product_groups')
product_group = product.get(id=product['product_group_id'])
product_group_name = product_group['name']
shopping_item = [product_group_name, product['name'], min_amount]
table_entries.append(shopping_item)
except Exception as e:
logger.error(e)
raise e
# Generate stock overview table
return tabulate(table_entries, headers=table_headers)