diff --git a/custom_components/shopping_list_manager/__init__.py b/custom_components/shopping_list_manager/__init__.py index 56cbb4d..3e583ac 100644 --- a/custom_components/shopping_list_manager/__init__.py +++ b/custom_components/shopping_list_manager/__init__.py @@ -1,56 +1,195 @@ -""" -Shopping List Manager - Home Assistant Custom Integration -Clean-slate architecture with enforced invariants -""" +"""Shopping List Manager integration for Home Assistant.""" import logging +import os + from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.components import websocket_api as ha_websocket -from .websocket_api import websocket_create_list - +from homeassistant.helpers.typing import ConfigType from .const import DOMAIN -from .manager import ShoppingListManager -# Import websocket handler functions directly -from .websocket_api import ( - websocket_add_product, - websocket_set_qty, - websocket_get_products, - websocket_get_active, - websocket_delete_product, - ws_get_catalogues, - ws_get_lists, -) +from .storage import ShoppingListStorage +from .utils.images import ImageHandler _LOGGER = logging.getLogger(__name__) +# Track storage instance globally +DATA_STORAGE = f"{DOMAIN}_storage" + +async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: + """Set up the Shopping List Manager component from yaml (not used).""" + # This integration doesn't support YAML configuration + # All setup is done via config entries (UI configuration) + return True + + +# In async_setup_entry function, after storage initialization: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Shopping List Manager from a config entry.""" - # Initialize the manager - manager = ShoppingListManager(hass) - await manager.async_load() + _LOGGER.info("Setting up Shopping List Manager") - # Store manager in hass.data + # Get component path for loading data files + component_path = os.path.dirname(__file__) + config_path = hass.config.path() + + # Get country from options (or fall back to data, or default to NZ) + country = entry.options.get("country") or entry.data.get("country", "NZ") + _LOGGER.info("Using country: %s", country) + + # Initialize storage with country + storage = ShoppingListStorage(hass, component_path, country) + await storage.async_load() + + # Initialize image handler + image_handler = ImageHandler(hass, config_path) + + # Store instances in hass.data hass.data.setdefault(DOMAIN, {}) - hass.data[DOMAIN]["manager"] = manager + hass.data[DOMAIN][DATA_STORAGE] = storage + hass.data[DOMAIN]["image_handler"] = image_handler + hass.data[DOMAIN]["country"] = country - # Register WebSocket commands using Home Assistant's websocket_api - ha_websocket.async_register_command(hass, websocket_create_list) - ha_websocket.async_register_command(hass, websocket_add_product) - ha_websocket.async_register_command(hass, websocket_set_qty) - ha_websocket.async_register_command(hass, websocket_get_products) - ha_websocket.async_register_command(hass, websocket_get_active) - ha_websocket.async_register_command(hass, websocket_delete_product) - ha_websocket.async_register_command(hass, ws_get_catalogues) - ha_websocket.async_register_command(hass, ws_get_lists) + # Register update listener for options changes + entry.async_on_unload(entry.add_update_listener(update_listener)) - _LOGGER.info("Shopping List Manager setup complete - registered 7 WebSocket commands") + # Register WebSocket commands + await _async_register_websocket_handlers(hass, storage) + # Register frontend resources + await _async_register_frontend(hass) + + _LOGGER.info("Shopping List Manager setup complete") return True +async def update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: + """Handle options update.""" + # Reload the integration when options change + await hass.config_entries.async_reload(entry.entry_id) + + async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: - """Unload Shopping List Manager.""" - hass.data[DOMAIN].pop("manager", None) + """Unload a config entry.""" + _LOGGER.info("Unloading Shopping List Manager") + + # Clean up hass.data + if DOMAIN in hass.data: + hass.data[DOMAIN].pop(DATA_STORAGE, None) + return True + + +async def _async_register_websocket_handlers( + hass: HomeAssistant, + storage: ShoppingListStorage +) -> None: + """Register WebSocket API handlers.""" + from homeassistant.components import websocket_api + from .websocket import handlers + + # Lists handlers + websocket_api.async_register_command( + hass, + handlers.websocket_get_lists, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_create_list, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_update_list, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_delete_list, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_set_active_list, + ) + + # Items handlers + websocket_api.async_register_command( + hass, + handlers.websocket_get_items, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_add_item, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_update_item, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_check_item, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_delete_item, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_reorder_items, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_bulk_check_items, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_clear_checked_items, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_get_list_total, + ) + + # Products handlers + websocket_api.async_register_command( + hass, + handlers.websocket_search_products, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_get_product_suggestions, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_add_product, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_update_product, + ) + websocket_api.async_register_command( + hass, + handlers.websocket_get_product_substitutes, + ) + + # Categories handlers + websocket_api.async_register_command( + hass, + handlers.websocket_get_categories, + ) + + _LOGGER.debug("WebSocket handlers registered") + + +async def _async_register_frontend(hass: HomeAssistant) -> None: + """Register frontend resources.""" + # Since frontend is a separate HACS module, we don't need to register it here + # The frontend card registers itself independently + _LOGGER.debug("Frontend resources skipped (separate HACS module)") + + _LOGGER.debug("Frontend resources registered") + + +def get_storage(hass: HomeAssistant) -> ShoppingListStorage: + """Get the storage instance from hass.data. + + Helper function for WebSocket handlers to access storage. + """ + return hass.data[DOMAIN][DATA_STORAGE] diff --git a/custom_components/shopping_list_manager/config_flow.py b/custom_components/shopping_list_manager/config_flow.py index 8492172..3d21b57 100644 --- a/custom_components/shopping_list_manager/config_flow.py +++ b/custom_components/shopping_list_manager/config_flow.py @@ -1,5 +1,7 @@ """Config flow for Shopping List Manager.""" +import voluptuous as vol from homeassistant import config_entries +from homeassistant.core import callback from .const import DOMAIN @@ -16,10 +18,76 @@ class ShoppingListManagerConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): return self.async_abort(reason="single_instance_allowed") if user_input is not None: + # Create entry with default country return self.async_create_entry( title="Shopping List Manager", - data={} + data={"country": "NZ"}, + options={ + "country": "NZ", + "enable_price_tracking": True, + "enable_image_search": True, + "metric_units_only": True, + } ) - # Show simple form - return self.async_show_form(step_id="user") \ No newline at end of file + # Show simple setup form + return self.async_show_form( + step_id="user", + description_placeholders={ + "info": "Country and other settings can be configured after setup via the Configure button." + } + ) + + @staticmethod + @callback + def async_get_options_flow(config_entry): + """Get the options flow for this handler.""" + return OptionsFlowHandler(config_entry) + + +class OptionsFlowHandler(config_entries.OptionsFlow): + """Handle options flow for Shopping List Manager.""" + + def __init__(self, config_entry): + """Initialize options flow.""" + self.config_entry = config_entry + + async def async_step_init(self, user_input=None): + """Manage the options.""" + if user_input is not None: + # Update options + return self.async_create_entry(title="", data=user_input) + + # Get current settings + current_country = self.config_entry.options.get( + "country", + self.config_entry.data.get("country", "NZ") + ) + + return self.async_show_form( + step_id="init", + data_schema=vol.Schema({ + vol.Required("country", default=current_country): vol.In({ + "NZ": "New Zealand", + "AU": "Australia", + "US": "United States", + "GB": "United Kingdom", + "CA": "Canada", + }), + vol.Optional( + "enable_price_tracking", + default=self.config_entry.options.get("enable_price_tracking", True) + ): bool, + vol.Optional( + "enable_image_search", + default=self.config_entry.options.get("enable_image_search", True) + ): bool, + vol.Optional( + "metric_units_only", + default=self.config_entry.options.get("metric_units_only", True) + ): bool, + }), + description_placeholders={ + "info": "Changing country will reload the product catalog on next restart." + } + ) diff --git a/custom_components/shopping_list_manager/const.py b/custom_components/shopping_list_manager/const.py index bdb838e..29b4d3f 100644 --- a/custom_components/shopping_list_manager/const.py +++ b/custom_components/shopping_list_manager/const.py @@ -1,12 +1,119 @@ """Constants for Shopping List Manager.""" +# Domain DOMAIN = "shopping_list_manager" -# Storage keys -STORAGE_VERSION = 1 +# Storage Keys +STORAGE_VERSION = 2 +STORAGE_KEY_LISTS = f"{DOMAIN}.lists" +STORAGE_KEY_ITEMS = f"{DOMAIN}.items" STORAGE_KEY_PRODUCTS = f"{DOMAIN}.products" -STORAGE_KEY_ACTIVE = f"{DOMAIN}.active_list" -LISTS_STORE_KEY = "shopping_list_manager.lists" +STORAGE_KEY_CATEGORIES = f"{DOMAIN}.categories" + +# WebSocket Commands - Lists +WS_TYPE_LISTS_GET_ALL = f"{DOMAIN}/lists/get_all" +WS_TYPE_LISTS_CREATE = f"{DOMAIN}/lists/create" +WS_TYPE_LISTS_UPDATE = f"{DOMAIN}/lists/update" +WS_TYPE_LISTS_DELETE = f"{DOMAIN}/lists/delete" +WS_TYPE_LISTS_SET_ACTIVE = f"{DOMAIN}/lists/set_active" + +# WebSocket Commands - Items +WS_TYPE_ITEMS_GET = f"{DOMAIN}/items/get" +WS_TYPE_ITEMS_ADD = f"{DOMAIN}/items/add" +WS_TYPE_ITEMS_UPDATE = f"{DOMAIN}/items/update" +WS_TYPE_ITEMS_CHECK = f"{DOMAIN}/items/check" +WS_TYPE_ITEMS_DELETE = f"{DOMAIN}/items/delete" +WS_TYPE_ITEMS_REORDER = f"{DOMAIN}/items/reorder" +WS_TYPE_ITEMS_BULK_CHECK = f"{DOMAIN}/items/bulk_check" +WS_TYPE_ITEMS_CLEAR_CHECKED = f"{DOMAIN}/items/clear_checked" +WS_TYPE_ITEMS_GET_TOTAL = f"{DOMAIN}/items/get_total" + +# WebSocket Commands - Products +WS_TYPE_PRODUCTS_SEARCH = f"{DOMAIN}/products/search" +WS_TYPE_PRODUCTS_SUGGESTIONS = f"{DOMAIN}/products/suggestions" +WS_TYPE_PRODUCTS_ADD = f"{DOMAIN}/products/add" +WS_TYPE_PRODUCTS_UPDATE = f"{DOMAIN}/products/update" +WS_TYPE_PRODUCTS_DELETE = f"{DOMAIN}/products/delete" + +# WebSocket Commands - Categories +WS_TYPE_CATEGORIES_GET_ALL = f"{DOMAIN}/categories/get_all" +WS_TYPE_CATEGORIES_REORDER = f"{DOMAIN}/categories/reorder" + +# WebSocket Commands - Subscriptions +WS_TYPE_SUBSCRIBE = f"{DOMAIN}/subscribe" +WS_TYPE_UNSUBSCRIBE = f"{DOMAIN}/unsubscribe" + +# WebSocket Commands - Barcode (Phase 5) +WS_TYPE_BARCODE_SCAN = f"{DOMAIN}/barcode/scan" +WS_TYPE_BARCODE_ADD = f"{DOMAIN}/barcode/add_to_list" + +# WebSocket Commands - OpenFoodFacts (Phase 5) +WS_TYPE_OFF_FETCH = f"{DOMAIN}/openfoodfacts/fetch" +WS_TYPE_OFF_IMPORT = f"{DOMAIN}/openfoodfacts/import" # Events -EVENT_SHOPPING_LIST_UPDATED = f"{DOMAIN}_updated" +EVENT_ITEM_ADDED = f"{DOMAIN}_item_added" +EVENT_ITEM_UPDATED = f"{DOMAIN}_item_updated" +EVENT_ITEM_CHECKED = f"{DOMAIN}_item_checked" +EVENT_ITEM_DELETED = f"{DOMAIN}_item_deleted" +EVENT_LIST_UPDATED = f"{DOMAIN}_list_updated" +EVENT_LIST_DELETED = f"{DOMAIN}_list_deleted" + +# Image Configuration +IMAGE_FORMAT = "webp" +IMAGE_SIZE = 200 # 200x200px +IMAGE_QUALITY = 85 +IMAGE_MAX_SIZE_KB = 15 +IMAGES_LOCAL_DIR = "www/shopping_list_manager/images" + +# Placeholder image (inline SVG) +PLACEHOLDER_IMAGE = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Crect width='200' height='200' fill='%23f0f0f0'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' font-family='Arial' font-size='16' fill='%23999'%3ENo Image%3C/text%3E%3C/svg%3E" + +# Metric Units (always metric, regardless of country) +METRIC_UNITS = { + "weight": ["kg", "g"], + "volume": ["L", "mL"], + "count": ["units", "pack", "loaf", "dozen", "ea", "pkt", "tray", "bottle", "can", "bunch", "pottle", "roll", "sachet", "tub", "bar"] +} + +# Default quantities for common products (NZ-focused, can be country-specific later) +DEFAULT_QUANTITIES = { + "milk": {"quantity": 2, "unit": "L"}, + "bread": {"quantity": 1, "unit": "loaf"}, + "butter": {"quantity": 500, "unit": "g"}, + "eggs": {"quantity": 12, "unit": "ea"}, + "cheese": {"quantity": 500, "unit": "g"}, + "yogurt": {"quantity": 1, "unit": "kg"}, + "flour": {"quantity": 1.5, "unit": "kg"}, + "sugar": {"quantity": 1.5, "unit": "kg"}, + "rice": {"quantity": 1, "unit": "kg"}, + "pasta": {"quantity": 500, "unit": "g"}, + "chicken breast": {"quantity": 1, "unit": "kg"}, + "beef mince": {"quantity": 500, "unit": "g"}, + "sausages": {"quantity": 500, "unit": "g"}, + "bacon": {"quantity": 500, "unit": "g"}, + "apples": {"quantity": 1, "unit": "kg"}, + "bananas": {"quantity": 1, "unit": "kg"}, + "potatoes": {"quantity": 2, "unit": "kg"}, + "onions": {"quantity": 1, "unit": "kg"}, + "carrots": {"quantity": 1, "unit": "kg"}, + "tomatoes": {"quantity": 500, "unit": "g"}, + "lettuce": {"quantity": 1, "unit": "ea"}, + "capsicum": {"quantity": 1, "unit": "ea"}, + "broccoli": {"quantity": 1, "unit": "ea"}, + "cereal": {"quantity": 1, "unit": "pack"}, + "baked beans": {"quantity": 1, "unit": "can"}, + "tuna": {"quantity": 1, "unit": "can"}, + "olive oil": {"quantity": 1, "unit": "L"}, + "coffee": {"quantity": 200, "unit": "g"}, + "tea bags": {"quantity": 100, "unit": "ea"}, + "toilet paper": {"quantity": 12, "unit": "roll"}, + "paper towels": {"quantity": 2, "unit": "roll"}, + "dishwashing liquid": {"quantity": 500, "unit": "mL"}, + "laundry powder": {"quantity": 2, "unit": "kg"} +} + +# Paths +CATEGORIES_FILE = "categories.json" +PRODUCTS_CATALOG_FILE = "products_catalog.json" +IMAGES_PATH = "images/products" diff --git a/custom_components/shopping_list_manager/data/catalog_loader.py b/custom_components/shopping_list_manager/data/catalog_loader.py new file mode 100644 index 0000000..a79719d --- /dev/null +++ b/custom_components/shopping_list_manager/data/catalog_loader.py @@ -0,0 +1,62 @@ +"""Product catalog loader for Shopping List Manager.""" +import json +import logging +from typing import List, Dict, Any +import aiofiles + +_LOGGER = logging.getLogger(__name__) + + +async def load_product_catalog(component_path: str, country_code: str = "NZ") -> List[Dict[str, Any]]: + """Load product catalog from JSON file asynchronously. + + Args: + component_path: Path to the component directory + country_code: Country code (e.g., 'NZ', 'AU', 'US') + + Returns: + List of product dictionaries + """ + import os + + # Try country-specific catalog first + if country_code: + catalog_file = os.path.join( + component_path, "data", f"products_catalog_{country_code.lower()}.json" + ) + if not os.path.exists(catalog_file): + _LOGGER.warning( + "No country-specific catalog found for %s at %s", + country_code, + catalog_file + ) + return [] + else: + return [] + + try: + # Use aiofiles for async file reading + async with aiofiles.open(catalog_file, "r", encoding="utf-8") as f: + content = await f.read() + data = json.loads(content) + + _LOGGER.info( + "Loaded product catalog version %s for region %s", + data.get("version", "unknown"), + data.get("region", "default") + ) + + products = data.get("products", []) + _LOGGER.info("Loaded %d products from catalog", len(products)) + + return products + + except FileNotFoundError: + _LOGGER.error("Product catalog file not found: %s", catalog_file) + return [] + except json.JSONDecodeError as err: + _LOGGER.error("Failed to parse product catalog file: %s", err) + return [] + except Exception as err: + _LOGGER.error("Unexpected error loading product catalog: %s", err) + return [] diff --git a/custom_components/shopping_list_manager/data/categories.json b/custom_components/shopping_list_manager/data/categories.json new file mode 100644 index 0000000..1a712f8 --- /dev/null +++ b/custom_components/shopping_list_manager/data/categories.json @@ -0,0 +1,110 @@ +{ + "version": "1.0.0", + "region": "NZ", + "categories": [ + { + "id": "produce", + "name": "Fruit & Veg", + "icon": "mdi:fruit-cherries", + "color": "#4CAF50", + "sort_order": 1, + "system": true + }, + { + "id": "dairy", + "name": "Dairy & Eggs", + "icon": "mdi:cheese", + "color": "#FFC107", + "sort_order": 2, + "system": true + }, + { + "id": "meat", + "name": "Meat & Seafood", + "icon": "mdi:food-steak", + "color": "#F44336", + "sort_order": 3, + "system": true + }, + { + "id": "bakery", + "name": "Bakery", + "icon": "mdi:bread-slice", + "color": "#FF9800", + "sort_order": 4, + "system": true + }, + { + "id": "frozen", + "name": "Frozen Foods", + "icon": "mdi:snowflake", + "color": "#2196F3", + "sort_order": 5, + "system": true + }, + { + "id": "pantry", + "name": "Pantry", + "icon": "mdi:package-variant", + "color": "#795548", + "sort_order": 6, + "system": true + }, + { + "id": "beverages", + "name": "Drinks", + "icon": "mdi:cup", + "color": "#00BCD4", + "sort_order": 7, + "system": true + }, + { + "id": "snacks", + "name": "Snacks & Biscuits", + "icon": "mdi:food-apple", + "color": "#E91E63", + "sort_order": 8, + "system": true + }, + { + "id": "household", + "name": "Household", + "icon": "mdi:spray-bottle", + "color": "#9C27B0", + "sort_order": 9, + "system": true + }, + { + "id": "health", + "name": "Health & Beauty", + "icon": "mdi:heart-pulse", + "color": "#E91E63", + "sort_order": 10, + "system": true + }, + { + "id": "pet", + "name": "Pet Supplies", + "icon": "mdi:paw", + "color": "#FF5722", + "sort_order": 11, + "system": true + }, + { + "id": "baby", + "name": "Baby", + "icon": "mdi:baby-face", + "color": "#FFEB3B", + "sort_order": 12, + "system": true + }, + { + "id": "other", + "name": "Other", + "icon": "mdi:dots-horizontal", + "color": "#9E9E9E", + "sort_order": 99, + "system": true + } + ] +} \ No newline at end of file diff --git a/custom_components/shopping_list_manager/data/category_loader.py b/custom_components/shopping_list_manager/data/category_loader.py new file mode 100644 index 0000000..ac4f0f5 --- /dev/null +++ b/custom_components/shopping_list_manager/data/category_loader.py @@ -0,0 +1,98 @@ +"""Category loader utility.""" +import json +import logging +import os +from typing import List, Dict, Any +import aiofiles + +_LOGGER = logging.getLogger(__name__) + + +async def load_categories(component_path: str, country_code: str = None) -> List[Dict[str, Any]]: + """Load categories from JSON file asynchronously. + + Args: + component_path: Path to the component directory + country_code: Country code from HA config (e.g., 'NZ', 'AU', 'US') + If None, loads default categories.json + + Returns: + List of category dictionaries + """ + import os + + # Try country-specific file first if country_code provided + if country_code: + country_file = os.path.join( + component_path, "data", f"categories_{country_code.lower()}.json" + ) + if os.path.exists(country_file): + categories_file = country_file + _LOGGER.debug("Using country-specific categories: %s", country_code) + else: + _LOGGER.debug( + "No country-specific categories found for %s, using default", + country_code + ) + categories_file = os.path.join(component_path, "data", "categories.json") + else: + categories_file = os.path.join(component_path, "data", "categories.json") + + try: + async with aiofiles.open(categories_file, "r", encoding="utf-8") as f: + content = await f.read() + data = json.loads(content) + + _LOGGER.info( + "Loaded categories version %s for region %s", + data.get("version", "unknown"), + data.get("region", "default") + ) + + return data.get("categories", []) + + except FileNotFoundError: + _LOGGER.error("Categories file not found: %s", categories_file) + return _get_fallback_categories() + except json.JSONDecodeError as err: + _LOGGER.error("Failed to parse categories file: %s", err) + return _get_fallback_categories() + except Exception as err: + _LOGGER.error("Unexpected error loading categories: %s", err) + return _get_fallback_categories() + + +def _get_fallback_categories() -> List[Dict[str, Any]]: + """Get minimal fallback categories if file loading fails. + + Returns: + List of basic category dictionaries + """ + _LOGGER.warning("Using fallback categories") + + return [ + { + "id": "produce", + "name": "Produce", + "icon": "mdi:fruit-cherries", + "color": "#4CAF50", + "sort_order": 1, + "system": True + }, + { + "id": "dairy", + "name": "Dairy", + "icon": "mdi:cheese", + "color": "#FFC107", + "sort_order": 2, + "system": True + }, + { + "id": "other", + "name": "Other", + "icon": "mdi:dots-horizontal", + "color": "#9E9E9E", + "sort_order": 99, + "system": True + } + ] diff --git a/custom_components/shopping_list_manager/data/products_catalog_au.json b/custom_components/shopping_list_manager/data/products_catalog_au.json new file mode 100644 index 0000000..7569564 --- /dev/null +++ b/custom_components/shopping_list_manager/data/products_catalog_au.json @@ -0,0 +1,5297 @@ +{ + "version": "2.2.0", + "region": "AU", + "currency": "AUD", + "last_updated": "2026-02-13", + "description": "Clean Australian grocery catalog based on cleaned NZ dataset", + "products": [ + { + "id": "prod_milk_trim", + "name": "Milk - Trim", + "category_id": "dairy", + "aliases": [ + "low fat milk", + "milk", + "milk trim", + "milk - trims", + "milk trim", + "skim milk", + "trim milk" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 3.99, + "brands": [ + "Woolworths", + "Coles", + "Meadow Fresh" + ], + "barcode": "9400547000019", + "image_hint": "milk_trim", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "milk" + ], + "substitution_group": "milk_group", + "priority_level": 5 + }, + { + "id": "prod_milk_whole", + "name": "Milk - Whole", + "category_id": "dairy", + "aliases": [ + "blue top milk", + "full cream milk", + "milk", + "milk whole", + "milk - wholes", + "milk whole", + "whole milk" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 4.29, + "brands": [ + "Woolworths", + "Coles", + "Meadow Fresh" + ], + "barcode": "9400547000026", + "image_hint": "milk_whole", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "milk" + ], + "substitution_group": "milk_group", + "priority_level": 5 + }, + { + "id": "prod_butter_salted", + "name": "Butter - Salted", + "category_id": "dairy", + "aliases": [ + "butter", + "butter salted", + "butter - salteds", + "butter salted", + "salted butter" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 6.99, + "brands": [ + "Woolworths", + "Westgold", + "Coles" + ], + "image_hint": "butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_butter_unsalted", + "name": "Butter - Unsalted", + "category_id": "dairy", + "aliases": [ + "butter", + "butter unsalted", + "butter - unsalteds", + "butter unsalted", + "unsalted butter" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 7.49, + "brands": [], + "image_hint": "butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cheese_tasty", + "name": "Cheese - Tasty", + "category_id": "dairy", + "aliases": [ + "cheddar", + "cheese", + "cheese tasty", + "cheese - tastys", + "cheese block", + "cheese tasty", + "tasty cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 9.99, + "brands": [], + "image_hint": "cheese_tasty", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_edam", + "name": "Cheese - Edam", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese edam", + "cheese - edams", + "cheese edam", + "edam cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 9.49, + "brands": [], + "image_hint": "cheese_edam", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_colby", + "name": "Cheese - Colby", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese colby", + "cheese - colbys", + "cheese colby", + "colby cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 9.49, + "brands": [], + "image_hint": "cheese_colby", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_grated", + "name": "Cheese - Grated", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese grated", + "cheese - grateds", + "cheese grated", + "grated cheese", + "shredded cheese" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 6.99, + "brands": [], + "image_hint": "cheese_grated", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_yogurt_plain", + "name": "Yogurt - Plain", + "category_id": "dairy", + "aliases": [ + "natural yogurt", + "plain yogurt", + "yogurt", + "yogurt plain", + "yogurt - plains", + "yogurt plain" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Woolworths", + "Cyclone", + "Coles", + "Meadow Fresh" + ], + "image_hint": "yogurt_plain", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "yogurt_group", + "priority_level": 4 + }, + { + "id": "prod_yogurt_greek", + "name": "Yogurt - Greek", + "category_id": "dairy", + "aliases": [ + "greek yogurt", + "yogurt", + "yogurt greek", + "yogurt - greeks", + "yogurt greek" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 7.99, + "brands": [ + "Chobani", + "Farmers Union", + "Coles", + "Woolworths" + ], + "image_hint": "yogurt_greek", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "yogurt_group", + "priority_level": 4 + }, + { + "id": "prod_eggs_free_range", + "name": "Eggs - Free Range", + "category_id": "dairy", + "aliases": [ + "eggs", + "eggs free range", + "eggs - free ranges", + "eggs free range", + "free range eggs" + ], + "default_unit": "ea", + "default_quantity": 12, + "price": 9.99, + "brands": [ + "Coles", + "Frenz", + "Woodland", + "Farmer Brown", + "Woolworths" + ], + "image_hint": "eggs_free_range", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "eggs" + ], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_eggs_cage", + "name": "Eggs - Cage", + "category_id": "dairy", + "aliases": [ + "budget eggs", + "cage eggs", + "eggs", + "eggs cage", + "eggs - cages", + "eggs cage" + ], + "default_unit": "ea", + "default_quantity": 12, + "price": 6.49, + "brands": [ + "Woolworths", + "Value", + "Coles" + ], + "image_hint": "eggs", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "eggs" + ], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cream", + "name": "Cream - Fresh", + "category_id": "dairy", + "aliases": [ + "cream", + "cream fresh", + "cream - freshs", + "cream fresh", + "fresh cream", + "pouring cream" + ], + "default_unit": "mL", + "default_quantity": 300, + "price": 4.99, + "brands": [ + "Woolworths", + "Coles", + "Meadow Fresh" + ], + "image_hint": "cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_sour_cream", + "name": "Sour Cream", + "category_id": "dairy", + "aliases": [ + "sour cream", + "sour creams" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.49, + "brands": [ + "Woolworths", + "Coles", + "Meadow Fresh" + ], + "image_hint": "sour_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_apples_gala", + "name": "Apples - Gala", + "category_id": "produce", + "aliases": [ + "apples", + "apples gala", + "apples - galas", + "apples gala", + "gala apples" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.99, + "image_hint": "apples_gala", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_apples_granny_smith", + "name": "Apples - Granny Smith", + "category_id": "produce", + "aliases": [ + "apples", + "apples granny smith", + "apples - granny smiths", + "apples granny smith", + "granny smith", + "green apples" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.99, + "image_hint": "apples_granny_smith", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_bananas", + "name": "Bananas", + "category_id": "produce", + "aliases": [ + "banana", + "bananas" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.99, + "image_hint": "bananas", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_oranges", + "name": "Oranges", + "category_id": "produce", + "aliases": [ + "orange", + "oranges" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.49, + "image_hint": "oranges", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_mandarins", + "name": "Mandarins", + "category_id": "produce", + "aliases": [ + "easy peelers", + "mandarin", + "mandarins" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.99, + "image_hint": "mandarins", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kiwifruit_green", + "name": "Kiwifruit - Green", + "category_id": "produce", + "aliases": [ + "green kiwifruit", + "kiwi", + "kiwifruit", + "kiwifruit green", + "kiwifruit - greens", + "kiwifruit green" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 6.99, + "image_hint": "kiwifruit_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kiwifruit_gold", + "name": "Kiwifruit - Gold", + "category_id": "produce", + "aliases": [ + "gold kiwifruit", + "kiwifruit", + "kiwifruit gold", + "kiwifruit - golds", + "kiwifruit gold", + "sungold" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 8.99, + "image_hint": "kiwifruit_gold", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_strawberries", + "name": "Strawberries", + "category_id": "produce", + "aliases": [ + "strawberrie", + "strawberries", + "strawberry" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.99, + "image_hint": "strawberries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_blueberries", + "name": "Blueberries", + "category_id": "produce", + "aliases": [ + "blueberrie", + "blueberries", + "blueberry" + ], + "default_unit": "g", + "default_quantity": 125, + "price": 6.99, + "image_hint": "blueberries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_grapes_green", + "name": "Grapes - Green", + "category_id": "produce", + "aliases": [ + "grapes", + "grapes green", + "grapes - greens", + "grapes green", + "green grapes", + "white grapes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 7.99, + "image_hint": "grapes_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_grapes_red", + "name": "Grapes - Red", + "category_id": "produce", + "aliases": [ + "grapes", + "grapes red", + "grapes - reds", + "grapes red", + "red grapes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 7.99, + "image_hint": "grapes_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_avocado", + "name": "Avocados", + "category_id": "produce", + "aliases": [ + "avo", + "avocado", + "avocados" + ], + "default_unit": "ea", + "default_quantity": 3, + "price": 2.99, + "image_hint": "avocado", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_tomatoes", + "name": "Tomatoes", + "category_id": "produce", + "aliases": [ + "tomato", + "tomatoe", + "tomatoes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 6.99, + "image_hint": "tomatoes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_tomatoes_cherry", + "name": "Cherry Tomatoes", + "category_id": "produce", + "aliases": [ + "cherry tomato", + "cherry tomatoe", + "cherry tomatoes" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.99, + "image_hint": "tomatoes_cherry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cucumber", + "name": "Cucumber", + "category_id": "produce", + "aliases": [ + "cucumber", + "cucumbers" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 2.99, + "image_hint": "cucumber", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_lettuce_iceberg", + "name": "Lettuce - Iceberg", + "category_id": "produce", + "aliases": [ + "iceberg lettuce", + "lettuce", + "lettuce iceberg", + "lettuce - icebergs", + "lettuce iceberg" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.99, + "image_hint": "lettuce_iceberg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_lettuce_cos", + "name": "Lettuce - Cos", + "category_id": "produce", + "aliases": [ + "cos lettuce", + "lettuce", + "lettuce cos", + "lettuce - co", + "lettuce cos", + "romaine" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.99, + "image_hint": "lettuce_cos", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_capsicum_red", + "name": "Capsicum - Red", + "category_id": "produce", + "aliases": [ + "capsicum", + "capsicum red", + "capsicum - reds", + "capsicum red", + "red capsicum", + "red pepper" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 2.49, + "image_hint": "capsicum_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_capsicum_green", + "name": "Capsicum - Green", + "category_id": "produce", + "aliases": [ + "capsicum", + "capsicum green", + "capsicum - greens", + "capsicum green", + "green capsicum", + "green pepper" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 1.99, + "image_hint": "capsicum_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_broccoli", + "name": "Broccoli", + "category_id": "produce", + "aliases": [ + "broccoli", + "broccoli head", + "broccolis" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.99, + "image_hint": "broccoli", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cauliflower", + "name": "Cauliflower", + "category_id": "produce", + "aliases": [ + "cauli", + "cauliflower", + "cauliflowers" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 4.99, + "image_hint": "cauliflower", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_carrots", + "name": "Carrots", + "category_id": "produce", + "aliases": [ + "carrot", + "carrots" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 2.99, + "image_hint": "carrots", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_potatoes", + "name": "Potatoes", + "category_id": "produce", + "aliases": [ + "potato", + "potatoe", + "potatoes", + "spuds" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 4.99, + "image_hint": "potatoes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kumara", + "name": "Sweet Potato", + "category_id": "produce", + "aliases": [ + "kumara", + "kumaras", + "kumera", + "sweet potato", + "sweet potato" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.99, + "image_hint": "kumara", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_onions_brown", + "name": "Onions - Brown", + "category_id": "produce", + "aliases": [ + "brown onions", + "onions", + "onions brown", + "onions - browns", + "onions brown" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.99, + "image_hint": "onions_brown", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_onions_red", + "name": "Onions - Red", + "category_id": "produce", + "aliases": [ + "onions", + "onions red", + "onions - reds", + "onions red", + "red onions" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.99, + "image_hint": "onions_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_garlic", + "name": "Garlic", + "category_id": "produce", + "aliases": [ + "garlic", + "garlic bulb", + "garlics" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 1.99, + "image_hint": "garlic", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_ginger", + "name": "Ginger", + "category_id": "produce", + "aliases": [ + "fresh ginger", + "ginger", + "gingers" + ], + "default_unit": "g", + "default_quantity": 100, + "price": 2.99, + "image_hint": "ginger", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_mushrooms_button", + "name": "Mushrooms - Button", + "category_id": "produce", + "aliases": [ + "button mushrooms", + "mushrooms", + "mushrooms button", + "mushrooms - buttons", + "mushrooms button" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.99, + "image_hint": "mushrooms_button", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_courgette", + "name": "Courgette", + "category_id": "produce", + "aliases": [ + "courgette", + "courgettes", + "zucchini" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 1.99, + "image_hint": "courgette", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_pumpkin", + "name": "Pumpkin", + "category_id": "produce", + "aliases": [ + "butternut", + "pumpkin", + "pumpkins", + "squash" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.99, + "image_hint": "pumpkin", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_spinach", + "name": "Spinach", + "category_id": "produce", + "aliases": [ + "baby spinach", + "spinach", + "spinachs" + ], + "default_unit": "g", + "default_quantity": 120, + "price": 3.99, + "image_hint": "spinach", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_chicken_breast", + "name": "Chicken Breast", + "category_id": "meat", + "aliases": [ + "chicken breast", + "chicken breast fillets", + "chicken breasts" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 16.99, + "brands": [ + "Tegel", + "Inghams", + "Coles", + "Woolworths" + ], + "image_hint": "chicken_breast", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_thigh", + "name": "Chicken Thighs", + "category_id": "meat", + "aliases": [ + "chicken thigh", + "chicken thigh fillets", + "chicken thighs" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 14.99, + "brands": [ + "Tegel", + "Inghams", + "Coles", + "Woolworths" + ], + "image_hint": "chicken_thigh", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_drumsticks", + "name": "Chicken Drumsticks", + "category_id": "meat", + "aliases": [ + "chicken drumstick", + "chicken drumsticks", + "drumsticks" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 11.99, + "brands": [ + "Tegel", + "Inghams", + "Coles", + "Woolworths" + ], + "image_hint": "chicken_drumsticks", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_whole", + "name": "Whole Chicken", + "category_id": "meat", + "aliases": [ + "whole chicken", + "whole chickens", + "whole roasting chicken" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 13.99, + "brands": [ + "Tegel", + "Inghams", + "Coles", + "Woolworths" + ], + "image_hint": "chicken_whole", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beef_mince", + "name": "Beef Mince", + "category_id": "meat", + "aliases": [ + "beef mince", + "beef minces", + "ground beef", + "mince" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 15.99, + "brands": [ + "Woolworths", + "Angus", + "Coles" + ], + "image_hint": "beef_mince", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beef_steak", + "name": "Beef Steak", + "category_id": "meat", + "aliases": [ + "beef steak", + "beef steaks", + "scotch fillet", + "sirloin" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 29.99, + "brands": [ + "Woolworths", + "Premium", + "Angus", + "Coles" + ], + "image_hint": "beef_steak", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "bbq_meat_group", + "priority_level": 1 + }, + { + "id": "prod_lamb_chops", + "name": "Lamb Chops", + "category_id": "meat", + "aliases": [ + "lamb chop", + "lamb chops", + "lamb loin chops" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 24.99, + "brands": [ + "Woolworths", + "Coles", + "Silver Fern Farms", + "Coastal Spring" + ], + "image_hint": "lamb_chops", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_lamb_leg", + "name": "Lamb Leg", + "category_id": "meat", + "aliases": [ + "lamb leg", + "lamb legs", + "leg of lamb" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 19.99, + "brands": [ + "Woolworths", + "Coles", + "Silver Fern Farms", + "Coastal Spring" + ], + "image_hint": "lamb_leg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_pork_chops", + "name": "Pork Chops", + "category_id": "meat", + "aliases": [ + "pork chop", + "pork chops", + "pork loin chops" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 17.99, + "image_hint": "pork_chops", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bacon", + "name": "Bacon", + "category_id": "meat", + "aliases": [ + "bacon", + "bacons", + "middle bacon", + "streaky bacon" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 7.99, + "brands": [ + "Beehive", + "Coles", + "Freedom Farms", + "Woolworths" + ], + "image_hint": "bacon", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_sausages", + "name": "Sausages", + "category_id": "meat", + "aliases": [ + "bangers", + "pork sausages", + "sausage", + "sausages" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 11.99, + "brands": [ + "Woolworths", + "Farmers Union", + "Coles" + ], + "image_hint": "sausages", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "bbq_meat_group", + "priority_level": 1 + }, + { + "id": "prod_salami", + "name": "Salami", + "category_id": "meat", + "aliases": [ + "italian salami", + "salami", + "salamis" + ], + "default_unit": "g", + "default_quantity": 100, + "price": 5.99, + "brands": [ + "Woolworths", + "Continental", + "Coles" + ], + "image_hint": "salami", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ham", + "name": "Ham", + "category_id": "meat", + "aliases": [ + "deli ham", + "ham", + "hams", + "leg ham" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 7.99, + "brands": [ + "Beehive", + "Coles", + "Woolworths" + ], + "image_hint": "ham", + "tags": [], + "collections": [ + "christmas" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_salmon_fresh", + "name": "Salmon - Fresh", + "category_id": "meat", + "aliases": [ + "fresh salmon", + "salmon", + "salmon fresh", + "salmon - freshs", + "salmon fillet", + "salmon fresh" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 39.99, + "brands": [ + "Woolworths", + "Regal", + "Coles" + ], + "image_hint": "salmon_fresh", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_fish_hoki", + "name": "Hoki Fillets", + "category_id": "meat", + "aliases": [ + "hoki", + "hoki fillet", + "hoki fillets", + "white fish" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 19.99, + "brands": [ + "Woolworths", + "Sanford", + "Coles" + ], + "image_hint": "fish_hoki", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_prawns", + "name": "Prawns - Cooked", + "category_id": "meat", + "aliases": [ + "cooked prawns", + "prawns", + "prawns cooked", + "prawns - cookeds", + "prawns cooked", + "shrimp" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 29.99, + "brands": [], + "image_hint": "prawns", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_mussels", + "name": "Mussels - Green Lipped", + "category_id": "meat", + "aliases": [ + "green lipped mussels", + "mussels", + "mussels green lipped", + "mussels - green lippeds", + "mussels green lipped" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 14.99, + "brands": [ + "Woolworths", + "Sanford", + "Coles" + ], + "image_hint": "mussels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bread_white", + "name": "Bread - White", + "category_id": "bakery", + "aliases": [ + "bread", + "bread white", + "bread - whites", + "bread white", + "sandwich bread", + "white bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 2.99, + "brands": [ + "Woolworths", + "Coles", + "Freyas", + "Vogels" + ], + "image_hint": "bread_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_wholemeal", + "name": "Bread - Wholemeal", + "category_id": "bakery", + "aliases": [ + "bread", + "bread wholemeal", + "bread - wholemeals", + "bread wholemeal", + "brown bread", + "wholemeal bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 3.49, + "brands": [ + "Woolworths", + "Coles", + "Vogels" + ], + "image_hint": "bread_wholemeal", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [ + "wholegrain" + ], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_vogels", + "name": "Bread - Vogels", + "category_id": "bakery", + "aliases": [ + "bread", + "bread vogels", + "bread - vogel", + "bread vogels", + "seed bread", + "vogels bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 4.99, + "brands": [ + "Woolworths", + "Coles", + "Vogels" + ], + "image_hint": "bread_vogels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_rolls", + "name": "Bread Rolls", + "category_id": "bakery", + "aliases": [ + "bread roll", + "bread rolls", + "dinner rolls", + "white rolls" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 3.99, + "brands": [ + "Woolworths", + "Bakery", + "Coles" + ], + "image_hint": "bread_rolls", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bagels", + "name": "Bagels", + "category_id": "bakery", + "aliases": [ + "bagel", + "bagels", + "plain bagels" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.99, + "brands": [], + "image_hint": "bagels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_english_muffins", + "name": "English Muffins", + "category_id": "bakery", + "aliases": [ + "english muffin", + "english muffins", + "muffins" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.49, + "brands": [], + "image_hint": "english_muffins", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wraps", + "name": "Wraps", + "category_id": "bakery", + "aliases": [ + "flour tortillas", + "tortilla wraps", + "wrap", + "wraps" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.99, + "brands": [ + "Woolworths", + "Mission", + "Farrah's", + "Coles" + ], + "image_hint": "wraps", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_pita_bread", + "name": "Pita Bread", + "category_id": "bakery", + "aliases": [ + "pita bread", + "pita breads", + "pita pocket" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 3.99, + "brands": [ + "Woolworths", + "Farrah's", + "Coles" + ], + "image_hint": "pita_bread", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_croissants", + "name": "Croissants", + "category_id": "bakery", + "aliases": [ + "butter croissants", + "croissant", + "croissants" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Woolworths", + "Bakery", + "Coles" + ], + "image_hint": "croissants", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_peas", + "name": "Frozen Peas", + "category_id": "frozen", + "aliases": [ + "frozen pea", + "frozen peas", + "peas frozen" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.99, + "brands": [], + "image_hint": "frozen_peas", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_mixed_veg", + "name": "Frozen Mixed Vegetables", + "category_id": "frozen", + "aliases": [ + "frozen mixed vegetable", + "frozen mixed vegetables", + "frozen vegetables", + "mixed veg" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.49, + "brands": [], + "image_hint": "frozen_mixed_veg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_chips", + "name": "Frozen Chips", + "category_id": "frozen", + "aliases": [ + "french fries", + "frozen chip", + "frozen chips", + "oven chips" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "McCain", + "Coles", + "Woolworths" + ], + "image_hint": "frozen_chips", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ice_cream_vanilla", + "name": "Ice Cream - Vanilla", + "category_id": "frozen", + "aliases": [ + "ice cream", + "ice cream vanilla", + "ice cream - vanillas", + "ice cream vanilla", + "vanilla ice cream" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 7.99, + "brands": [ + "Much Moore", + "Coles", + "Woolworths" + ], + "image_hint": "ice_cream_vanilla", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ice_cream_hokey_pokey", + "name": "Ice Cream - Hokey Pokey", + "category_id": "frozen", + "aliases": [ + "hokey pokey ice cream", + "ice cream", + "ice cream hokey pokey", + "ice cream - hokey pokeys", + "ice cream hokey pokey" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 8.99, + "brands": [], + "image_hint": "ice_cream_hokey_pokey", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_pizza", + "name": "Frozen Pizza", + "category_id": "frozen", + "aliases": [ + "frozen pizza", + "frozen pizzas", + "pizza" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 6.99, + "brands": [ + "Dr Oetker", + "Woolworths", + "Coles", + "McCain" + ], + "image_hint": "frozen_pizza", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_fish_fingers", + "name": "Fish Fingers", + "category_id": "frozen", + "aliases": [ + "fish finger", + "fish fingers", + "fish sticks" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 7.99, + "brands": [ + "Woolworths", + "Coles", + "Birds Eye" + ], + "image_hint": "fish_fingers", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [ + "fish" + ], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_berries", + "name": "Frozen Mixed Berries", + "category_id": "frozen", + "aliases": [ + "frozen berries", + "frozen mixed berrie", + "frozen mixed berries" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 6.99, + "brands": [ + "Woolworths", + "Value", + "Coles" + ], + "image_hint": "frozen_berries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_rice_white", + "name": "Rice - White", + "category_id": "pantry", + "aliases": [ + "long grain rice", + "rice", + "rice white", + "rice - whites", + "rice white", + "white rice" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.99, + "brands": [ + "Woolworths", + "Sunrice", + "Coles" + ], + "image_hint": "rice_white", + "tags": [ + "gluten_free", + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [ + "gluten_free" + ], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "rice_group", + "priority_level": 3 + }, + { + "id": "prod_rice_basmati", + "name": "Rice - Basmati", + "category_id": "pantry", + "aliases": [ + "basmati rice", + "rice", + "rice basmati", + "rice - basmatis", + "rice basmati" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Woolworths", + "Tilda", + "Sunrice", + "Coles" + ], + "image_hint": "rice_basmati", + "tags": [ + "gluten_free", + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [ + "gluten_free" + ], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "rice_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_spaghetti", + "name": "Pasta - Spaghetti", + "category_id": "pantry", + "aliases": [ + "pasta", + "pasta spaghetti", + "pasta - spaghettis", + "pasta spaghetti", + "spaghetti" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 2.99, + "brands": [ + "San Remo", + "Barilla", + "Coles", + "Woolworths" + ], + "image_hint": "pasta_spaghetti", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_penne", + "name": "Pasta - Penne", + "category_id": "pantry", + "aliases": [ + "pasta", + "pasta penne", + "pasta - pennes", + "pasta penne", + "penne pasta" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 2.99, + "brands": [ + "San Remo", + "Barilla", + "Coles", + "Woolworths" + ], + "image_hint": "pasta_penne", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_sauce", + "name": "Pasta Sauce", + "category_id": "pantry", + "aliases": [ + "bolognese sauce", + "pasta sauce", + "pasta sauces", + "tomato pasta sauce" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 3.99, + "brands": [ + "Woolworths", + "Barilla", + "Dolmio", + "Coles" + ], + "image_hint": "pasta_sauce", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_flour_plain", + "name": "Flour - Plain", + "category_id": "pantry", + "aliases": [ + "flour", + "flour plain", + "flour - plains", + "flour plain", + "plain flour", + "white flour" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.49, + "brands": [ + "Woolworths", + "Champion", + "Coles", + "Edmonds" + ], + "image_hint": "flour_plain", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_flour_self_raising", + "name": "Flour - Self Raising", + "category_id": "pantry", + "aliases": [ + "flour", + "flour self raising", + "flour - self raisings", + "flour self raising", + "self raising flour" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.49, + "brands": [ + "Woolworths", + "Champion", + "Coles", + "Edmonds" + ], + "image_hint": "flour_self_raising", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_sugar_white", + "name": "Sugar - White", + "category_id": "pantry", + "aliases": [ + "caster sugar", + "sugar", + "sugar white", + "sugar - whites", + "sugar white", + "white sugar" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.99, + "brands": [ + "Woolworths", + "Chelsea", + "Coles" + ], + "image_hint": "sugar_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_sugar_brown", + "name": "Sugar - Brown", + "category_id": "pantry", + "aliases": [ + "brown sugar", + "soft brown", + "sugar", + "sugar brown", + "sugar - browns", + "sugar brown" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.49, + "brands": [ + "Woolworths", + "Chelsea", + "Coles" + ], + "image_hint": "sugar_brown", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_oil_olive", + "name": "Olive Oil", + "category_id": "pantry", + "aliases": [ + "EVOO", + "extra virgin olive oil", + "olive oil", + "olive oils" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 12.99, + "brands": [ + "Woolworths", + "Olivado", + "Coles" + ], + "image_hint": "oil_olive", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_oil_vegetable", + "name": "Vegetable Oil", + "category_id": "pantry", + "aliases": [ + "canola oil", + "cooking oil", + "vegetable oil", + "vegetable oils" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 6.99, + "brands": [ + "Woolworths", + "Coles", + "Olivani" + ], + "image_hint": "oil_vegetable", + "tags": [ + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tomatoes_canned", + "name": "Canned Tomatoes", + "category_id": "pantry", + "aliases": [ + "canned tomatoe", + "canned tomatoes", + "chopped tomatoes", + "tinned tomatoes" + ], + "default_unit": "can", + "default_quantity": 4, + "price": 1.99, + "brands": [], + "image_hint": "tomatoes_canned", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_baked_beans", + "name": "Baked Beans", + "category_id": "pantry", + "aliases": [ + "baked bean", + "baked beans", + "beans in tomato sauce" + ], + "default_unit": "can", + "default_quantity": 1, + "price": 2.49, + "brands": [ + "Woolworths", + "Coles", + "Heinz" + ], + "image_hint": "baked_beans", + "tags": [ + "gluten_free" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tuna", + "name": "Tuna in Oil", + "category_id": "pantry", + "aliases": [ + "canned tuna", + "tinned tuna", + "tuna in oil", + "tuna in oils" + ], + "default_unit": "can", + "default_quantity": 3, + "price": 2.99, + "brands": [ + "Woolworths", + "John West", + "Coles" + ], + "image_hint": "tuna", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_coconut_cream", + "name": "Coconut Cream", + "category_id": "pantry", + "aliases": [ + "coconut cream", + "coconut creams", + "coconut milk" + ], + "default_unit": "can", + "default_quantity": 2, + "price": 2.99, + "brands": [ + "Woolworths", + "Coles", + "Ayam" + ], + "image_hint": "coconut_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_peanut_butter", + "name": "Peanut Butter", + "category_id": "pantry", + "aliases": [ + "crunchy peanut butter", + "peanut butter", + "peanut butters", + "smooth peanut butter" + ], + "default_unit": "g", + "default_quantity": 380, + "price": 5.99, + "brands": [ + "Kraft", + "ETA", + "Coles", + "Woolworths", + "Pic's" + ], + "image_hint": "peanut_butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_jam_strawberry", + "name": "Jam - Strawberry", + "category_id": "pantry", + "aliases": [ + "jam", + "jam strawberry", + "jam - strawberrys", + "jam strawberry", + "strawberry jam" + ], + "default_unit": "g", + "default_quantity": 340, + "price": 4.99, + "brands": [ + "Woolworths", + "Anathoth", + "Barker's", + "Coles" + ], + "image_hint": "jam_strawberry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_honey", + "name": "Honey", + "category_id": "pantry", + "aliases": [ + "clover honey", + "honey", + "honeys", + "manuka honey" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 8.99, + "brands": [ + "Airborne", + "Manuka Health", + "Coles", + "Woolworths" + ], + "image_hint": "honey", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_marmite", + "name": "Marmite", + "category_id": "pantry", + "aliases": [ + "marmite", + "marmites", + "yeast spread" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.99, + "brands": [], + "image_hint": "marmite", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_vegemite", + "name": "Vegemite", + "category_id": "pantry", + "aliases": [ + "vegemite", + "vegemites", + "yeast spread" + ], + "default_unit": "g", + "default_quantity": 220, + "price": 5.49, + "brands": [ + "Woolworths", + "Bega", + "Coles" + ], + "image_hint": "vegemite", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_soy_sauce", + "name": "Soy Sauce", + "category_id": "pantry", + "aliases": [ + "kikkoman", + "soy sauce", + "soy sauces" + ], + "default_unit": "mL", + "default_quantity": 250, + "price": 4.99, + "brands": [ + "Woolworths", + "Kikkoman", + "Coles" + ], + "image_hint": "soy_sauce", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [ + "soy" + ], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tomato_sauce", + "name": "Tomato Sauce", + "category_id": "pantry", + "aliases": [ + "ketchup", + "tomato ketchup", + "tomato sauce", + "tomato sauces" + ], + "default_unit": "mL", + "default_quantity": 560, + "price": 4.99, + "brands": [ + "Woolworths", + "Coles", + "Heinz" + ], + "image_hint": "tomato_sauce", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_bbq_sauce", + "name": "BBQ Sauce", + "category_id": "pantry", + "aliases": [ + "barbecue sauce", + "bbq sauce", + "bbq sauces" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 4.99, + "brands": [ + "Woolworths", + "Masterfoods", + "Coles" + ], + "image_hint": "bbq_sauce", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_mayonnaise", + "name": "Mayonnaise", + "category_id": "pantry", + "aliases": [ + "mayo", + "mayonnaise", + "mayonnaises" + ], + "default_unit": "mL", + "default_quantity": 440, + "price": 5.99, + "brands": [ + "Woolworths", + "Best Foods", + "Coles" + ], + "image_hint": "mayonnaise", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_mustard", + "name": "Mustard", + "category_id": "pantry", + "aliases": [ + "american mustard", + "dijon mustard", + "mustard", + "mustards" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 3.99, + "brands": [ + "Woolworths", + "Masterfoods", + "Coles", + "French's" + ], + "image_hint": "mustard", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_salt", + "name": "Salt", + "category_id": "pantry", + "aliases": [ + "cooking salt", + "salt", + "salts", + "table salt" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 1.99, + "brands": [ + "Woolworths", + "Cerebos", + "Coles" + ], + "image_hint": "salt", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_pepper", + "name": "Black Pepper", + "category_id": "pantry", + "aliases": [ + "black pepper", + "black peppers", + "ground pepper" + ], + "default_unit": "g", + "default_quantity": 50, + "price": 3.99, + "brands": [ + "Woolworths", + "Masterfoods", + "Coles" + ], + "image_hint": "pepper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_stock_cubes_chicken", + "name": "Stock Cubes - Chicken", + "category_id": "pantry", + "aliases": [ + "bouillon", + "chicken stock", + "stock cubes", + "stock cubes chicken", + "stock cubes - chickens", + "stock cubes chicken" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 2.99, + "brands": [ + "Woolworths", + "Continental", + "Maggi", + "Coles" + ], + "image_hint": "stock_cubes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_stock_cubes_beef", + "name": "Stock Cubes - Beef", + "category_id": "pantry", + "aliases": [ + "beef stock", + "stock cubes", + "stock cubes beef", + "stock cubes - beefs", + "stock cubes beef" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 2.99, + "brands": [ + "Woolworths", + "Continental", + "Maggi", + "Coles" + ], + "image_hint": "stock_cubes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_coffee_instant", + "name": "Instant Coffee", + "category_id": "beverages", + "aliases": [ + "coffee", + "instant coffee", + "instant coffees", + "nescafe" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 12.99, + "brands": [ + "Robert Harris", + "Gregg's", + "Nescafe", + "Coles", + "Woolworths" + ], + "image_hint": "coffee_instant", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_coffee_ground", + "name": "Ground Coffee", + "category_id": "beverages", + "aliases": [ + "filter coffee", + "ground coffee", + "ground coffees" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 8.99, + "brands": [ + "Robert Harris", + "L'affare", + "Coles", + "Woolworths", + "Vittoria" + ], + "image_hint": "coffee_ground", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tea_black", + "name": "Tea - Black", + "category_id": "beverages", + "aliases": [ + "black tea", + "tea", + "tea black", + "tea - blacks", + "tea bags", + "tea black" + ], + "default_unit": "ea", + "default_quantity": 100, + "price": 6.99, + "brands": [ + "Bell", + "Coles", + "Woolworths", + "Twinings", + "Dilmah" + ], + "image_hint": "tea_black", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tea_green", + "name": "Tea - Green", + "category_id": "beverages", + "aliases": [ + "green tea", + "tea", + "tea green", + "tea - greens", + "tea green" + ], + "default_unit": "ea", + "default_quantity": 40, + "price": 5.99, + "brands": [ + "Woolworths", + "Coles", + "Twinings", + "Dilmah" + ], + "image_hint": "tea_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_juice_orange", + "name": "Orange Juice", + "category_id": "beverages", + "aliases": [ + "OJ", + "fresh orange juice", + "orange juice", + "orange juices" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 6.99, + "brands": [ + "Just Juice", + "Charlies", + "Coles", + "Woolworths" + ], + "image_hint": "juice_orange", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_juice_apple", + "name": "Apple Juice", + "category_id": "beverages", + "aliases": [ + "apple juice", + "apple juices", + "fresh apple juice" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 6.99, + "brands": [ + "Just Juice", + "Charlies", + "Coles", + "Woolworths" + ], + "image_hint": "juice_apple", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soft_drink_coke", + "name": "Coca Cola", + "category_id": "beverages", + "aliases": [ + "coca cola", + "coca colas", + "coke", + "cola" + ], + "default_unit": "L", + "default_quantity": 2.25, + "price": 4.99, + "brands": [ + "Woolworths", + "Coca-Cola", + "Coles" + ], + "image_hint": "coke", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soft_drink_lemonade", + "name": "Lemonade", + "category_id": "beverages", + "aliases": [ + "7up", + "lemonade", + "lemonades", + "sprite" + ], + "default_unit": "L", + "default_quantity": 2.25, + "price": 4.99, + "brands": [ + "Woolworths", + "Schweppes", + "Sprite", + "Coles" + ], + "image_hint": "lemonade", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_water_still", + "name": "Water - Still", + "category_id": "beverages", + "aliases": [ + "bottled water", + "spring water", + "water", + "water still", + "water - stills", + "water still" + ], + "default_unit": "L", + "default_quantity": 1.5, + "price": 2.49, + "brands": [ + "Woolworths", + "Pump", + "Evian", + "Coles" + ], + "image_hint": "water_still", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_water_sparkling", + "name": "Water - Sparkling", + "category_id": "beverages", + "aliases": [ + "soda water", + "sparkling water", + "water", + "water sparkling", + "water - sparklings", + "water sparkling" + ], + "default_unit": "L", + "default_quantity": 1.5, + "price": 2.99, + "brands": [ + "Woolworths", + "Schweppes", + "San Pellegrino", + "Coles" + ], + "image_hint": "water_sparkling", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beer", + "name": "Beer", + "category_id": "beverages", + "aliases": [ + "ale", + "beer", + "beers", + "lager" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 24.99, + "brands": [ + "Coles", + "DB Export", + "Steinlager", + "Speights", + "Woolworths" + ], + "image_hint": "beer", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wine_red", + "name": "Wine - Red", + "category_id": "beverages", + "aliases": [ + "red wine", + "wine", + "wine red", + "wine - reds", + "wine red" + ], + "default_unit": "bottle", + "default_quantity": 1, + "price": 15.99, + "brands": [ + "Woolworths", + "Villa Maria", + "Coles", + "Oyster Bay" + ], + "image_hint": "wine_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wine_white", + "name": "Wine - White", + "category_id": "beverages", + "aliases": [ + "sauvignon blanc", + "white wine", + "wine", + "wine white", + "wine - whites", + "wine white" + ], + "default_unit": "bottle", + "default_quantity": 1, + "price": 15.99, + "brands": [ + "Cloudy Bay", + "Coles", + "Villa Maria", + "Woolworths", + "Oyster Bay" + ], + "image_hint": "wine_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_cornflakes", + "name": "Cornflakes", + "category_id": "snacks", + "aliases": [ + "cornflake", + "cornflakes", + "kelloggs cornflakes" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 6.99, + "brands": [ + "Woolworths", + "Kelloggs", + "Coles" + ], + "image_hint": "cereal_cornflakes", + "tags": [ + "gluten_free" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_weet_bix", + "name": "Weet-Bix", + "category_id": "snacks", + "aliases": [ + "weet bix", + "weet-bix", + "weet-bixs", + "weetbix", + "wheat biscuits" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 7.99, + "brands": [], + "image_hint": "cereal_weet_bix", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_muesli", + "name": "Muesli", + "category_id": "snacks", + "aliases": [ + "muesli", + "mueslis", + "toasted muesli" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 8.99, + "brands": [ + "Woolworths", + "Hubbards", + "Coles" + ], + "image_hint": "cereal_muesli", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_oats_rolled", + "name": "Rolled Oats", + "category_id": "snacks", + "aliases": [ + "oats", + "porridge oats", + "rolled oat", + "rolled oats" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Woolworths", + "Harraways", + "Coles" + ], + "image_hint": "oats_rolled", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chips_salt", + "name": "Potato Chips - Salt", + "category_id": "snacks", + "aliases": [ + "crisps", + "potato chips", + "potato chips salt", + "potato chips - salts", + "potato chips salt", + "ready salted chips" + ], + "default_unit": "g", + "default_quantity": 150, + "price": 3.99, + "brands": [ + "Woolworths", + "Coles", + "Bluebird", + "Eta" + ], + "image_hint": "chips_salt", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chips_chicken", + "name": "Potato Chips - Chicken", + "category_id": "snacks", + "aliases": [ + "chicken chips", + "potato chips", + "potato chips chicken", + "potato chips - chickens", + "potato chips chicken" + ], + "default_unit": "g", + "default_quantity": 150, + "price": 3.99, + "brands": [ + "Woolworths", + "Coles", + "Bluebird", + "Eta" + ], + "image_hint": "chips_chicken", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_crackers", + "name": "Crackers", + "category_id": "snacks", + "aliases": [ + "cracker", + "crackers", + "savoy", + "water crackers" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 3.99, + "brands": [ + "Woolworths", + "Arnott's", + "Coles", + "Griffin's" + ], + "image_hint": "crackers", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cookies_chocolate_chip", + "name": "Chocolate Chip Cookies", + "category_id": "snacks", + "aliases": [ + "choc chip biscuits", + "chocolate chip cookie", + "chocolate chip cookies", + "cookies" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.99, + "brands": [ + "Cookie Time", + "Woolworths", + "Coles", + "Griffin's" + ], + "image_hint": "cookies_chocolate_chip", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tim_tams", + "name": "Tim Tams", + "category_id": "snacks", + "aliases": [ + "chocolate biscuits", + "tim tam", + "tim tams" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.49, + "brands": [ + "Woolworths", + "Arnott's", + "Coles" + ], + "image_hint": "tim_tams", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chocolate_whittakers", + "name": "Chocolate - Whittaker's", + "category_id": "snacks", + "aliases": [ + "chocolate", + "chocolate whittaker's", + "chocolate - whittaker'", + "chocolate bar", + "chocolate whittaker's", + "whittakers block" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.99, + "brands": [], + "image_hint": "chocolate_whittakers", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chocolate_cadbury", + "name": "Chocolate - Cadbury", + "category_id": "snacks", + "aliases": [ + "cadbury block", + "chocolate", + "chocolate cadbury", + "chocolate - cadburys", + "chocolate cadbury" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 4.99, + "brands": [ + "Woolworths", + "Cadbury", + "Coles" + ], + "image_hint": "chocolate_cadbury", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_muesli_bars", + "name": "Muesli Bars", + "category_id": "snacks", + "aliases": [ + "granola bars", + "muesli bar", + "muesli bars" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Woolworths", + "Nice & Natural", + "Uncle Tobys", + "Coles" + ], + "image_hint": "muesli_bars", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_popcorn", + "name": "Popcorn", + "category_id": "snacks", + "aliases": [ + "microwave popcorn", + "popcorn", + "popcorns" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.99, + "brands": [ + "Woolworths", + "Proper", + "Eta", + "Coles" + ], + "image_hint": "popcorn", + "tags": [ + "gluten_free" + ], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_nuts_mixed", + "name": "Mixed Nuts", + "category_id": "snacks", + "aliases": [ + "mixed nut", + "mixed nuts", + "roasted nuts" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 6.99, + "brands": [ + "Woolworths", + "Eta", + "Coles" + ], + "image_hint": "nuts_mixed", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toilet_paper", + "name": "Toilet Paper", + "category_id": "household", + "aliases": [ + "TP", + "bathroom tissue", + "toilet paper", + "toilet papers" + ], + "default_unit": "roll", + "default_quantity": 12, + "price": 12.99, + "brands": [ + "Woolworths", + "Purex", + "Sorbent", + "Coles" + ], + "image_hint": "toilet_paper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_paper_towels", + "name": "Paper Towels", + "category_id": "household", + "aliases": [ + "kitchen paper", + "paper towel", + "paper towels" + ], + "default_unit": "roll", + "default_quantity": 4, + "price": 8.99, + "brands": [ + "Woolworths", + "Handee", + "Sorbent", + "Coles" + ], + "image_hint": "paper_towels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tissues", + "name": "Tissues", + "category_id": "household", + "aliases": [ + "facial tissues", + "kleenex", + "tissue", + "tissues" + ], + "default_unit": "box", + "default_quantity": 4, + "price": 7.99, + "brands": [ + "Woolworths", + "Kleenex", + "Sorbent", + "Coles" + ], + "image_hint": "tissues", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dishwashing_liquid", + "name": "Dishwashing Liquid", + "category_id": "household", + "aliases": [ + "dish soap", + "dishwash", + "dishwashing liquid", + "dishwashing liquids" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 4.99, + "brands": [ + "Woolworths", + "Sunlight", + "Morning Fresh", + "Coles" + ], + "image_hint": "dishwashing_liquid", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dishwasher_tablets", + "name": "Dishwasher Tablets", + "category_id": "household", + "aliases": [ + "dishwasher pods", + "dishwasher tablet", + "dishwasher tablets" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 14.99, + "brands": [ + "Woolworths", + "Earthwise", + "Coles", + "Finish" + ], + "image_hint": "dishwasher_tablets", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_laundry_powder", + "name": "Laundry Powder", + "category_id": "household", + "aliases": [ + "laundry powder", + "laundry powders", + "washing powder" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 16.99, + "brands": [ + "Persil", + "Earthwise", + "Coles", + "OMO", + "Woolworths" + ], + "image_hint": "laundry_powder", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_laundry_liquid", + "name": "Laundry Liquid", + "category_id": "household", + "aliases": [ + "laundry liquid", + "laundry liquids", + "washing liquid" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 14.99, + "brands": [ + "Persil", + "Earthwise", + "Coles", + "OMO", + "Woolworths" + ], + "image_hint": "laundry_liquid", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_fabric_softener", + "name": "Fabric Softener", + "category_id": "household", + "aliases": [ + "comfort", + "downy", + "fabric softener", + "fabric softeners" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 9.99, + "brands": [ + "Comfort", + "Earthwise", + "Coles", + "Woolworths" + ], + "image_hint": "fabric_softener", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_spray_cleaner", + "name": "Spray Cleaner", + "category_id": "household", + "aliases": [ + "multi-purpose cleaner", + "spray cleaner", + "spray cleaners", + "spray n wipe" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 6.99, + "brands": [ + "Woolworths", + "Coles", + "Jif", + "Spray n Wipe" + ], + "image_hint": "spray_cleaner", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bleach", + "name": "Bleach", + "category_id": "household", + "aliases": [ + "bleach", + "bleachs", + "janola" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Woolworths", + "Domestos", + "Coles", + "Janola" + ], + "image_hint": "bleach", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bin_bags", + "name": "Bin Bags", + "category_id": "household", + "aliases": [ + "bin bag", + "bin bags", + "garbage bags", + "rubbish bags" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 8.99, + "brands": [ + "Woolworths", + "Glad", + "Ecostore", + "Coles" + ], + "image_hint": "bin_bags", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cling_film", + "name": "Cling Film", + "category_id": "household", + "aliases": [ + "cling film", + "cling films", + "glad wrap", + "plastic wrap" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Woolworths", + "Glad", + "Coles", + "Multix" + ], + "image_hint": "cling_film", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_aluminium_foil", + "name": "Aluminium Foil", + "category_id": "household", + "aliases": [ + "alfoil", + "aluminium foil", + "aluminium foils", + "tin foil" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 6.99, + "brands": [ + "Woolworths", + "Multix", + "Coles", + "Alfoil" + ], + "image_hint": "aluminium_foil", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baking_paper", + "name": "Baking Paper", + "category_id": "household", + "aliases": [ + "baking paper", + "baking papers", + "parchment paper" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 4.99, + "brands": [ + "Woolworths", + "Alfoil", + "Coles", + "Multix" + ], + "image_hint": "baking_paper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_shampoo", + "name": "Shampoo", + "category_id": "health", + "aliases": [ + "hair shampoo", + "shampoo", + "shampoos" + ], + "default_unit": "mL", + "default_quantity": 400, + "price": 8.99, + "brands": [ + "Head & Shoulders", + "Coles", + "Woolworths", + "Garnier", + "Pantene" + ], + "image_hint": "shampoo", + "tags": [], + "collections": [ + "christmas" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_conditioner", + "name": "Conditioner", + "category_id": "health", + "aliases": [ + "conditioner", + "conditioners", + "hair conditioner" + ], + "default_unit": "mL", + "default_quantity": 400, + "price": 8.99, + "brands": [ + "Head & Shoulders", + "Coles", + "Woolworths", + "Garnier", + "Pantene" + ], + "image_hint": "conditioner", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_body_wash", + "name": "Body Wash", + "category_id": "health", + "aliases": [ + "body wash", + "body washs", + "shower gel" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 7.99, + "brands": [ + "Dove", + "Coles", + "Palmolive", + "Woolworths", + "Nivea" + ], + "image_hint": "body_wash", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soap_bar", + "name": "Bar Soap", + "category_id": "health", + "aliases": [ + "bar soap", + "bar soaps", + "bath soap", + "hand soap" + ], + "default_unit": "bar", + "default_quantity": 4, + "price": 4.99, + "brands": [ + "Woolworths", + "Dove", + "Coles", + "Palmolive" + ], + "image_hint": "soap_bar", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toothpaste", + "name": "Toothpaste", + "category_id": "health", + "aliases": [ + "colgate", + "toothpaste", + "toothpastes" + ], + "default_unit": "g", + "default_quantity": 110, + "price": 5.99, + "brands": [ + "Woolworths", + "Coles", + "Colgate", + "Sensodyne" + ], + "image_hint": "toothpaste", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toothbrush", + "name": "Toothbrush", + "category_id": "health", + "aliases": [ + "tooth brush", + "toothbrush", + "toothbrushs" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 6.99, + "brands": [ + "Woolworths", + "Colgate", + "Coles", + "Oral-B" + ], + "image_hint": "toothbrush", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_deodorant", + "name": "Deodorant", + "category_id": "health", + "aliases": [ + "antiperspirant", + "deodorant", + "deodorants" + ], + "default_unit": "g", + "default_quantity": 50, + "price": 7.99, + "brands": [ + "Dove", + "Rexona", + "Lynx", + "Coles", + "Woolworths" + ], + "image_hint": "deodorant", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_razor_blades", + "name": "Razor Blades", + "category_id": "health", + "aliases": [ + "gillette", + "razor blade", + "razor blades", + "shaving blades" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 19.99, + "brands": [ + "Woolworths", + "Coles", + "Schick", + "Gillette" + ], + "image_hint": "razor_blades", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_shaving_cream", + "name": "Shaving Cream", + "category_id": "health", + "aliases": [ + "shave gel", + "shaving cream", + "shaving creams" + ], + "default_unit": "mL", + "default_quantity": 200, + "price": 6.99, + "brands": [ + "Woolworths", + "Coles", + "Nivea", + "Gillette" + ], + "image_hint": "shaving_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_sunscreen", + "name": "Sunscreen SPF50", + "category_id": "health", + "aliases": [ + "sun cream", + "sunblock", + "sunscreen spf50", + "sunscreen spf50s" + ], + "default_unit": "mL", + "default_quantity": 200, + "price": 14.99, + "brands": [ + "Woolworths", + "Coles", + "Neutrogena", + "Cancer Society" + ], + "image_hint": "sunscreen", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_paracetamol", + "name": "Paracetamol", + "category_id": "health", + "aliases": [ + "pain relief", + "panadol", + "paracetamol", + "paracetamols" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 8.99, + "brands": [ + "Woolworths", + "Coles", + "Panadol" + ], + "image_hint": "paracetamol", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ibuprofen", + "name": "Ibuprofen", + "category_id": "health", + "aliases": [ + "ibuprofen", + "ibuprofens", + "nurofen", + "pain relief" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 9.99, + "brands": [ + "Nurofen", + "Coles", + "Woolworths" + ], + "image_hint": "ibuprofen", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bandaids", + "name": "Band-Aids", + "category_id": "health", + "aliases": [ + "band aids", + "band-aid", + "band-aids", + "bandages", + "plasters" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Band-Aid", + "Elastoplast", + "Coles", + "Woolworths" + ], + "image_hint": "bandaids", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_vitamins_c", + "name": "Vitamin C", + "category_id": "health", + "aliases": [ + "vitamin c", + "vitamin c tablets", + "vitamin cs" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 12.99, + "brands": [ + "Woolworths", + "Healtheries", + "Coles", + "Blackmores" + ], + "image_hint": "vitamins_c", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_nappies", + "name": "Nappies", + "category_id": "baby", + "aliases": [ + "baby nappies", + "diapers", + "nappie", + "nappies" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 29.99, + "brands": [ + "Woolworths", + "Huggies", + "Coles" + ], + "image_hint": "nappies", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baby_wipes", + "name": "Baby Wipes", + "category_id": "baby", + "aliases": [ + "baby wipe", + "baby wipes", + "wet wipes" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Woolworths", + "Huggies", + "Coles" + ], + "image_hint": "baby_wipes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baby_formula", + "name": "Baby Formula", + "category_id": "baby", + "aliases": [ + "baby formula", + "baby formulas", + "infant formula" + ], + "default_unit": "g", + "default_quantity": 900, + "price": 29.99, + "brands": [ + "Woolworths", + "Coles", + "Aptamil", + "Karicare" + ], + "image_hint": "baby_formula", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dog_food_dry", + "name": "Dog Food - Dry", + "category_id": "pet", + "aliases": [ + "dog biscuits", + "dog food", + "dog food dry", + "dog food - drys", + "dog food dry", + "dog kibble" + ], + "default_unit": "kg", + "default_quantity": 3, + "price": 24.99, + "brands": [ + "Pedigree", + "Coles", + "Eukanuba", + "Woolworths" + ], + "image_hint": "dog_food_dry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dog_food_wet", + "name": "Dog Food - Wet", + "category_id": "pet", + "aliases": [ + "canned dog food", + "dog food", + "dog food wet", + "dog food - wets", + "dog food wet" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 19.99, + "brands": [ + "Pedigree", + "Champ", + "Coles", + "Woolworths" + ], + "image_hint": "dog_food_wet", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_food_dry", + "name": "Cat Food - Dry", + "category_id": "pet", + "aliases": [ + "cat biscuits", + "cat food", + "cat food dry", + "cat food - drys", + "cat food dry" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 19.99, + "brands": [ + "Woolworths", + "Whiskas", + "Fancy Feast", + "Coles" + ], + "image_hint": "cat_food_dry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_food_wet", + "name": "Cat Food - Wet", + "category_id": "pet", + "aliases": [ + "canned cat food", + "cat food", + "cat food wet", + "cat food - wets", + "cat food wet" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 14.99, + "brands": [ + "Woolworths", + "Whiskas", + "Fancy Feast", + "Coles" + ], + "image_hint": "cat_food_wet", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_litter", + "name": "Cat Litter", + "category_id": "pet", + "aliases": [ + "cat litter", + "cat litters", + "kitty litter" + ], + "default_unit": "kg", + "default_quantity": 5, + "price": 12.99, + "brands": [ + "Catlove", + "Paws", + "Coles", + "Woolworths" + ], + "image_hint": "cat_litter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + } + ], + "country": "Australia" +} \ No newline at end of file diff --git a/custom_components/shopping_list_manager/data/products_catalog_ca.json b/custom_components/shopping_list_manager/data/products_catalog_ca.json new file mode 100644 index 0000000..3631de6 --- /dev/null +++ b/custom_components/shopping_list_manager/data/products_catalog_ca.json @@ -0,0 +1,5421 @@ +{ + "version": "2.1.0", + "region": "CA", + "currency": "CAD", + "last_updated": "2026-02-13", + "description": "Clean Canadian grocery catalog based on cleaned NZ dataset (no synthetic variants)", + "products": [ + { + "id": "prod_milk_trim", + "name": "Milk - Trim", + "category_id": "dairy", + "aliases": [ + "low fat milk", + "milk", + "milk trim", + "milk - trims", + "milk trim", + "skim milk", + "trim milk" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 4.21, + "brands": [ + "Real Canadian Superstore", + "FreshCo", + "Sobeys", + "Meadow Fresh" + ], + "barcode": "9400547000019", + "image_hint": "milk_trim", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "milk" + ], + "substitution_group": "milk_group", + "priority_level": 5 + }, + { + "id": "prod_milk_whole", + "name": "Milk - Whole", + "category_id": "dairy", + "aliases": [ + "blue top milk", + "full cream milk", + "milk", + "milk whole", + "milk - wholes", + "milk whole", + "whole milk" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 4.82, + "brands": [ + "Costco Canada", + "Metro", + "Loblaws", + "Meadow Fresh" + ], + "barcode": "9400547000026", + "image_hint": "milk_whole", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "milk" + ], + "substitution_group": "milk_group", + "priority_level": 5 + }, + { + "id": "prod_butter_salted", + "name": "Butter - Salted", + "category_id": "dairy", + "aliases": [ + "butter", + "butter salted", + "butter - salteds", + "butter salted", + "salted butter" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 7.72, + "brands": [ + "Food Basics", + "Westgold", + "Sobeys", + "Loblaws" + ], + "image_hint": "butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_butter_unsalted", + "name": "Butter - Unsalted", + "category_id": "dairy", + "aliases": [ + "butter", + "butter unsalted", + "butter - unsalteds", + "butter unsalted", + "unsalted butter" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 8.59, + "brands": [], + "image_hint": "butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cheese_tasty", + "name": "Cheese - Tasty", + "category_id": "dairy", + "aliases": [ + "cheddar", + "cheese", + "cheese tasty", + "cheese - tastys", + "cheese block", + "cheese tasty", + "tasty cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 9.86, + "brands": [], + "image_hint": "cheese_tasty", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_edam", + "name": "Cheese - Edam", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese edam", + "cheese - edams", + "cheese edam", + "edam cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 10.43, + "brands": [], + "image_hint": "cheese_edam", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_colby", + "name": "Cheese - Colby", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese colby", + "cheese - colbys", + "cheese colby", + "colby cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 10.6, + "brands": [], + "image_hint": "cheese_colby", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_grated", + "name": "Cheese - Grated", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese grated", + "cheese - grateds", + "cheese grated", + "grated cheese", + "shredded cheese" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 6.97, + "brands": [], + "image_hint": "cheese_grated", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_yogurt_plain", + "name": "Yogurt - Plain", + "category_id": "dairy", + "aliases": [ + "natural yogurt", + "plain yogurt", + "yogurt", + "yogurt plain", + "yogurt - plains", + "yogurt plain" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.8, + "brands": [ + "Metro", + "Cyclone", + "FreshCo", + "Sobeys", + "Meadow Fresh" + ], + "image_hint": "yogurt_plain", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "yogurt_group", + "priority_level": 4 + }, + { + "id": "prod_yogurt_greek", + "name": "Yogurt - Greek", + "category_id": "dairy", + "aliases": [ + "greek yogurt", + "yogurt", + "yogurt greek", + "yogurt - greeks", + "yogurt greek" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 7.98, + "brands": [ + "Chobani", + "Costco Canada", + "Farmers Union", + "Food Basics", + "Longo's" + ], + "image_hint": "yogurt_greek", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "yogurt_group", + "priority_level": 4 + }, + { + "id": "prod_eggs_free_range", + "name": "Eggs - Free Range", + "category_id": "dairy", + "aliases": [ + "eggs", + "eggs free range", + "eggs - free ranges", + "eggs free range", + "free range eggs" + ], + "default_unit": "ea", + "default_quantity": 12, + "price": 10.09, + "brands": [ + "Loblaws", + "Frenz", + "FreshCo", + "No Frills", + "Woodland", + "Farmer Brown" + ], + "image_hint": "eggs_free_range", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "eggs" + ], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_eggs_cage", + "name": "Eggs - Cage", + "category_id": "dairy", + "aliases": [ + "budget eggs", + "cage eggs", + "eggs", + "eggs cage", + "eggs - cages", + "eggs cage" + ], + "default_unit": "ea", + "default_quantity": 12, + "price": 6.89, + "brands": [ + "Food Basics", + "Metro", + "Sobeys", + "Value" + ], + "image_hint": "eggs", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "eggs" + ], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cream", + "name": "Cream - Fresh", + "category_id": "dairy", + "aliases": [ + "cream", + "cream fresh", + "cream - freshs", + "cream fresh", + "fresh cream", + "pouring cream" + ], + "default_unit": "mL", + "default_quantity": 300, + "price": 5.63, + "brands": [ + "Real Canadian Superstore", + "Longo's", + "Loblaws", + "Meadow Fresh" + ], + "image_hint": "cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_sour_cream", + "name": "Sour Cream", + "category_id": "dairy", + "aliases": [ + "sour cream", + "sour creams" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.99, + "brands": [ + "Longo's", + "Sobeys", + "Loblaws", + "Meadow Fresh" + ], + "image_hint": "sour_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_apples_gala", + "name": "Apples - Gala", + "category_id": "produce", + "aliases": [ + "apples", + "apples gala", + "apples - galas", + "apples gala", + "gala apples" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.58, + "image_hint": "apples_gala", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_apples_granny_smith", + "name": "Apples - Granny Smith", + "category_id": "produce", + "aliases": [ + "apples", + "apples granny smith", + "apples - granny smiths", + "apples granny smith", + "granny smith", + "green apples" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.85, + "image_hint": "apples_granny_smith", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_bananas", + "name": "Bananas", + "category_id": "produce", + "aliases": [ + "banana", + "bananas" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.04, + "image_hint": "bananas", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_oranges", + "name": "Oranges", + "category_id": "produce", + "aliases": [ + "orange", + "oranges" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.15, + "image_hint": "oranges", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_mandarins", + "name": "Mandarins", + "category_id": "produce", + "aliases": [ + "easy peelers", + "mandarin", + "mandarins" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 6.53, + "image_hint": "mandarins", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kiwifruit_green", + "name": "Kiwifruit - Green", + "category_id": "produce", + "aliases": [ + "green kiwifruit", + "kiwi", + "kiwifruit", + "kiwifruit green", + "kiwifruit - greens", + "kiwifruit green" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 7.84, + "image_hint": "kiwifruit_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kiwifruit_gold", + "name": "Kiwifruit - Gold", + "category_id": "produce", + "aliases": [ + "gold kiwifruit", + "kiwifruit", + "kiwifruit gold", + "kiwifruit - golds", + "kiwifruit gold", + "sungold" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 9.25, + "image_hint": "kiwifruit_gold", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_strawberries", + "name": "Strawberries", + "category_id": "produce", + "aliases": [ + "strawberrie", + "strawberries", + "strawberry" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 6.03, + "image_hint": "strawberries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_blueberries", + "name": "Blueberries", + "category_id": "produce", + "aliases": [ + "blueberrie", + "blueberries", + "blueberry" + ], + "default_unit": "g", + "default_quantity": 125, + "price": 7.22, + "image_hint": "blueberries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_grapes_green", + "name": "Grapes - Green", + "category_id": "produce", + "aliases": [ + "grapes", + "grapes green", + "grapes - greens", + "grapes green", + "green grapes", + "white grapes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 7.75, + "image_hint": "grapes_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_grapes_red", + "name": "Grapes - Red", + "category_id": "produce", + "aliases": [ + "grapes", + "grapes red", + "grapes - reds", + "grapes red", + "red grapes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 7.96, + "image_hint": "grapes_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_avocado", + "name": "Avocados", + "category_id": "produce", + "aliases": [ + "avo", + "avocado", + "avocados" + ], + "default_unit": "ea", + "default_quantity": 3, + "price": 2.9, + "image_hint": "avocado", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_tomatoes", + "name": "Tomatoes", + "category_id": "produce", + "aliases": [ + "tomato", + "tomatoe", + "tomatoes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 7.18, + "image_hint": "tomatoes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_tomatoes_cherry", + "name": "Cherry Tomatoes", + "category_id": "produce", + "aliases": [ + "cherry tomato", + "cherry tomatoe", + "cherry tomatoes" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.22, + "image_hint": "tomatoes_cherry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cucumber", + "name": "Cucumber", + "category_id": "produce", + "aliases": [ + "cucumber", + "cucumbers" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.01, + "image_hint": "cucumber", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_lettuce_iceberg", + "name": "Lettuce - Iceberg", + "category_id": "produce", + "aliases": [ + "iceberg lettuce", + "lettuce", + "lettuce iceberg", + "lettuce - icebergs", + "lettuce iceberg" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 4.46, + "image_hint": "lettuce_iceberg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_lettuce_cos", + "name": "Lettuce - Cos", + "category_id": "produce", + "aliases": [ + "cos lettuce", + "lettuce", + "lettuce cos", + "lettuce - co", + "lettuce cos", + "romaine" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 4.48, + "image_hint": "lettuce_cos", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_capsicum_red", + "name": "Capsicum - Red", + "category_id": "produce", + "aliases": [ + "capsicum", + "capsicum red", + "capsicum - reds", + "capsicum red", + "red capsicum", + "red pepper" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 2.6, + "image_hint": "capsicum_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_capsicum_green", + "name": "Capsicum - Green", + "category_id": "produce", + "aliases": [ + "capsicum", + "capsicum green", + "capsicum - greens", + "capsicum green", + "green capsicum", + "green pepper" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 2.15, + "image_hint": "capsicum_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_broccoli", + "name": "Broccoli", + "category_id": "produce", + "aliases": [ + "broccoli", + "broccoli head", + "broccolis" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.85, + "image_hint": "broccoli", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cauliflower", + "name": "Cauliflower", + "category_id": "produce", + "aliases": [ + "cauli", + "cauliflower", + "cauliflowers" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 4.88, + "image_hint": "cauliflower", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_carrots", + "name": "Carrots", + "category_id": "produce", + "aliases": [ + "carrot", + "carrots" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.42, + "image_hint": "carrots", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_potatoes", + "name": "Potatoes", + "category_id": "produce", + "aliases": [ + "potato", + "potatoe", + "potatoes", + "spuds" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 5.26, + "image_hint": "potatoes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kumara", + "name": "Sweet Potato", + "category_id": "produce", + "aliases": [ + "kumara", + "kumaras", + "kumera", + "sweet potato", + "sweet potato" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.9, + "image_hint": "kumara", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_onions_brown", + "name": "Onions - Brown", + "category_id": "produce", + "aliases": [ + "brown onions", + "onions", + "onions brown", + "onions - browns", + "onions brown" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.5, + "image_hint": "onions_brown", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_onions_red", + "name": "Onions - Red", + "category_id": "produce", + "aliases": [ + "onions", + "onions red", + "onions - reds", + "onions red", + "red onions" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.11, + "image_hint": "onions_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_garlic", + "name": "Garlic", + "category_id": "produce", + "aliases": [ + "garlic", + "garlic bulb", + "garlics" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 1.91, + "image_hint": "garlic", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_ginger", + "name": "Ginger", + "category_id": "produce", + "aliases": [ + "fresh ginger", + "ginger", + "gingers" + ], + "default_unit": "g", + "default_quantity": 100, + "price": 3.06, + "image_hint": "ginger", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_mushrooms_button", + "name": "Mushrooms - Button", + "category_id": "produce", + "aliases": [ + "button mushrooms", + "mushrooms", + "mushrooms button", + "mushrooms - buttons", + "mushrooms button" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.81, + "image_hint": "mushrooms_button", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_courgette", + "name": "Courgette", + "category_id": "produce", + "aliases": [ + "courgette", + "courgettes", + "zucchini" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 2.17, + "image_hint": "courgette", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_pumpkin", + "name": "Pumpkin", + "category_id": "produce", + "aliases": [ + "butternut", + "pumpkin", + "pumpkins", + "squash" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.04, + "image_hint": "pumpkin", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_spinach", + "name": "Spinach", + "category_id": "produce", + "aliases": [ + "baby spinach", + "spinach", + "spinachs" + ], + "default_unit": "g", + "default_quantity": 120, + "price": 4.56, + "image_hint": "spinach", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_chicken_breast", + "name": "Chicken Breast", + "category_id": "meat", + "aliases": [ + "chicken breast", + "chicken breast fillets", + "chicken breasts" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 17.47, + "brands": [ + "Tegel", + "Inghams", + "FreshCo", + "Walmart Canada", + "Real Canadian Superstore" + ], + "image_hint": "chicken_breast", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_thigh", + "name": "Chicken Thighs", + "category_id": "meat", + "aliases": [ + "chicken thigh", + "chicken thigh fillets", + "chicken thighs" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 16.94, + "brands": [ + "Tegel", + "Inghams", + "Metro", + "Loblaws", + "FreshCo" + ], + "image_hint": "chicken_thigh", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_drumsticks", + "name": "Chicken Drumsticks", + "category_id": "meat", + "aliases": [ + "chicken drumstick", + "chicken drumsticks", + "drumsticks" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 12.76, + "brands": [ + "Tegel", + "Inghams", + "Food Basics", + "No Frills", + "Walmart Canada" + ], + "image_hint": "chicken_drumsticks", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_whole", + "name": "Whole Chicken", + "category_id": "meat", + "aliases": [ + "whole chicken", + "whole chickens", + "whole roasting chicken" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 15.43, + "brands": [ + "Tegel", + "Costco Canada", + "Inghams", + "Real Canadian Superstore", + "Sobeys" + ], + "image_hint": "chicken_whole", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beef_mince", + "name": "Beef Mince", + "category_id": "meat", + "aliases": [ + "beef mince", + "beef minces", + "ground beef", + "mince" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 16.52, + "brands": [ + "No Frills", + "FreshCo", + "Angus", + "Loblaws" + ], + "image_hint": "beef_mince", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beef_steak", + "name": "Beef Steak", + "category_id": "meat", + "aliases": [ + "beef steak", + "beef steaks", + "scotch fillet", + "sirloin" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 33.81, + "brands": [ + "Angus", + "Premium", + "FreshCo", + "Longo's", + "Sobeys" + ], + "image_hint": "beef_steak", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "bbq_meat_group", + "priority_level": 1 + }, + { + "id": "prod_lamb_chops", + "name": "Lamb Chops", + "category_id": "meat", + "aliases": [ + "lamb chop", + "lamb chops", + "lamb loin chops" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 28.07, + "brands": [ + "Metro", + "Loblaws", + "Coastal Spring", + "Food Basics", + "Silver Fern Farms" + ], + "image_hint": "lamb_chops", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_lamb_leg", + "name": "Lamb Leg", + "category_id": "meat", + "aliases": [ + "lamb leg", + "lamb legs", + "leg of lamb" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 20.57, + "brands": [ + "Coastal Spring", + "Food Basics", + "No Frills", + "Silver Fern Farms", + "Sobeys" + ], + "image_hint": "lamb_leg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_pork_chops", + "name": "Pork Chops", + "category_id": "meat", + "aliases": [ + "pork chop", + "pork chops", + "pork loin chops" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 18.46, + "image_hint": "pork_chops", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bacon", + "name": "Bacon", + "category_id": "meat", + "aliases": [ + "bacon", + "bacons", + "middle bacon", + "streaky bacon" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 8.81, + "brands": [ + "Food Basics", + "Longo's", + "Beehive", + "Sobeys", + "Freedom Farms" + ], + "image_hint": "bacon", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_sausages", + "name": "Sausages", + "category_id": "meat", + "aliases": [ + "bangers", + "pork sausages", + "sausage", + "sausages" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 13.53, + "brands": [ + "Food Basics", + "Farmers Union", + "Longo's", + "Loblaws" + ], + "image_hint": "sausages", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "bbq_meat_group", + "priority_level": 1 + }, + { + "id": "prod_salami", + "name": "Salami", + "category_id": "meat", + "aliases": [ + "italian salami", + "salami", + "salamis" + ], + "default_unit": "g", + "default_quantity": 100, + "price": 6.68, + "brands": [ + "No Frills", + "Costco Canada", + "Longo's", + "Continental" + ], + "image_hint": "salami", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ham", + "name": "Ham", + "category_id": "meat", + "aliases": [ + "deli ham", + "ham", + "hams", + "leg ham" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 8.59, + "brands": [ + "Beehive", + "Real Canadian Superstore", + "Metro", + "Loblaws" + ], + "image_hint": "ham", + "tags": [], + "collections": [ + "christmas" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_salmon_fresh", + "name": "Salmon - Fresh", + "category_id": "meat", + "aliases": [ + "fresh salmon", + "salmon", + "salmon fresh", + "salmon - freshs", + "salmon fillet", + "salmon fresh" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 41.13, + "brands": [ + "Real Canadian Superstore", + "Regal", + "Loblaws", + "FreshCo" + ], + "image_hint": "salmon_fresh", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_fish_hoki", + "name": "Hoki Fillets", + "category_id": "meat", + "aliases": [ + "hoki", + "hoki fillet", + "hoki fillets", + "white fish" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 20.75, + "brands": [ + "Food Basics", + "Sanford", + "Sobeys", + "FreshCo" + ], + "image_hint": "fish_hoki", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_prawns", + "name": "Prawns - Cooked", + "category_id": "meat", + "aliases": [ + "cooked prawns", + "prawns", + "prawns cooked", + "prawns - cookeds", + "prawns cooked", + "shrimp" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 33.89, + "brands": [], + "image_hint": "prawns", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_mussels", + "name": "Mussels - Green Lipped", + "category_id": "meat", + "aliases": [ + "green lipped mussels", + "mussels", + "mussels green lipped", + "mussels - green lippeds", + "mussels green lipped" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 16.19, + "brands": [ + "Real Canadian Superstore", + "Sanford", + "Sobeys", + "Walmart Canada" + ], + "image_hint": "mussels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bread_white", + "name": "Bread - White", + "category_id": "bakery", + "aliases": [ + "bread", + "bread white", + "bread - whites", + "bread white", + "sandwich bread", + "white bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 3.17, + "brands": [ + "Costco Canada", + "Freyas", + "Vogels", + "FreshCo", + "Sobeys" + ], + "image_hint": "bread_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_wholemeal", + "name": "Bread - Wholemeal", + "category_id": "bakery", + "aliases": [ + "bread", + "bread wholemeal", + "bread - wholemeals", + "bread wholemeal", + "brown bread", + "wholemeal bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 3.48, + "brands": [ + "Food Basics", + "Walmart Canada", + "Sobeys", + "Vogels" + ], + "image_hint": "bread_wholemeal", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [ + "wholegrain" + ], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_vogels", + "name": "Bread - Vogels", + "category_id": "bakery", + "aliases": [ + "bread", + "bread vogels", + "bread - vogel", + "bread vogels", + "seed bread", + "vogels bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 5.45, + "brands": [ + "No Frills", + "Food Basics", + "Metro", + "Vogels" + ], + "image_hint": "bread_vogels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_rolls", + "name": "Bread Rolls", + "category_id": "bakery", + "aliases": [ + "bread roll", + "bread rolls", + "dinner rolls", + "white rolls" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.28, + "brands": [ + "Metro", + "Bakery", + "Loblaws", + "Longo's" + ], + "image_hint": "bread_rolls", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bagels", + "name": "Bagels", + "category_id": "bakery", + "aliases": [ + "bagel", + "bagels", + "plain bagels" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.11, + "brands": [], + "image_hint": "bagels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_english_muffins", + "name": "English Muffins", + "category_id": "bakery", + "aliases": [ + "english muffin", + "english muffins", + "muffins" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.33, + "brands": [], + "image_hint": "english_muffins", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wraps", + "name": "Wraps", + "category_id": "bakery", + "aliases": [ + "flour tortillas", + "tortilla wraps", + "wrap", + "wraps" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.83, + "brands": [ + "Costco Canada", + "Mission", + "FreshCo", + "Sobeys", + "Farrah's" + ], + "image_hint": "wraps", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_pita_bread", + "name": "Pita Bread", + "category_id": "bakery", + "aliases": [ + "pita bread", + "pita breads", + "pita pocket" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.25, + "brands": [ + "Food Basics", + "Costco Canada", + "Sobeys", + "Farrah's" + ], + "image_hint": "pita_bread", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_croissants", + "name": "Croissants", + "category_id": "bakery", + "aliases": [ + "butter croissants", + "croissant", + "croissants" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 6.72, + "brands": [ + "Costco Canada", + "Bakery", + "Walmart Canada", + "Loblaws" + ], + "image_hint": "croissants", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_peas", + "name": "Frozen Peas", + "category_id": "frozen", + "aliases": [ + "frozen pea", + "frozen peas", + "peas frozen" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.18, + "brands": [], + "image_hint": "frozen_peas", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_mixed_veg", + "name": "Frozen Mixed Vegetables", + "category_id": "frozen", + "aliases": [ + "frozen mixed vegetable", + "frozen mixed vegetables", + "frozen vegetables", + "mixed veg" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 6.25, + "brands": [], + "image_hint": "frozen_mixed_veg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_chips", + "name": "Frozen Chips", + "category_id": "frozen", + "aliases": [ + "french fries", + "frozen chip", + "frozen chips", + "oven chips" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.98, + "brands": [ + "McCain", + "Real Canadian Superstore", + "Walmart Canada", + "FreshCo" + ], + "image_hint": "frozen_chips", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ice_cream_vanilla", + "name": "Ice Cream - Vanilla", + "category_id": "frozen", + "aliases": [ + "ice cream", + "ice cream vanilla", + "ice cream - vanillas", + "ice cream vanilla", + "vanilla ice cream" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 8.35, + "brands": [ + "Much Moore", + "Costco Canada", + "Metro", + "FreshCo" + ], + "image_hint": "ice_cream_vanilla", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ice_cream_hokey_pokey", + "name": "Ice Cream - Hokey Pokey", + "category_id": "frozen", + "aliases": [ + "hokey pokey ice cream", + "ice cream", + "ice cream hokey pokey", + "ice cream - hokey pokeys", + "ice cream hokey pokey" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 9.97, + "brands": [], + "image_hint": "ice_cream_hokey_pokey", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_pizza", + "name": "Frozen Pizza", + "category_id": "frozen", + "aliases": [ + "frozen pizza", + "frozen pizzas", + "pizza" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 6.9, + "brands": [ + "McCain", + "Loblaws", + "Food Basics", + "Dr Oetker", + "Real Canadian Superstore" + ], + "image_hint": "frozen_pizza", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_fish_fingers", + "name": "Fish Fingers", + "category_id": "frozen", + "aliases": [ + "fish finger", + "fish fingers", + "fish sticks" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 8.25, + "brands": [ + "Food Basics", + "FreshCo", + "Walmart Canada", + "Birds Eye" + ], + "image_hint": "fish_fingers", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [ + "fish" + ], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_berries", + "name": "Frozen Mixed Berries", + "category_id": "frozen", + "aliases": [ + "frozen berries", + "frozen mixed berrie", + "frozen mixed berries" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 6.79, + "brands": [ + "No Frills", + "Longo's", + "Value", + "FreshCo" + ], + "image_hint": "frozen_berries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_rice_white", + "name": "Rice - White", + "category_id": "pantry", + "aliases": [ + "long grain rice", + "rice", + "rice white", + "rice - whites", + "rice white", + "white rice" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.57, + "brands": [ + "Real Canadian Superstore", + "Longo's", + "Sunrice", + "FreshCo" + ], + "image_hint": "rice_white", + "tags": [ + "gluten_free", + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [ + "gluten_free" + ], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "rice_group", + "priority_level": 3 + }, + { + "id": "prod_rice_basmati", + "name": "Rice - Basmati", + "category_id": "pantry", + "aliases": [ + "basmati rice", + "rice", + "rice basmati", + "rice - basmatis", + "rice basmati" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.79, + "brands": [ + "FreshCo", + "Tilda", + "Walmart Canada", + "Real Canadian Superstore", + "Sunrice" + ], + "image_hint": "rice_basmati", + "tags": [ + "gluten_free", + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [ + "gluten_free" + ], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "rice_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_spaghetti", + "name": "Pasta - Spaghetti", + "category_id": "pantry", + "aliases": [ + "pasta", + "pasta spaghetti", + "pasta - spaghettis", + "pasta spaghetti", + "spaghetti" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 2.87, + "brands": [ + "Loblaws", + "Barilla", + "No Frills", + "San Remo", + "Sobeys" + ], + "image_hint": "pasta_spaghetti", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_penne", + "name": "Pasta - Penne", + "category_id": "pantry", + "aliases": [ + "pasta", + "pasta penne", + "pasta - pennes", + "pasta penne", + "penne pasta" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 2.95, + "brands": [ + "Metro", + "Barilla", + "FreshCo", + "San Remo", + "Longo's" + ], + "image_hint": "pasta_penne", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_sauce", + "name": "Pasta Sauce", + "category_id": "pantry", + "aliases": [ + "bolognese sauce", + "pasta sauce", + "pasta sauces", + "tomato pasta sauce" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 4.08, + "brands": [ + "Food Basics", + "Barilla", + "Dolmio", + "Real Canadian Superstore", + "Sobeys" + ], + "image_hint": "pasta_sauce", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_flour_plain", + "name": "Flour - Plain", + "category_id": "pantry", + "aliases": [ + "flour", + "flour plain", + "flour - plains", + "flour plain", + "plain flour", + "white flour" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.48, + "brands": [ + "Metro", + "Champion", + "FreshCo", + "Walmart Canada", + "Edmonds" + ], + "image_hint": "flour_plain", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_flour_self_raising", + "name": "Flour - Self Raising", + "category_id": "pantry", + "aliases": [ + "flour", + "flour self raising", + "flour - self raisings", + "flour self raising", + "self raising flour" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.62, + "brands": [ + "Metro", + "Champion", + "No Frills", + "Sobeys", + "Edmonds" + ], + "image_hint": "flour_self_raising", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_sugar_white", + "name": "Sugar - White", + "category_id": "pantry", + "aliases": [ + "caster sugar", + "sugar", + "sugar white", + "sugar - whites", + "sugar white", + "white sugar" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.81, + "brands": [ + "Real Canadian Superstore", + "Chelsea", + "Sobeys", + "FreshCo" + ], + "image_hint": "sugar_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_sugar_brown", + "name": "Sugar - Brown", + "category_id": "pantry", + "aliases": [ + "brown sugar", + "soft brown", + "sugar", + "sugar brown", + "sugar - browns", + "sugar brown" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.61, + "brands": [ + "Chelsea", + "Longo's", + "Metro", + "FreshCo" + ], + "image_hint": "sugar_brown", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_oil_olive", + "name": "Olive Oil", + "category_id": "pantry", + "aliases": [ + "EVOO", + "extra virgin olive oil", + "olive oil", + "olive oils" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 14.85, + "brands": [ + "Sobeys", + "Walmart Canada", + "Olivado", + "No Frills" + ], + "image_hint": "oil_olive", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_oil_vegetable", + "name": "Vegetable Oil", + "category_id": "pantry", + "aliases": [ + "canola oil", + "cooking oil", + "vegetable oil", + "vegetable oils" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 7.13, + "brands": [ + "Food Basics", + "Longo's", + "Sobeys", + "Olivani" + ], + "image_hint": "oil_vegetable", + "tags": [ + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tomatoes_canned", + "name": "Canned Tomatoes", + "category_id": "pantry", + "aliases": [ + "canned tomatoe", + "canned tomatoes", + "chopped tomatoes", + "tinned tomatoes" + ], + "default_unit": "can", + "default_quantity": 4, + "price": 2.17, + "brands": [], + "image_hint": "tomatoes_canned", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_baked_beans", + "name": "Baked Beans", + "category_id": "pantry", + "aliases": [ + "baked bean", + "baked beans", + "beans in tomato sauce" + ], + "default_unit": "can", + "default_quantity": 1, + "price": 2.53, + "brands": [ + "Metro", + "Walmart Canada", + "Loblaws", + "Heinz" + ], + "image_hint": "baked_beans", + "tags": [ + "gluten_free" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tuna", + "name": "Tuna in Oil", + "category_id": "pantry", + "aliases": [ + "canned tuna", + "tinned tuna", + "tuna in oil", + "tuna in oils" + ], + "default_unit": "can", + "default_quantity": 3, + "price": 2.92, + "brands": [ + "No Frills", + "Food Basics", + "John West", + "Loblaws" + ], + "image_hint": "tuna", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_coconut_cream", + "name": "Coconut Cream", + "category_id": "pantry", + "aliases": [ + "coconut cream", + "coconut creams", + "coconut milk" + ], + "default_unit": "can", + "default_quantity": 2, + "price": 3.43, + "brands": [ + "No Frills", + "Food Basics", + "FreshCo", + "Ayam" + ], + "image_hint": "coconut_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_peanut_butter", + "name": "Peanut Butter", + "category_id": "pantry", + "aliases": [ + "crunchy peanut butter", + "peanut butter", + "peanut butters", + "smooth peanut butter" + ], + "default_unit": "g", + "default_quantity": 380, + "price": 6.62, + "brands": [ + "Kraft", + "ETA", + "No Frills", + "Walmart Canada", + "Sobeys", + "Pic's" + ], + "image_hint": "peanut_butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_jam_strawberry", + "name": "Jam - Strawberry", + "category_id": "pantry", + "aliases": [ + "jam", + "jam strawberry", + "jam - strawberrys", + "jam strawberry", + "strawberry jam" + ], + "default_unit": "g", + "default_quantity": 340, + "price": 4.99, + "brands": [ + "Costco Canada", + "Anathoth", + "FreshCo", + "Barker's", + "Sobeys" + ], + "image_hint": "jam_strawberry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_honey", + "name": "Honey", + "category_id": "pantry", + "aliases": [ + "clover honey", + "honey", + "honeys", + "manuka honey" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 9.02, + "brands": [ + "Metro", + "Airborne", + "Manuka Health", + "No Frills", + "Longo's" + ], + "image_hint": "honey", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_marmite", + "name": "Marmite", + "category_id": "pantry", + "aliases": [ + "marmite", + "marmites", + "yeast spread" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.87, + "brands": [], + "image_hint": "marmite", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_vegemite", + "name": "Vegemite", + "category_id": "pantry", + "aliases": [ + "vegemite", + "vegemites", + "yeast spread" + ], + "default_unit": "g", + "default_quantity": 220, + "price": 5.38, + "brands": [ + "No Frills", + "Metro", + "Bega", + "FreshCo" + ], + "image_hint": "vegemite", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_soy_sauce", + "name": "Soy Sauce", + "category_id": "pantry", + "aliases": [ + "kikkoman", + "soy sauce", + "soy sauces" + ], + "default_unit": "mL", + "default_quantity": 250, + "price": 5.13, + "brands": [ + "No Frills", + "Real Canadian Superstore", + "Kikkoman", + "Walmart Canada" + ], + "image_hint": "soy_sauce", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [ + "soy" + ], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tomato_sauce", + "name": "Tomato Sauce", + "category_id": "pantry", + "aliases": [ + "ketchup", + "tomato ketchup", + "tomato sauce", + "tomato sauces" + ], + "default_unit": "mL", + "default_quantity": 560, + "price": 5.41, + "brands": [ + "FreshCo", + "Metro", + "Walmart Canada", + "Heinz" + ], + "image_hint": "tomato_sauce", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_bbq_sauce", + "name": "BBQ Sauce", + "category_id": "pantry", + "aliases": [ + "barbecue sauce", + "bbq sauce", + "bbq sauces" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 4.98, + "brands": [ + "Masterfoods", + "Costco Canada", + "Sobeys", + "Loblaws" + ], + "image_hint": "bbq_sauce", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_mayonnaise", + "name": "Mayonnaise", + "category_id": "pantry", + "aliases": [ + "mayo", + "mayonnaise", + "mayonnaises" + ], + "default_unit": "mL", + "default_quantity": 440, + "price": 6.32, + "brands": [ + "Food Basics", + "Best Foods", + "Metro", + "Walmart Canada" + ], + "image_hint": "mayonnaise", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_mustard", + "name": "Mustard", + "category_id": "pantry", + "aliases": [ + "american mustard", + "dijon mustard", + "mustard", + "mustards" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.57, + "brands": [ + "Costco Canada", + "Food Basics", + "French's", + "No Frills", + "Masterfoods" + ], + "image_hint": "mustard", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_salt", + "name": "Salt", + "category_id": "pantry", + "aliases": [ + "cooking salt", + "salt", + "salts", + "table salt" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 2.16, + "brands": [ + "Real Canadian Superstore", + "Walmart Canada", + "Sobeys", + "Cerebos" + ], + "image_hint": "salt", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_pepper", + "name": "Black Pepper", + "category_id": "pantry", + "aliases": [ + "black pepper", + "black peppers", + "ground pepper" + ], + "default_unit": "g", + "default_quantity": 50, + "price": 4.32, + "brands": [ + "Masterfoods", + "Costco Canada", + "Longo's", + "Food Basics" + ], + "image_hint": "pepper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_stock_cubes_chicken", + "name": "Stock Cubes - Chicken", + "category_id": "pantry", + "aliases": [ + "bouillon", + "chicken stock", + "stock cubes", + "stock cubes chicken", + "stock cubes - chickens", + "stock cubes chicken" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 2.96, + "brands": [ + "Metro", + "Continental", + "Maggi", + "Loblaws", + "Real Canadian Superstore" + ], + "image_hint": "stock_cubes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_stock_cubes_beef", + "name": "Stock Cubes - Beef", + "category_id": "pantry", + "aliases": [ + "beef stock", + "stock cubes", + "stock cubes beef", + "stock cubes - beefs", + "stock cubes beef" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 2.97, + "brands": [ + "Costco Canada", + "Continental", + "Maggi", + "Walmart Canada", + "Real Canadian Superstore" + ], + "image_hint": "stock_cubes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_coffee_instant", + "name": "Instant Coffee", + "category_id": "beverages", + "aliases": [ + "coffee", + "instant coffee", + "instant coffees", + "nescafe" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 13.66, + "brands": [ + "Metro", + "Robert Harris", + "Gregg's", + "Nescafe", + "Longo's", + "Walmart Canada" + ], + "image_hint": "coffee_instant", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_coffee_ground", + "name": "Ground Coffee", + "category_id": "beverages", + "aliases": [ + "filter coffee", + "ground coffee", + "ground coffees" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 9.67, + "brands": [ + "Robert Harris", + "Loblaws", + "L'affare", + "No Frills", + "Longo's", + "Vittoria" + ], + "image_hint": "coffee_ground", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tea_black", + "name": "Tea - Black", + "category_id": "beverages", + "aliases": [ + "black tea", + "tea", + "tea black", + "tea - blacks", + "tea bags", + "tea black" + ], + "default_unit": "ea", + "default_quantity": 100, + "price": 7.91, + "brands": [ + "Metro", + "Loblaws", + "Bell", + "No Frills", + "Twinings", + "Dilmah" + ], + "image_hint": "tea_black", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tea_green", + "name": "Tea - Green", + "category_id": "beverages", + "aliases": [ + "green tea", + "tea", + "tea green", + "tea - greens", + "tea green" + ], + "default_unit": "ea", + "default_quantity": 40, + "price": 6.84, + "brands": [ + "Costco Canada", + "FreshCo", + "No Frills", + "Twinings", + "Dilmah" + ], + "image_hint": "tea_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_juice_orange", + "name": "Orange Juice", + "category_id": "beverages", + "aliases": [ + "OJ", + "fresh orange juice", + "orange juice", + "orange juices" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 7.47, + "brands": [ + "Costco Canada", + "Just Juice", + "Charlies", + "Real Canadian Superstore", + "Sobeys" + ], + "image_hint": "juice_orange", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_juice_apple", + "name": "Apple Juice", + "category_id": "beverages", + "aliases": [ + "apple juice", + "apple juices", + "fresh apple juice" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 7.29, + "brands": [ + "Loblaws", + "Just Juice", + "Food Basics", + "Longo's", + "Charlies" + ], + "image_hint": "juice_apple", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soft_drink_coke", + "name": "Coca Cola", + "category_id": "beverages", + "aliases": [ + "coca cola", + "coca colas", + "coke", + "cola" + ], + "default_unit": "L", + "default_quantity": 2.25, + "price": 4.88, + "brands": [ + "No Frills", + "Real Canadian Superstore", + "Coca-Cola", + "Loblaws" + ], + "image_hint": "coke", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soft_drink_lemonade", + "name": "Lemonade", + "category_id": "beverages", + "aliases": [ + "7up", + "lemonade", + "lemonades", + "sprite" + ], + "default_unit": "L", + "default_quantity": 2.25, + "price": 5.6, + "brands": [ + "Schweppes", + "FreshCo", + "No Frills", + "Longo's", + "Sprite" + ], + "image_hint": "lemonade", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_water_still", + "name": "Water - Still", + "category_id": "beverages", + "aliases": [ + "bottled water", + "spring water", + "water", + "water still", + "water - stills", + "water still" + ], + "default_unit": "L", + "default_quantity": 1.5, + "price": 2.55, + "brands": [ + "Pump", + "Metro", + "Loblaws", + "FreshCo", + "Evian" + ], + "image_hint": "water_still", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_water_sparkling", + "name": "Water - Sparkling", + "category_id": "beverages", + "aliases": [ + "soda water", + "sparkling water", + "water", + "water sparkling", + "water - sparklings", + "water sparkling" + ], + "default_unit": "L", + "default_quantity": 1.5, + "price": 3.4, + "brands": [ + "Food Basics", + "Schweppes", + "San Pellegrino", + "FreshCo", + "Real Canadian Superstore" + ], + "image_hint": "water_sparkling", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beer", + "name": "Beer", + "category_id": "beverages", + "aliases": [ + "ale", + "beer", + "beers", + "lager" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 27.14, + "brands": [ + "Costco Canada", + "Metro", + "DB Export", + "No Frills", + "Steinlager", + "Speights" + ], + "image_hint": "beer", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wine_red", + "name": "Wine - Red", + "category_id": "beverages", + "aliases": [ + "red wine", + "wine", + "wine red", + "wine - reds", + "wine red" + ], + "default_unit": "bottle", + "default_quantity": 1, + "price": 18.2, + "brands": [ + "Costco Canada", + "FreshCo", + "Villa Maria", + "Longo's", + "Oyster Bay" + ], + "image_hint": "wine_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wine_white", + "name": "Wine - White", + "category_id": "beverages", + "aliases": [ + "sauvignon blanc", + "white wine", + "wine", + "wine white", + "wine - whites", + "wine white" + ], + "default_unit": "bottle", + "default_quantity": 1, + "price": 15.22, + "brands": [ + "Metro", + "Cloudy Bay", + "Loblaws", + "Villa Maria", + "Walmart Canada", + "Oyster Bay" + ], + "image_hint": "wine_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_cornflakes", + "name": "Cornflakes", + "category_id": "snacks", + "aliases": [ + "cornflake", + "cornflakes", + "kelloggs cornflakes" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 7.99, + "brands": [ + "Metro", + "Walmart Canada", + "Kelloggs", + "Loblaws" + ], + "image_hint": "cereal_cornflakes", + "tags": [ + "gluten_free" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_weet_bix", + "name": "Weet-Bix", + "category_id": "snacks", + "aliases": [ + "weet bix", + "weet-bix", + "weet-bixs", + "weetbix", + "wheat biscuits" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 9.15, + "brands": [], + "image_hint": "cereal_weet_bix", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_muesli", + "name": "Muesli", + "category_id": "snacks", + "aliases": [ + "muesli", + "mueslis", + "toasted muesli" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 8.71, + "brands": [ + "Costco Canada", + "Metro", + "Longo's", + "Hubbards" + ], + "image_hint": "cereal_muesli", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_oats_rolled", + "name": "Rolled Oats", + "category_id": "snacks", + "aliases": [ + "oats", + "porridge oats", + "rolled oat", + "rolled oats" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 6.47, + "brands": [ + "Real Canadian Superstore", + "Walmart Canada", + "Harraways", + "Food Basics" + ], + "image_hint": "oats_rolled", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chips_salt", + "name": "Potato Chips - Salt", + "category_id": "snacks", + "aliases": [ + "crisps", + "potato chips", + "potato chips salt", + "potato chips - salts", + "potato chips salt", + "ready salted chips" + ], + "default_unit": "g", + "default_quantity": 150, + "price": 4.46, + "brands": [ + "Food Basics", + "FreshCo", + "Bluebird", + "Eta", + "Real Canadian Superstore" + ], + "image_hint": "chips_salt", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chips_chicken", + "name": "Potato Chips - Chicken", + "category_id": "snacks", + "aliases": [ + "chicken chips", + "potato chips", + "potato chips chicken", + "potato chips - chickens", + "potato chips chicken" + ], + "default_unit": "g", + "default_quantity": 150, + "price": 3.96, + "brands": [ + "Loblaws", + "Food Basics", + "No Frills", + "Bluebird", + "Eta" + ], + "image_hint": "chips_chicken", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_crackers", + "name": "Crackers", + "category_id": "snacks", + "aliases": [ + "cracker", + "crackers", + "savoy", + "water crackers" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 3.91, + "brands": [ + "Arnott's", + "FreshCo", + "No Frills", + "Sobeys", + "Griffin's" + ], + "image_hint": "crackers", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cookies_chocolate_chip", + "name": "Chocolate Chip Cookies", + "category_id": "snacks", + "aliases": [ + "choc chip biscuits", + "chocolate chip cookie", + "chocolate chip cookies", + "cookies" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.12, + "brands": [ + "Metro", + "Cookie Time", + "Longo's", + "Sobeys", + "Griffin's" + ], + "image_hint": "cookies_chocolate_chip", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tim_tams", + "name": "Tim Tams", + "category_id": "snacks", + "aliases": [ + "chocolate biscuits", + "tim tam", + "tim tams" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.34, + "brands": [ + "No Frills", + "Metro", + "Arnott's", + "Loblaws" + ], + "image_hint": "tim_tams", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chocolate_whittakers", + "name": "Chocolate - Whittaker's", + "category_id": "snacks", + "aliases": [ + "chocolate", + "chocolate whittaker's", + "chocolate - whittaker'", + "chocolate bar", + "chocolate whittaker's", + "whittakers block" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 6.83, + "brands": [], + "image_hint": "chocolate_whittakers", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chocolate_cadbury", + "name": "Chocolate - Cadbury", + "category_id": "snacks", + "aliases": [ + "cadbury block", + "chocolate", + "chocolate cadbury", + "chocolate - cadburys", + "chocolate cadbury" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 4.78, + "brands": [ + "Real Canadian Superstore", + "Cadbury", + "Sobeys", + "FreshCo" + ], + "image_hint": "chocolate_cadbury", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_muesli_bars", + "name": "Muesli Bars", + "category_id": "snacks", + "aliases": [ + "granola bars", + "muesli bar", + "muesli bars" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.84, + "brands": [ + "Metro", + "Food Basics", + "FreshCo", + "Nice & Natural", + "Uncle Tobys" + ], + "image_hint": "muesli_bars", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_popcorn", + "name": "Popcorn", + "category_id": "snacks", + "aliases": [ + "microwave popcorn", + "popcorn", + "popcorns" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.54, + "brands": [ + "Costco Canada", + "FreshCo", + "Proper", + "Eta", + "Sobeys" + ], + "image_hint": "popcorn", + "tags": [ + "gluten_free" + ], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_nuts_mixed", + "name": "Mixed Nuts", + "category_id": "snacks", + "aliases": [ + "mixed nut", + "mixed nuts", + "roasted nuts" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 6.82, + "brands": [ + "No Frills", + "Costco Canada", + "Eta", + "FreshCo" + ], + "image_hint": "nuts_mixed", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toilet_paper", + "name": "Toilet Paper", + "category_id": "household", + "aliases": [ + "TP", + "bathroom tissue", + "toilet paper", + "toilet papers" + ], + "default_unit": "roll", + "default_quantity": 12, + "price": 13.85, + "brands": [ + "Loblaws", + "Sorbent", + "FreshCo", + "Purex", + "Sobeys" + ], + "image_hint": "toilet_paper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_paper_towels", + "name": "Paper Towels", + "category_id": "household", + "aliases": [ + "kitchen paper", + "paper towel", + "paper towels" + ], + "default_unit": "roll", + "default_quantity": 4, + "price": 9.06, + "brands": [ + "Sorbent", + "FreshCo", + "No Frills", + "Handee", + "Longo's" + ], + "image_hint": "paper_towels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tissues", + "name": "Tissues", + "category_id": "household", + "aliases": [ + "facial tissues", + "kleenex", + "tissue", + "tissues" + ], + "default_unit": "box", + "default_quantity": 4, + "price": 8.64, + "brands": [ + "Loblaws", + "Sorbent", + "FreshCo", + "Kleenex", + "Sobeys" + ], + "image_hint": "tissues", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dishwashing_liquid", + "name": "Dishwashing Liquid", + "category_id": "household", + "aliases": [ + "dish soap", + "dishwash", + "dishwashing liquid", + "dishwashing liquids" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 5.1, + "brands": [ + "Food Basics", + "Sunlight", + "Walmart Canada", + "Morning Fresh", + "Real Canadian Superstore" + ], + "image_hint": "dishwashing_liquid", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dishwasher_tablets", + "name": "Dishwasher Tablets", + "category_id": "household", + "aliases": [ + "dishwasher pods", + "dishwasher tablet", + "dishwasher tablets" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 16.77, + "brands": [ + "Earthwise", + "Metro", + "Longo's", + "Walmart Canada", + "Finish" + ], + "image_hint": "dishwasher_tablets", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_laundry_powder", + "name": "Laundry Powder", + "category_id": "household", + "aliases": [ + "laundry powder", + "laundry powders", + "washing powder" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 17.23, + "brands": [ + "Costco Canada", + "Persil", + "Metro", + "Earthwise", + "OMO", + "Sobeys" + ], + "image_hint": "laundry_powder", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_laundry_liquid", + "name": "Laundry Liquid", + "category_id": "household", + "aliases": [ + "laundry liquid", + "laundry liquids", + "washing liquid" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 16.96, + "brands": [ + "Persil", + "Earthwise", + "Food Basics", + "FreshCo", + "No Frills", + "OMO" + ], + "image_hint": "laundry_liquid", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_fabric_softener", + "name": "Fabric Softener", + "category_id": "household", + "aliases": [ + "comfort", + "downy", + "fabric softener", + "fabric softeners" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 10.79, + "brands": [ + "Earthwise", + "Comfort", + "Longo's", + "Walmart Canada", + "Real Canadian Superstore" + ], + "image_hint": "fabric_softener", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_spray_cleaner", + "name": "Spray Cleaner", + "category_id": "household", + "aliases": [ + "multi-purpose cleaner", + "spray cleaner", + "spray cleaners", + "spray n wipe" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 7.26, + "brands": [ + "Costco Canada", + "Metro", + "Jif", + "Spray n Wipe", + "Real Canadian Superstore" + ], + "image_hint": "spray_cleaner", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bleach", + "name": "Bleach", + "category_id": "household", + "aliases": [ + "bleach", + "bleachs", + "janola" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 6.66, + "brands": [ + "Costco Canada", + "Metro", + "Domestos", + "Food Basics", + "Janola" + ], + "image_hint": "bleach", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bin_bags", + "name": "Bin Bags", + "category_id": "household", + "aliases": [ + "bin bag", + "bin bags", + "garbage bags", + "rubbish bags" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 10.02, + "brands": [ + "FreshCo", + "Glad", + "Ecostore", + "Longo's", + "Walmart Canada" + ], + "image_hint": "bin_bags", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cling_film", + "name": "Cling Film", + "category_id": "household", + "aliases": [ + "cling film", + "cling films", + "glad wrap", + "plastic wrap" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 6.32, + "brands": [ + "Costco Canada", + "Loblaws", + "Multix", + "Glad", + "Sobeys" + ], + "image_hint": "cling_film", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_aluminium_foil", + "name": "Aluminium Foil", + "category_id": "household", + "aliases": [ + "alfoil", + "aluminium foil", + "aluminium foils", + "tin foil" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 7.38, + "brands": [ + "Loblaws", + "Food Basics", + "Multix", + "Alfoil", + "Walmart Canada" + ], + "image_hint": "aluminium_foil", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baking_paper", + "name": "Baking Paper", + "category_id": "household", + "aliases": [ + "baking paper", + "baking papers", + "parchment paper" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 5.44, + "brands": [ + "Metro", + "Loblaws", + "Alfoil", + "Multix", + "Longo's" + ], + "image_hint": "baking_paper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_shampoo", + "name": "Shampoo", + "category_id": "health", + "aliases": [ + "hair shampoo", + "shampoo", + "shampoos" + ], + "default_unit": "mL", + "default_quantity": 400, + "price": 10.27, + "brands": [ + "Head & Shoulders", + "Metro", + "Food Basics", + "No Frills", + "Garnier", + "Pantene" + ], + "image_hint": "shampoo", + "tags": [], + "collections": [ + "christmas" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_conditioner", + "name": "Conditioner", + "category_id": "health", + "aliases": [ + "conditioner", + "conditioners", + "hair conditioner" + ], + "default_unit": "mL", + "default_quantity": 400, + "price": 9.95, + "brands": [ + "Head & Shoulders", + "Costco Canada", + "Food Basics", + "No Frills", + "Garnier", + "Pantene" + ], + "image_hint": "conditioner", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_body_wash", + "name": "Body Wash", + "category_id": "health", + "aliases": [ + "body wash", + "body washs", + "shower gel" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 8.56, + "brands": [ + "Metro", + "Dove", + "Loblaws", + "Walmart Canada", + "Palmolive", + "Nivea" + ], + "image_hint": "body_wash", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soap_bar", + "name": "Bar Soap", + "category_id": "health", + "aliases": [ + "bar soap", + "bar soaps", + "bath soap", + "hand soap" + ], + "default_unit": "bar", + "default_quantity": 4, + "price": 5.63, + "brands": [ + "Costco Canada", + "Metro", + "Dove", + "Loblaws", + "Palmolive" + ], + "image_hint": "soap_bar", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toothpaste", + "name": "Toothpaste", + "category_id": "health", + "aliases": [ + "colgate", + "toothpaste", + "toothpastes" + ], + "default_unit": "g", + "default_quantity": 110, + "price": 6.67, + "brands": [ + "Costco Canada", + "Sensodyne", + "FreshCo", + "Walmart Canada", + "Colgate" + ], + "image_hint": "toothpaste", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toothbrush", + "name": "Toothbrush", + "category_id": "health", + "aliases": [ + "tooth brush", + "toothbrush", + "toothbrushs" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 7.37, + "brands": [ + "Loblaws", + "Oral-B", + "FreshCo", + "Longo's", + "Colgate" + ], + "image_hint": "toothbrush", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_deodorant", + "name": "Deodorant", + "category_id": "health", + "aliases": [ + "antiperspirant", + "deodorant", + "deodorants" + ], + "default_unit": "g", + "default_quantity": 50, + "price": 7.8, + "brands": [ + "Costco Canada", + "Dove", + "Rexona", + "Loblaws", + "Lynx", + "Walmart Canada" + ], + "image_hint": "deodorant", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_razor_blades", + "name": "Razor Blades", + "category_id": "health", + "aliases": [ + "gillette", + "razor blade", + "razor blades", + "shaving blades" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 19.13, + "brands": [ + "No Frills", + "Schick", + "Longo's", + "Walmart Canada", + "Gillette" + ], + "image_hint": "razor_blades", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_shaving_cream", + "name": "Shaving Cream", + "category_id": "health", + "aliases": [ + "shave gel", + "shaving cream", + "shaving creams" + ], + "default_unit": "mL", + "default_quantity": 200, + "price": 6.65, + "brands": [ + "Metro", + "Food Basics", + "FreshCo", + "Gillette", + "Nivea" + ], + "image_hint": "shaving_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_sunscreen", + "name": "Sunscreen SPF50", + "category_id": "health", + "aliases": [ + "sun cream", + "sunblock", + "sunscreen spf50", + "sunscreen spf50s" + ], + "default_unit": "mL", + "default_quantity": 200, + "price": 16.82, + "brands": [ + "Costco Canada", + "Cancer Society", + "FreshCo", + "Neutrogena", + "Walmart Canada" + ], + "image_hint": "sunscreen", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_paracetamol", + "name": "Paracetamol", + "category_id": "health", + "aliases": [ + "pain relief", + "panadol", + "paracetamol", + "paracetamols" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 10.15, + "brands": [ + "Real Canadian Superstore", + "Walmart Canada", + "Sobeys", + "Panadol" + ], + "image_hint": "paracetamol", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ibuprofen", + "name": "Ibuprofen", + "category_id": "health", + "aliases": [ + "ibuprofen", + "ibuprofens", + "nurofen", + "pain relief" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 10.09, + "brands": [ + "Nurofen", + "Food Basics", + "Costco Canada", + "Walmart Canada" + ], + "image_hint": "ibuprofen", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bandaids", + "name": "Band-Aids", + "category_id": "health", + "aliases": [ + "band aids", + "band-aid", + "band-aids", + "bandages", + "plasters" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 6.76, + "brands": [ + "Metro", + "Band-Aid", + "No Frills", + "Sobeys", + "Elastoplast" + ], + "image_hint": "bandaids", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_vitamins_c", + "name": "Vitamin C", + "category_id": "health", + "aliases": [ + "vitamin c", + "vitamin c tablets", + "vitamin cs" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 12.51, + "brands": [ + "Loblaws", + "Blackmores", + "Food Basics", + "Walmart Canada", + "Healtheries" + ], + "image_hint": "vitamins_c", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_nappies", + "name": "Nappies", + "category_id": "baby", + "aliases": [ + "baby nappies", + "diapers", + "nappie", + "nappies" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 29.36, + "brands": [ + "No Frills", + "Costco Canada", + "Huggies", + "FreshCo" + ], + "image_hint": "nappies", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baby_wipes", + "name": "Baby Wipes", + "category_id": "baby", + "aliases": [ + "baby wipe", + "baby wipes", + "wet wipes" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 6.65, + "brands": [ + "Costco Canada", + "Huggies", + "Sobeys", + "Food Basics" + ], + "image_hint": "baby_wipes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baby_formula", + "name": "Baby Formula", + "category_id": "baby", + "aliases": [ + "baby formula", + "baby formulas", + "infant formula" + ], + "default_unit": "g", + "default_quantity": 900, + "price": 28.57, + "brands": [ + "Loblaws", + "Longo's", + "Karicare", + "Real Canadian Superstore", + "Aptamil" + ], + "image_hint": "baby_formula", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dog_food_dry", + "name": "Dog Food - Dry", + "category_id": "pet", + "aliases": [ + "dog biscuits", + "dog food", + "dog food dry", + "dog food - drys", + "dog food dry", + "dog kibble" + ], + "default_unit": "kg", + "default_quantity": 3, + "price": 28.17, + "brands": [ + "Pedigree", + "Metro", + "No Frills", + "Longo's", + "Eukanuba" + ], + "image_hint": "dog_food_dry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dog_food_wet", + "name": "Dog Food - Wet", + "category_id": "pet", + "aliases": [ + "canned dog food", + "dog food", + "dog food wet", + "dog food - wets", + "dog food wet" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 21.7, + "brands": [ + "Pedigree", + "Costco Canada", + "Food Basics", + "No Frills", + "Champ" + ], + "image_hint": "dog_food_wet", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_food_dry", + "name": "Cat Food - Dry", + "category_id": "pet", + "aliases": [ + "cat biscuits", + "cat food", + "cat food dry", + "cat food - drys", + "cat food dry" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 21.91, + "brands": [ + "Costco Canada", + "Loblaws", + "No Frills", + "Whiskas", + "Fancy Feast" + ], + "image_hint": "cat_food_dry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_food_wet", + "name": "Cat Food - Wet", + "category_id": "pet", + "aliases": [ + "canned cat food", + "cat food", + "cat food wet", + "cat food - wets", + "cat food wet" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 15.2, + "brands": [ + "Costco Canada", + "Food Basics", + "FreshCo", + "Whiskas", + "Fancy Feast" + ], + "image_hint": "cat_food_wet", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_litter", + "name": "Cat Litter", + "category_id": "pet", + "aliases": [ + "cat litter", + "cat litters", + "kitty litter" + ], + "default_unit": "kg", + "default_quantity": 5, + "price": 12.7, + "brands": [ + "Catlove", + "Walmart Canada", + "Real Canadian Superstore", + "Paws", + "Sobeys" + ], + "image_hint": "cat_litter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + } + ], + "country": "Canada" +} \ No newline at end of file diff --git a/custom_components/shopping_list_manager/data/products_catalog_gb.json b/custom_components/shopping_list_manager/data/products_catalog_gb.json new file mode 100644 index 0000000..2a86578 --- /dev/null +++ b/custom_components/shopping_list_manager/data/products_catalog_gb.json @@ -0,0 +1,5423 @@ +{ + "version": "2.1.0", + "region": "GB", + "currency": "GBP", + "last_updated": "2026-02-13", + "description": "Clean UK grocery catalog based on cleaned NZ dataset (no synthetic variants)", + "products": [ + { + "id": "prod_milk_trim", + "name": "Milk - Trim", + "category_id": "dairy", + "aliases": [ + "low fat milk", + "milk", + "milk trim", + "milk - trims", + "milk trim", + "skim milk", + "trim milk" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 3.76, + "brands": [ + "Co-op", + "Iceland", + "Marks & Spencer", + "Meadow Fresh" + ], + "barcode": "9400547000019", + "image_hint": "milk_trim", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "milk" + ], + "substitution_group": "milk_group", + "priority_level": 5 + }, + { + "id": "prod_milk_whole", + "name": "Milk - Whole", + "category_id": "dairy", + "aliases": [ + "blue top milk", + "full cream milk", + "milk", + "milk whole", + "milk - wholes", + "milk whole", + "whole milk" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 4.03, + "brands": [ + "Waitrose", + "Sainsbury's", + "Aldi UK", + "Meadow Fresh" + ], + "barcode": "9400547000026", + "image_hint": "milk_whole", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "milk" + ], + "substitution_group": "milk_group", + "priority_level": 5 + }, + { + "id": "prod_butter_salted", + "name": "Butter - Salted", + "category_id": "dairy", + "aliases": [ + "butter", + "butter salted", + "butter - salteds", + "butter salted", + "salted butter" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 6.58, + "brands": [ + "Waitrose", + "Westgold", + "Iceland", + "ASDA" + ], + "image_hint": "butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_butter_unsalted", + "name": "Butter - Unsalted", + "category_id": "dairy", + "aliases": [ + "butter", + "butter unsalted", + "butter - unsalteds", + "butter unsalted", + "unsalted butter" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 6.82, + "brands": [], + "image_hint": "butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cheese_tasty", + "name": "Cheese - Tasty", + "category_id": "dairy", + "aliases": [ + "cheddar", + "cheese", + "cheese tasty", + "cheese - tastys", + "cheese block", + "cheese tasty", + "tasty cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 9.09, + "brands": [], + "image_hint": "cheese_tasty", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_edam", + "name": "Cheese - Edam", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese edam", + "cheese - edams", + "cheese edam", + "edam cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 8.92, + "brands": [], + "image_hint": "cheese_edam", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_colby", + "name": "Cheese - Colby", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese colby", + "cheese - colbys", + "cheese colby", + "colby cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 8.63, + "brands": [], + "image_hint": "cheese_colby", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_grated", + "name": "Cheese - Grated", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese grated", + "cheese - grateds", + "cheese grated", + "grated cheese", + "shredded cheese" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 6.4, + "brands": [], + "image_hint": "cheese_grated", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_yogurt_plain", + "name": "Yoghurt - Plain", + "category_id": "dairy", + "aliases": [ + "natural yogurt", + "plain yogurt", + "yogurt", + "yogurt plain", + "yogurt - plains", + "yogurt plain", + "yoghurt" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 6.28, + "brands": [ + "Tesco", + "Co-op", + "Cyclone", + "Sainsbury's", + "Meadow Fresh" + ], + "image_hint": "yogurt_plain", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "yogurt_group", + "priority_level": 4 + }, + { + "id": "prod_yogurt_greek", + "name": "Yoghurt - Greek", + "category_id": "dairy", + "aliases": [ + "greek yogurt", + "yogurt", + "yogurt greek", + "yogurt - greeks", + "yogurt greek", + "yoghurt" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 7.86, + "brands": [ + "Chobani", + "Farmers Union", + "Co-op", + "Aldi UK", + "Sainsbury's" + ], + "image_hint": "yogurt_greek", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "yogurt_group", + "priority_level": 4 + }, + { + "id": "prod_eggs_free_range", + "name": "Eggs - Free Range", + "category_id": "dairy", + "aliases": [ + "eggs", + "eggs free range", + "eggs - free ranges", + "eggs free range", + "free range eggs" + ], + "default_unit": "ea", + "default_quantity": 12, + "price": 10.2, + "brands": [ + "Tesco", + "Lidl UK", + "Frenz", + "Woodland", + "Farmer Brown", + "Marks & Spencer" + ], + "image_hint": "eggs_free_range", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "eggs" + ], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_eggs_cage", + "name": "Eggs - Cage", + "category_id": "dairy", + "aliases": [ + "budget eggs", + "cage eggs", + "eggs", + "eggs cage", + "eggs - cages", + "eggs cage" + ], + "default_unit": "ea", + "default_quantity": 12, + "price": 6.05, + "brands": [ + "Lidl UK", + "Marks & Spencer", + "ASDA", + "Value" + ], + "image_hint": "eggs", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "eggs" + ], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cream", + "name": "Cream - Fresh", + "category_id": "dairy", + "aliases": [ + "cream", + "cream fresh", + "cream - freshs", + "cream fresh", + "fresh cream", + "pouring cream" + ], + "default_unit": "mL", + "default_quantity": 300, + "price": 4.76, + "brands": [ + "Sainsbury's", + "Lidl UK", + "Aldi UK", + "Meadow Fresh" + ], + "image_hint": "cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_sour_cream", + "name": "Sour Cream", + "category_id": "dairy", + "aliases": [ + "sour cream", + "sour creams" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.36, + "brands": [ + "Co-op", + "Marks & Spencer", + "Morrisons", + "Meadow Fresh" + ], + "image_hint": "sour_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_apples_gala", + "name": "Apples - Gala", + "category_id": "produce", + "aliases": [ + "apples", + "apples gala", + "apples - galas", + "apples gala", + "gala apples" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.65, + "image_hint": "apples_gala", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_apples_granny_smith", + "name": "Apples - Granny Smith", + "category_id": "produce", + "aliases": [ + "apples", + "apples granny smith", + "apples - granny smiths", + "apples granny smith", + "granny smith", + "green apples" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.06, + "image_hint": "apples_granny_smith", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_bananas", + "name": "Bananas", + "category_id": "produce", + "aliases": [ + "banana", + "bananas" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.99, + "image_hint": "bananas", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_oranges", + "name": "Oranges", + "category_id": "produce", + "aliases": [ + "orange", + "oranges" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.49, + "image_hint": "oranges", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_mandarins", + "name": "Mandarins", + "category_id": "produce", + "aliases": [ + "easy peelers", + "mandarin", + "mandarins" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.41, + "image_hint": "mandarins", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kiwifruit_green", + "name": "Kiwifruit - Green", + "category_id": "produce", + "aliases": [ + "green kiwifruit", + "kiwi", + "kiwifruit", + "kiwifruit green", + "kiwifruit - greens", + "kiwifruit green" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 7.12, + "image_hint": "kiwifruit_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kiwifruit_gold", + "name": "Kiwifruit - Gold", + "category_id": "produce", + "aliases": [ + "gold kiwifruit", + "kiwifruit", + "kiwifruit gold", + "kiwifruit - golds", + "kiwifruit gold", + "sungold" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 8.23, + "image_hint": "kiwifruit_gold", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_strawberries", + "name": "Strawberries", + "category_id": "produce", + "aliases": [ + "strawberrie", + "strawberries", + "strawberry" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 6.17, + "image_hint": "strawberries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_blueberries", + "name": "Blueberries", + "category_id": "produce", + "aliases": [ + "blueberrie", + "blueberries", + "blueberry" + ], + "default_unit": "g", + "default_quantity": 125, + "price": 7.07, + "image_hint": "blueberries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_grapes_green", + "name": "Grapes - Green", + "category_id": "produce", + "aliases": [ + "grapes", + "grapes green", + "grapes - greens", + "grapes green", + "green grapes", + "white grapes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 7.34, + "image_hint": "grapes_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_grapes_red", + "name": "Grapes - Red", + "category_id": "produce", + "aliases": [ + "grapes", + "grapes red", + "grapes - reds", + "grapes red", + "red grapes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 8.11, + "image_hint": "grapes_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_avocado", + "name": "Avocados", + "category_id": "produce", + "aliases": [ + "avo", + "avocado", + "avocados" + ], + "default_unit": "ea", + "default_quantity": 3, + "price": 3.02, + "image_hint": "avocado", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_tomatoes", + "name": "Tomatoes", + "category_id": "produce", + "aliases": [ + "tomato", + "tomatoe", + "tomatoes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 6.78, + "image_hint": "tomatoes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_tomatoes_cherry", + "name": "Cherry Tomatoes", + "category_id": "produce", + "aliases": [ + "cherry tomato", + "cherry tomatoe", + "cherry tomatoes" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.51, + "image_hint": "tomatoes_cherry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cucumber", + "name": "Cucumber", + "category_id": "produce", + "aliases": [ + "cucumber", + "cucumbers" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.02, + "image_hint": "cucumber", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_lettuce_iceberg", + "name": "Lettuce - Iceberg", + "category_id": "produce", + "aliases": [ + "iceberg lettuce", + "lettuce", + "lettuce iceberg", + "lettuce - icebergs", + "lettuce iceberg" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 4.07, + "image_hint": "lettuce_iceberg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_lettuce_cos", + "name": "Lettuce - Cos", + "category_id": "produce", + "aliases": [ + "cos lettuce", + "lettuce", + "lettuce cos", + "lettuce - co", + "lettuce cos", + "romaine" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.68, + "image_hint": "lettuce_cos", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_capsicum_red", + "name": "Capsicum - Red", + "category_id": "produce", + "aliases": [ + "capsicum", + "capsicum red", + "capsicum - reds", + "capsicum red", + "red capsicum", + "red pepper" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 2.33, + "image_hint": "capsicum_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_capsicum_green", + "name": "Capsicum - Green", + "category_id": "produce", + "aliases": [ + "capsicum", + "capsicum green", + "capsicum - greens", + "capsicum green", + "green capsicum", + "green pepper" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 1.95, + "image_hint": "capsicum_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_broccoli", + "name": "Broccoli", + "category_id": "produce", + "aliases": [ + "broccoli", + "broccoli head", + "broccolis" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.6, + "image_hint": "broccoli", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cauliflower", + "name": "Cauliflower", + "category_id": "produce", + "aliases": [ + "cauli", + "cauliflower", + "cauliflowers" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 4.98, + "image_hint": "cauliflower", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_carrots", + "name": "Carrots", + "category_id": "produce", + "aliases": [ + "carrot", + "carrots" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 2.91, + "image_hint": "carrots", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_potatoes", + "name": "Potatoes", + "category_id": "produce", + "aliases": [ + "potato", + "potatoe", + "potatoes", + "spuds" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 4.89, + "image_hint": "potatoes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kumara", + "name": "Sweet Potato", + "category_id": "produce", + "aliases": [ + "kumara", + "kumaras", + "kumera", + "sweet potato", + "sweet potato" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.9, + "image_hint": "kumara", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_onions_brown", + "name": "Onions - Brown", + "category_id": "produce", + "aliases": [ + "brown onions", + "onions", + "onions brown", + "onions - browns", + "onions brown" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.89, + "image_hint": "onions_brown", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_onions_red", + "name": "Onions - Red", + "category_id": "produce", + "aliases": [ + "onions", + "onions red", + "onions - reds", + "onions red", + "red onions" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.86, + "image_hint": "onions_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_garlic", + "name": "Garlic", + "category_id": "produce", + "aliases": [ + "garlic", + "garlic bulb", + "garlics" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 1.89, + "image_hint": "garlic", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_ginger", + "name": "Ginger", + "category_id": "produce", + "aliases": [ + "fresh ginger", + "ginger", + "gingers" + ], + "default_unit": "g", + "default_quantity": 100, + "price": 3.01, + "image_hint": "ginger", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_mushrooms_button", + "name": "Mushrooms - Button", + "category_id": "produce", + "aliases": [ + "button mushrooms", + "mushrooms", + "mushrooms button", + "mushrooms - buttons", + "mushrooms button" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.65, + "image_hint": "mushrooms_button", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_courgette", + "name": "Courgette", + "category_id": "produce", + "aliases": [ + "courgette", + "courgettes", + "zucchini" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 2.05, + "image_hint": "courgette", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_pumpkin", + "name": "Pumpkin", + "category_id": "produce", + "aliases": [ + "butternut", + "pumpkin", + "pumpkins", + "squash" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.12, + "image_hint": "pumpkin", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_spinach", + "name": "Spinach", + "category_id": "produce", + "aliases": [ + "baby spinach", + "spinach", + "spinachs" + ], + "default_unit": "g", + "default_quantity": 120, + "price": 3.71, + "image_hint": "spinach", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_chicken_breast", + "name": "Chicken Breast", + "category_id": "meat", + "aliases": [ + "chicken breast", + "chicken breast fillets", + "chicken breasts" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 15.64, + "brands": [ + "Tegel", + "Inghams", + "Lidl UK", + "ASDA", + "Aldi UK" + ], + "image_hint": "chicken_breast", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_thigh", + "name": "Chicken Thighs", + "category_id": "meat", + "aliases": [ + "chicken thigh", + "chicken thigh fillets", + "chicken thighs" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 14.38, + "brands": [ + "Tegel", + "Inghams", + "Iceland", + "Lidl UK", + "Waitrose" + ], + "image_hint": "chicken_thigh", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_drumsticks", + "name": "Chicken Drumsticks", + "category_id": "meat", + "aliases": [ + "chicken drumstick", + "chicken drumsticks", + "drumsticks" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 12.14, + "brands": [ + "Tegel", + "Inghams", + "Iceland", + "Sainsbury's", + "Marks & Spencer" + ], + "image_hint": "chicken_drumsticks", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_whole", + "name": "Whole Chicken", + "category_id": "meat", + "aliases": [ + "whole chicken", + "whole chickens", + "whole roasting chicken" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 12.93, + "brands": [ + "Tegel", + "Inghams", + "Co-op", + "Lidl UK", + "Morrisons" + ], + "image_hint": "chicken_whole", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beef_mince", + "name": "Beef Mince", + "category_id": "meat", + "aliases": [ + "beef mince", + "beef minces", + "ground beef", + "mince" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 14.66, + "brands": [ + "Morrisons", + "Tesco", + "ASDA", + "Angus" + ], + "image_hint": "beef_mince", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beef_steak", + "name": "Beef Steak", + "category_id": "meat", + "aliases": [ + "beef steak", + "beef steaks", + "scotch fillet", + "sirloin" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 27.19, + "brands": [ + "Iceland", + "Angus", + "Premium", + "Waitrose", + "Sainsbury's" + ], + "image_hint": "beef_steak", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "bbq_meat_group", + "priority_level": 1 + }, + { + "id": "prod_lamb_chops", + "name": "Lamb Chops", + "category_id": "meat", + "aliases": [ + "lamb chop", + "lamb chops", + "lamb loin chops" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 24.98, + "brands": [ + "Iceland", + "Tesco", + "Coastal Spring", + "ASDA", + "Silver Fern Farms" + ], + "image_hint": "lamb_chops", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_lamb_leg", + "name": "Lamb Leg", + "category_id": "meat", + "aliases": [ + "lamb leg", + "lamb legs", + "leg of lamb" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 19.33, + "brands": [ + "Tesco", + "Coastal Spring", + "Co-op", + "Waitrose", + "Silver Fern Farms" + ], + "image_hint": "lamb_leg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_pork_chops", + "name": "Pork Chops", + "category_id": "meat", + "aliases": [ + "pork chop", + "pork chops", + "pork loin chops" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 16.57, + "image_hint": "pork_chops", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bacon", + "name": "Bacon", + "category_id": "meat", + "aliases": [ + "bacon", + "bacons", + "middle bacon", + "streaky bacon" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 7.26, + "brands": [ + "Tesco", + "Lidl UK", + "Waitrose", + "Beehive", + "Freedom Farms" + ], + "image_hint": "bacon", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_sausages", + "name": "Sausages", + "category_id": "meat", + "aliases": [ + "bangers", + "pork sausages", + "sausage", + "sausages" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 11.04, + "brands": [ + "Co-op", + "Sainsbury's", + "Farmers Union", + "Waitrose" + ], + "image_hint": "sausages", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "bbq_meat_group", + "priority_level": 1 + }, + { + "id": "prod_salami", + "name": "Salami", + "category_id": "meat", + "aliases": [ + "italian salami", + "salami", + "salamis" + ], + "default_unit": "g", + "default_quantity": 100, + "price": 6.17, + "brands": [ + "Waitrose", + "Sainsbury's", + "Continental", + "Aldi UK" + ], + "image_hint": "salami", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ham", + "name": "Ham", + "category_id": "meat", + "aliases": [ + "deli ham", + "ham", + "hams", + "leg ham" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 7.61, + "brands": [ + "Beehive", + "Co-op", + "ASDA", + "Aldi UK" + ], + "image_hint": "ham", + "tags": [], + "collections": [ + "christmas" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_salmon_fresh", + "name": "Salmon - Fresh", + "category_id": "meat", + "aliases": [ + "fresh salmon", + "salmon", + "salmon fresh", + "salmon - freshs", + "salmon fillet", + "salmon fresh" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 40.34, + "brands": [ + "Waitrose", + "Sainsbury's", + "Tesco", + "Regal" + ], + "image_hint": "salmon_fresh", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_fish_hoki", + "name": "Hoki Fillets", + "category_id": "meat", + "aliases": [ + "hoki", + "hoki fillet", + "hoki fillets", + "white fish" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 19.66, + "brands": [ + "Sainsbury's", + "Iceland", + "Sanford", + "Marks & Spencer" + ], + "image_hint": "fish_hoki", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_prawns", + "name": "Prawns - Cooked", + "category_id": "meat", + "aliases": [ + "cooked prawns", + "prawns", + "prawns cooked", + "prawns - cookeds", + "prawns cooked", + "shrimp" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 27.19, + "brands": [], + "image_hint": "prawns", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_mussels", + "name": "Mussels - Green Lipped", + "category_id": "meat", + "aliases": [ + "green lipped mussels", + "mussels", + "mussels green lipped", + "mussels - green lippeds", + "mussels green lipped" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 13.89, + "brands": [ + "Co-op", + "Lidl UK", + "Sanford", + "Marks & Spencer" + ], + "image_hint": "mussels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bread_white", + "name": "Bread - White", + "category_id": "bakery", + "aliases": [ + "bread", + "bread white", + "bread - whites", + "bread white", + "sandwich bread", + "white bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 3.06, + "brands": [ + "Iceland", + "Freyas", + "Lidl UK", + "Vogels", + "Sainsbury's" + ], + "image_hint": "bread_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_wholemeal", + "name": "Bread - Wholemeal", + "category_id": "bakery", + "aliases": [ + "bread", + "bread wholemeal", + "bread - wholemeals", + "bread wholemeal", + "brown bread", + "wholemeal bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 3.52, + "brands": [ + "Sainsbury's", + "Iceland", + "Lidl UK", + "Vogels" + ], + "image_hint": "bread_wholemeal", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [ + "wholegrain" + ], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_vogels", + "name": "Bread - Vogels", + "category_id": "bakery", + "aliases": [ + "bread", + "bread vogels", + "bread - vogel", + "bread vogels", + "seed bread", + "vogels bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 5.04, + "brands": [ + "Co-op", + "Marks & Spencer", + "Waitrose", + "Vogels" + ], + "image_hint": "bread_vogels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_rolls", + "name": "Bread Rolls", + "category_id": "bakery", + "aliases": [ + "bread roll", + "bread rolls", + "dinner rolls", + "white rolls" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.06, + "brands": [ + "Sainsbury's", + "Iceland", + "Bakery", + "Marks & Spencer" + ], + "image_hint": "bread_rolls", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bagels", + "name": "Bagels", + "category_id": "bakery", + "aliases": [ + "bagel", + "bagels", + "plain bagels" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.69, + "brands": [], + "image_hint": "bagels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_english_muffins", + "name": "English Muffins", + "category_id": "bakery", + "aliases": [ + "english muffin", + "english muffins", + "muffins" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.63, + "brands": [], + "image_hint": "english_muffins", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wraps", + "name": "Wraps", + "category_id": "bakery", + "aliases": [ + "flour tortillas", + "tortilla wraps", + "wrap", + "wraps" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.0, + "brands": [ + "Iceland", + "Co-op", + "Mission", + "Farrah's", + "Morrisons" + ], + "image_hint": "wraps", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_pita_bread", + "name": "Pita Bread", + "category_id": "bakery", + "aliases": [ + "pita bread", + "pita breads", + "pita pocket" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.0, + "brands": [ + "Lidl UK", + "Sainsbury's", + "Tesco", + "Farrah's" + ], + "image_hint": "pita_bread", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_croissants", + "name": "Croissants", + "category_id": "bakery", + "aliases": [ + "butter croissants", + "croissant", + "croissants" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.98, + "brands": [ + "Co-op", + "Sainsbury's", + "Bakery", + "Lidl UK" + ], + "image_hint": "croissants", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_peas", + "name": "Frozen Peas", + "category_id": "frozen", + "aliases": [ + "frozen pea", + "frozen peas", + "peas frozen" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.96, + "brands": [], + "image_hint": "frozen_peas", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_mixed_veg", + "name": "Frozen Mixed Vegetables", + "category_id": "frozen", + "aliases": [ + "frozen mixed vegetable", + "frozen mixed vegetables", + "frozen vegetables", + "mixed veg" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.36, + "brands": [], + "image_hint": "frozen_mixed_veg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_chips", + "name": "Frozen Chips", + "category_id": "frozen", + "aliases": [ + "french fries", + "frozen chip", + "frozen chips", + "oven chips" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 6.12, + "brands": [ + "McCain", + "Sainsbury's", + "Co-op", + "Waitrose" + ], + "image_hint": "frozen_chips", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ice_cream_vanilla", + "name": "Ice Cream - Vanilla", + "category_id": "frozen", + "aliases": [ + "ice cream", + "ice cream vanilla", + "ice cream - vanillas", + "ice cream vanilla", + "vanilla ice cream" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 7.64, + "brands": [ + "Much Moore", + "Lidl UK", + "Co-op", + "Aldi UK" + ], + "image_hint": "ice_cream_vanilla", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ice_cream_hokey_pokey", + "name": "Ice Cream - Hokey Pokey", + "category_id": "frozen", + "aliases": [ + "hokey pokey ice cream", + "ice cream", + "ice cream hokey pokey", + "ice cream - hokey pokeys", + "ice cream hokey pokey" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 8.87, + "brands": [], + "image_hint": "ice_cream_hokey_pokey", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_pizza", + "name": "Frozen Pizza", + "category_id": "frozen", + "aliases": [ + "frozen pizza", + "frozen pizzas", + "pizza" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 6.57, + "brands": [ + "McCain", + "Iceland", + "Tesco", + "Dr Oetker", + "Morrisons" + ], + "image_hint": "frozen_pizza", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_fish_fingers", + "name": "Fish Fingers", + "category_id": "frozen", + "aliases": [ + "fish finger", + "fish fingers", + "fish sticks" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 7.7, + "brands": [ + "Co-op", + "Lidl UK", + "Aldi UK", + "Birds Eye" + ], + "image_hint": "fish_fingers", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [ + "fish" + ], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_berries", + "name": "Frozen Mixed Berries", + "category_id": "frozen", + "aliases": [ + "frozen berries", + "frozen mixed berrie", + "frozen mixed berries" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 6.66, + "brands": [ + "Waitrose", + "Marks & Spencer", + "Value", + "Aldi UK" + ], + "image_hint": "frozen_berries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_rice_white", + "name": "Rice - White", + "category_id": "pantry", + "aliases": [ + "long grain rice", + "rice", + "rice white", + "rice - whites", + "rice white", + "white rice" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.15, + "brands": [ + "Waitrose", + "Lidl UK", + "Tesco", + "Sunrice" + ], + "image_hint": "rice_white", + "tags": [ + "gluten_free", + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [ + "gluten_free" + ], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "rice_group", + "priority_level": 3 + }, + { + "id": "prod_rice_basmati", + "name": "Rice - Basmati", + "category_id": "pantry", + "aliases": [ + "basmati rice", + "rice", + "rice basmati", + "rice - basmatis", + "rice basmati" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.43, + "brands": [ + "Tilda", + "Sunrice", + "Aldi UK", + "Sainsbury's", + "Morrisons" + ], + "image_hint": "rice_basmati", + "tags": [ + "gluten_free", + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [ + "gluten_free" + ], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "rice_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_spaghetti", + "name": "Pasta - Spaghetti", + "category_id": "pantry", + "aliases": [ + "pasta", + "pasta spaghetti", + "pasta - spaghettis", + "pasta spaghetti", + "spaghetti" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 2.95, + "brands": [ + "Tesco", + "Barilla", + "San Remo", + "Aldi UK", + "Morrisons" + ], + "image_hint": "pasta_spaghetti", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_penne", + "name": "Pasta - Penne", + "category_id": "pantry", + "aliases": [ + "pasta", + "pasta penne", + "pasta - pennes", + "pasta penne", + "penne pasta" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 2.7, + "brands": [ + "Tesco", + "Co-op", + "Lidl UK", + "Barilla", + "San Remo" + ], + "image_hint": "pasta_penne", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_sauce", + "name": "Pasta Sauce", + "category_id": "pantry", + "aliases": [ + "bolognese sauce", + "pasta sauce", + "pasta sauces", + "tomato pasta sauce" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 4.04, + "brands": [ + "Tesco", + "Iceland", + "Co-op", + "Barilla", + "Dolmio" + ], + "image_hint": "pasta_sauce", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_flour_plain", + "name": "Flour - Plain", + "category_id": "pantry", + "aliases": [ + "flour", + "flour plain", + "flour - plains", + "flour plain", + "plain flour", + "white flour" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.24, + "brands": [ + "Tesco", + "Champion", + "Lidl UK", + "Marks & Spencer", + "Edmonds" + ], + "image_hint": "flour_plain", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_flour_self_raising", + "name": "Flour - Self Raising", + "category_id": "pantry", + "aliases": [ + "flour", + "flour self raising", + "flour - self raisings", + "flour self raising", + "self raising flour" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.17, + "brands": [ + "Champion", + "Lidl UK", + "Marks & Spencer", + "Morrisons", + "Edmonds" + ], + "image_hint": "flour_self_raising", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_sugar_white", + "name": "Sugar - White", + "category_id": "pantry", + "aliases": [ + "caster sugar", + "sugar", + "sugar white", + "sugar - whites", + "sugar white", + "white sugar" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.79, + "brands": [ + "Lidl UK", + "Chelsea", + "Iceland", + "Aldi UK" + ], + "image_hint": "sugar_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_sugar_brown", + "name": "Sugar - Brown", + "category_id": "pantry", + "aliases": [ + "brown sugar", + "soft brown", + "sugar", + "sugar brown", + "sugar - browns", + "sugar brown" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.21, + "brands": [ + "Sainsbury's", + "Chelsea", + "Marks & Spencer", + "Lidl UK" + ], + "image_hint": "sugar_brown", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_oil_olive", + "name": "Olive Oil", + "category_id": "pantry", + "aliases": [ + "EVOO", + "extra virgin olive oil", + "olive oil", + "olive oils" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 11.98, + "brands": [ + "Iceland", + "Marks & Spencer", + "Olivado", + "Aldi UK" + ], + "image_hint": "oil_olive", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_oil_vegetable", + "name": "Vegetable Oil", + "category_id": "pantry", + "aliases": [ + "canola oil", + "cooking oil", + "vegetable oil", + "vegetable oils" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 6.37, + "brands": [ + "Lidl UK", + "Sainsbury's", + "Iceland", + "Olivani" + ], + "image_hint": "oil_vegetable", + "tags": [ + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tomatoes_canned", + "name": "Canned Tomatoes", + "category_id": "pantry", + "aliases": [ + "canned tomatoe", + "canned tomatoes", + "chopped tomatoes", + "tinned tomatoes" + ], + "default_unit": "can", + "default_quantity": 4, + "price": 1.84, + "brands": [], + "image_hint": "tomatoes_canned", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_baked_beans", + "name": "Baked Beans", + "category_id": "pantry", + "aliases": [ + "baked bean", + "baked beans", + "beans in tomato sauce" + ], + "default_unit": "can", + "default_quantity": 1, + "price": 2.39, + "brands": [ + "Waitrose", + "Iceland", + "ASDA", + "Heinz" + ], + "image_hint": "baked_beans", + "tags": [ + "gluten_free" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tuna", + "name": "Tuna in Oil", + "category_id": "pantry", + "aliases": [ + "canned tuna", + "tinned tuna", + "tuna in oil", + "tuna in oils" + ], + "default_unit": "can", + "default_quantity": 3, + "price": 2.98, + "brands": [ + "Waitrose", + "John West", + "ASDA", + "Aldi UK" + ], + "image_hint": "tuna", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_coconut_cream", + "name": "Coconut Cream", + "category_id": "pantry", + "aliases": [ + "coconut cream", + "coconut creams", + "coconut milk" + ], + "default_unit": "can", + "default_quantity": 2, + "price": 2.76, + "brands": [ + "Tesco", + "Morrisons", + "Marks & Spencer", + "Ayam" + ], + "image_hint": "coconut_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_peanut_butter", + "name": "Peanut Butter", + "category_id": "pantry", + "aliases": [ + "crunchy peanut butter", + "peanut butter", + "peanut butters", + "smooth peanut butter" + ], + "default_unit": "g", + "default_quantity": 380, + "price": 5.41, + "brands": [ + "Kraft", + "Tesco", + "ETA", + "Lidl UK", + "Sainsbury's", + "Pic's" + ], + "image_hint": "peanut_butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_jam_strawberry", + "name": "Jam - Strawberry", + "category_id": "pantry", + "aliases": [ + "jam", + "jam strawberry", + "jam - strawberrys", + "jam strawberry", + "strawberry jam" + ], + "default_unit": "g", + "default_quantity": 340, + "price": 5.13, + "brands": [ + "Lidl UK", + "Anathoth", + "Barker's", + "Sainsbury's", + "Marks & Spencer" + ], + "image_hint": "jam_strawberry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_honey", + "name": "Honey", + "category_id": "pantry", + "aliases": [ + "clover honey", + "honey", + "honeys", + "manuka honey" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 8.53, + "brands": [ + "Tesco", + "Airborne", + "Co-op", + "Manuka Health", + "Marks & Spencer" + ], + "image_hint": "honey", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_marmite", + "name": "Marmite", + "category_id": "pantry", + "aliases": [ + "marmite", + "marmites", + "yeast spread" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.42, + "brands": [], + "image_hint": "marmite", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_vegemite", + "name": "Vegemite", + "category_id": "pantry", + "aliases": [ + "vegemite", + "vegemites", + "yeast spread" + ], + "default_unit": "g", + "default_quantity": 220, + "price": 4.95, + "brands": [ + "Lidl UK", + "Marks & Spencer", + "Bega", + "Aldi UK" + ], + "image_hint": "vegemite", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_soy_sauce", + "name": "Soy Sauce", + "category_id": "pantry", + "aliases": [ + "kikkoman", + "soy sauce", + "soy sauces" + ], + "default_unit": "mL", + "default_quantity": 250, + "price": 5.0, + "brands": [ + "Kikkoman", + "Marks & Spencer", + "ASDA", + "Iceland" + ], + "image_hint": "soy_sauce", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [ + "soy" + ], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tomato_sauce", + "name": "Tomato Sauce", + "category_id": "pantry", + "aliases": [ + "ketchup", + "tomato ketchup", + "tomato sauce", + "tomato sauces" + ], + "default_unit": "mL", + "default_quantity": 560, + "price": 4.83, + "brands": [ + "Co-op", + "Iceland", + "Waitrose", + "Heinz" + ], + "image_hint": "tomato_sauce", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_bbq_sauce", + "name": "BBQ Sauce", + "category_id": "pantry", + "aliases": [ + "barbecue sauce", + "bbq sauce", + "bbq sauces" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 4.62, + "brands": [ + "Masterfoods", + "Tesco", + "Morrisons", + "Marks & Spencer" + ], + "image_hint": "bbq_sauce", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_mayonnaise", + "name": "Mayonnaise", + "category_id": "pantry", + "aliases": [ + "mayo", + "mayonnaise", + "mayonnaises" + ], + "default_unit": "mL", + "default_quantity": 440, + "price": 5.92, + "brands": [ + "Best Foods", + "Iceland", + "ASDA", + "Morrisons" + ], + "image_hint": "mayonnaise", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_mustard", + "name": "Mustard", + "category_id": "pantry", + "aliases": [ + "american mustard", + "dijon mustard", + "mustard", + "mustards" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.08, + "brands": [ + "Iceland", + "Co-op", + "French's", + "Waitrose", + "Masterfoods" + ], + "image_hint": "mustard", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_salt", + "name": "Salt", + "category_id": "pantry", + "aliases": [ + "cooking salt", + "salt", + "salts", + "table salt" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 1.9, + "brands": [ + "Co-op", + "Iceland", + "Marks & Spencer", + "Cerebos" + ], + "image_hint": "salt", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_pepper", + "name": "Black Pepper", + "category_id": "pantry", + "aliases": [ + "black pepper", + "black peppers", + "ground pepper" + ], + "default_unit": "g", + "default_quantity": 50, + "price": 3.69, + "brands": [ + "Masterfoods", + "Marks & Spencer", + "ASDA", + "Aldi UK" + ], + "image_hint": "pepper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_stock_cubes_chicken", + "name": "Stock Cubes - Chicken", + "category_id": "pantry", + "aliases": [ + "bouillon", + "chicken stock", + "stock cubes", + "stock cubes chicken", + "stock cubes - chickens", + "stock cubes chicken" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 3.01, + "brands": [ + "Tesco", + "Continental", + "Maggi", + "Waitrose", + "Aldi UK" + ], + "image_hint": "stock_cubes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_stock_cubes_beef", + "name": "Stock Cubes - Beef", + "category_id": "pantry", + "aliases": [ + "beef stock", + "stock cubes", + "stock cubes beef", + "stock cubes - beefs", + "stock cubes beef" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 2.75, + "brands": [ + "Continental", + "Maggi", + "Co-op", + "ASDA", + "Waitrose" + ], + "image_hint": "stock_cubes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_coffee_instant", + "name": "Instant Coffee", + "category_id": "beverages", + "aliases": [ + "coffee", + "instant coffee", + "instant coffees", + "nescafe" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 12.89, + "brands": [ + "Iceland", + "Robert Harris", + "Co-op", + "Gregg's", + "Nescafe", + "Morrisons" + ], + "image_hint": "coffee_instant", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_coffee_ground", + "name": "Ground Coffee", + "category_id": "beverages", + "aliases": [ + "filter coffee", + "ground coffee", + "ground coffees" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 9.16, + "brands": [ + "Robert Harris", + "Iceland", + "L'affare", + "Aldi UK", + "Vittoria", + "Marks & Spencer" + ], + "image_hint": "coffee_ground", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tea_black", + "name": "Tea - Black", + "category_id": "beverages", + "aliases": [ + "black tea", + "tea", + "tea black", + "tea - blacks", + "tea bags", + "tea black" + ], + "default_unit": "ea", + "default_quantity": 100, + "price": 6.7, + "brands": [ + "Bell", + "ASDA", + "Waitrose", + "Aldi UK", + "Twinings", + "Dilmah" + ], + "image_hint": "tea_black", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tea_green", + "name": "Tea - Green", + "category_id": "beverages", + "aliases": [ + "green tea", + "tea", + "tea green", + "tea - greens", + "tea green" + ], + "default_unit": "ea", + "default_quantity": 40, + "price": 5.42, + "brands": [ + "Tesco", + "Co-op", + "Marks & Spencer", + "Twinings", + "Dilmah" + ], + "image_hint": "tea_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_juice_orange", + "name": "Orange Juice", + "category_id": "beverages", + "aliases": [ + "OJ", + "fresh orange juice", + "orange juice", + "orange juices" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 7.33, + "brands": [ + "Just Juice", + "Waitrose", + "Aldi UK", + "Charlies", + "Marks & Spencer" + ], + "image_hint": "juice_orange", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_juice_apple", + "name": "Apple Juice", + "category_id": "beverages", + "aliases": [ + "apple juice", + "apple juices", + "fresh apple juice" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 6.87, + "brands": [ + "Just Juice", + "Lidl UK", + "Waitrose", + "Charlies", + "Sainsbury's" + ], + "image_hint": "juice_apple", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soft_drink_coke", + "name": "Coca Cola", + "category_id": "beverages", + "aliases": [ + "coca cola", + "coca colas", + "coke", + "cola" + ], + "default_unit": "L", + "default_quantity": 2.25, + "price": 5.13, + "brands": [ + "Waitrose", + "Sainsbury's", + "Coca-Cola", + "Aldi UK" + ], + "image_hint": "coke", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soft_drink_lemonade", + "name": "Lemonade", + "category_id": "beverages", + "aliases": [ + "7up", + "lemonade", + "lemonades", + "sprite" + ], + "default_unit": "L", + "default_quantity": 2.25, + "price": 5.0, + "brands": [ + "Lidl UK", + "Schweppes", + "Aldi UK", + "Marks & Spencer", + "Sprite" + ], + "image_hint": "lemonade", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_water_still", + "name": "Water - Still", + "category_id": "beverages", + "aliases": [ + "bottled water", + "spring water", + "water", + "water still", + "water - stills", + "water still" + ], + "default_unit": "L", + "default_quantity": 1.5, + "price": 2.37, + "brands": [ + "Pump", + "Iceland", + "Aldi UK", + "Evian", + "Marks & Spencer" + ], + "image_hint": "water_still", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_water_sparkling", + "name": "Water - Sparkling", + "category_id": "beverages", + "aliases": [ + "soda water", + "sparkling water", + "water", + "water sparkling", + "water - sparklings", + "water sparkling" + ], + "default_unit": "L", + "default_quantity": 1.5, + "price": 3.04, + "brands": [ + "Co-op", + "Schweppes", + "San Pellegrino", + "Waitrose", + "Marks & Spencer" + ], + "image_hint": "water_sparkling", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beer", + "name": "Beer", + "category_id": "beverages", + "aliases": [ + "ale", + "beer", + "beers", + "lager" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 24.24, + "brands": [ + "Lidl UK", + "DB Export", + "Steinlager", + "Speights", + "Marks & Spencer", + "Morrisons" + ], + "image_hint": "beer", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wine_red", + "name": "Wine - Red", + "category_id": "beverages", + "aliases": [ + "red wine", + "wine", + "wine red", + "wine - reds", + "wine red" + ], + "default_unit": "bottle", + "default_quantity": 1, + "price": 15.0, + "brands": [ + "ASDA", + "Villa Maria", + "Aldi UK", + "Morrisons", + "Oyster Bay" + ], + "image_hint": "wine_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wine_white", + "name": "Wine - White", + "category_id": "beverages", + "aliases": [ + "sauvignon blanc", + "white wine", + "wine", + "wine white", + "wine - whites", + "wine white" + ], + "default_unit": "bottle", + "default_quantity": 1, + "price": 15.53, + "brands": [ + "Tesco", + "Iceland", + "Cloudy Bay", + "Co-op", + "Villa Maria", + "Oyster Bay" + ], + "image_hint": "wine_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_cornflakes", + "name": "Cornflakes", + "category_id": "snacks", + "aliases": [ + "cornflake", + "cornflakes", + "kelloggs cornflakes" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 6.76, + "brands": [ + "Waitrose", + "Co-op", + "Kelloggs", + "Morrisons" + ], + "image_hint": "cereal_cornflakes", + "tags": [ + "gluten_free" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_weet_bix", + "name": "Weet-Bix", + "category_id": "snacks", + "aliases": [ + "weet bix", + "weet-bix", + "weet-bixs", + "weetbix", + "wheat biscuits" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 8.37, + "brands": [], + "image_hint": "cereal_weet_bix", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_muesli", + "name": "Muesli", + "category_id": "snacks", + "aliases": [ + "muesli", + "mueslis", + "toasted muesli" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 8.72, + "brands": [ + "Iceland", + "ASDA", + "Hubbards", + "Marks & Spencer" + ], + "image_hint": "cereal_muesli", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_oats_rolled", + "name": "Rolled Oats", + "category_id": "snacks", + "aliases": [ + "oats", + "porridge oats", + "rolled oat", + "rolled oats" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.88, + "brands": [ + "Waitrose", + "Lidl UK", + "Harraways", + "ASDA" + ], + "image_hint": "oats_rolled", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chips_salt", + "name": "Potato Chips - Salt", + "category_id": "snacks", + "aliases": [ + "crisps", + "potato chips", + "potato chips salt", + "potato chips - salts", + "potato chips salt", + "ready salted chips" + ], + "default_unit": "g", + "default_quantity": 150, + "price": 3.73, + "brands": [ + "Tesco", + "ASDA", + "Bluebird", + "Eta", + "Sainsbury's" + ], + "image_hint": "chips_salt", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chips_chicken", + "name": "Potato Chips - Chicken", + "category_id": "snacks", + "aliases": [ + "chicken chips", + "potato chips", + "potato chips chicken", + "potato chips - chickens", + "potato chips chicken" + ], + "default_unit": "g", + "default_quantity": 150, + "price": 3.96, + "brands": [ + "Lidl UK", + "Waitrose", + "Bluebird", + "Eta", + "Aldi UK" + ], + "image_hint": "chips_chicken", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_crackers", + "name": "Crackers", + "category_id": "snacks", + "aliases": [ + "cracker", + "crackers", + "savoy", + "water crackers" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 3.72, + "brands": [ + "Arnott's", + "ASDA", + "Sainsbury's", + "Morrisons", + "Griffin's" + ], + "image_hint": "crackers", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cookies_chocolate_chip", + "name": "Chocolate Chip Cookies", + "category_id": "snacks", + "aliases": [ + "choc chip biscuits", + "chocolate chip cookie", + "chocolate chip cookies", + "cookies" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.97, + "brands": [ + "Cookie Time", + "Sainsbury's", + "Marks & Spencer", + "Morrisons", + "Griffin's" + ], + "image_hint": "cookies_chocolate_chip", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tim_tams", + "name": "Tim Tams", + "category_id": "snacks", + "aliases": [ + "chocolate biscuits", + "tim tam", + "tim tams" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.53, + "brands": [ + "Co-op", + "ASDA", + "Arnott's", + "Aldi UK" + ], + "image_hint": "tim_tams", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chocolate_whittakers", + "name": "Chocolate - Whittaker's", + "category_id": "snacks", + "aliases": [ + "chocolate", + "chocolate whittaker's", + "chocolate - whittaker'", + "chocolate bar", + "chocolate whittaker's", + "whittakers block" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 6.24, + "brands": [], + "image_hint": "chocolate_whittakers", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chocolate_cadbury", + "name": "Chocolate - Cadbury", + "category_id": "snacks", + "aliases": [ + "cadbury block", + "chocolate", + "chocolate cadbury", + "chocolate - cadburys", + "chocolate cadbury" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 5.02, + "brands": [ + "Cadbury", + "Tesco", + "ASDA", + "Iceland" + ], + "image_hint": "chocolate_cadbury", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_muesli_bars", + "name": "Muesli Bars", + "category_id": "snacks", + "aliases": [ + "granola bars", + "muesli bar", + "muesli bars" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.72, + "brands": [ + "Waitrose", + "Nice & Natural", + "Uncle Tobys", + "Sainsbury's", + "Marks & Spencer" + ], + "image_hint": "muesli_bars", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_popcorn", + "name": "Popcorn", + "category_id": "snacks", + "aliases": [ + "microwave popcorn", + "popcorn", + "popcorns" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.82, + "brands": [ + "Co-op", + "Proper", + "Eta", + "Sainsbury's", + "Marks & Spencer" + ], + "image_hint": "popcorn", + "tags": [ + "gluten_free" + ], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_nuts_mixed", + "name": "Mixed Nuts", + "category_id": "snacks", + "aliases": [ + "mixed nut", + "mixed nuts", + "roasted nuts" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 7.2, + "brands": [ + "Eta", + "ASDA", + "Aldi UK", + "Marks & Spencer" + ], + "image_hint": "nuts_mixed", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toilet_paper", + "name": "Toilet Paper", + "category_id": "household", + "aliases": [ + "TP", + "bathroom tissue", + "toilet paper", + "toilet papers" + ], + "default_unit": "roll", + "default_quantity": 12, + "price": 12.76, + "brands": [ + "Sorbent", + "Waitrose", + "Purex", + "Aldi UK", + "Morrisons" + ], + "image_hint": "toilet_paper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_paper_towels", + "name": "Paper Towels", + "category_id": "household", + "aliases": [ + "kitchen paper", + "paper towel", + "paper towels" + ], + "default_unit": "roll", + "default_quantity": 4, + "price": 8.32, + "brands": [ + "Iceland", + "Lidl UK", + "Sorbent", + "Handee", + "Marks & Spencer" + ], + "image_hint": "paper_towels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tissues", + "name": "Tissues", + "category_id": "household", + "aliases": [ + "facial tissues", + "kleenex", + "tissue", + "tissues" + ], + "default_unit": "box", + "default_quantity": 4, + "price": 7.75, + "brands": [ + "Tesco", + "Sorbent", + "Kleenex", + "Aldi UK", + "Morrisons" + ], + "image_hint": "tissues", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dishwashing_liquid", + "name": "Dishwashing Liquid", + "category_id": "household", + "aliases": [ + "dish soap", + "dishwash", + "dishwashing liquid", + "dishwashing liquids" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 4.58, + "brands": [ + "Iceland", + "Tesco", + "Sunlight", + "Morning Fresh", + "Morrisons" + ], + "image_hint": "dishwashing_liquid", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dishwasher_tablets", + "name": "Dishwasher Tablets", + "category_id": "household", + "aliases": [ + "dishwasher pods", + "dishwasher tablet", + "dishwasher tablets" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 14.18, + "brands": [ + "Earthwise", + "Iceland", + "Co-op", + "ASDA", + "Finish" + ], + "image_hint": "dishwasher_tablets", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_laundry_powder", + "name": "Laundry Powder", + "category_id": "household", + "aliases": [ + "laundry powder", + "laundry powders", + "washing powder" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 17.0, + "brands": [ + "Persil", + "Earthwise", + "Co-op", + "Lidl UK", + "OMO", + "Marks & Spencer" + ], + "image_hint": "laundry_powder", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_laundry_liquid", + "name": "Laundry Liquid", + "category_id": "household", + "aliases": [ + "laundry liquid", + "laundry liquids", + "washing liquid" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 14.17, + "brands": [ + "Persil", + "Earthwise", + "Waitrose", + "OMO", + "Sainsbury's", + "Marks & Spencer" + ], + "image_hint": "laundry_liquid", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_fabric_softener", + "name": "Fabric Softener", + "category_id": "household", + "aliases": [ + "comfort", + "downy", + "fabric softener", + "fabric softeners" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 10.3, + "brands": [ + "Earthwise", + "Tesco", + "Comfort", + "Waitrose", + "Marks & Spencer" + ], + "image_hint": "fabric_softener", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_spray_cleaner", + "name": "Spray Cleaner", + "category_id": "household", + "aliases": [ + "multi-purpose cleaner", + "spray cleaner", + "spray cleaners", + "spray n wipe" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 6.83, + "brands": [ + "Jif", + "Spray n Wipe", + "ASDA", + "Sainsbury's", + "Morrisons" + ], + "image_hint": "spray_cleaner", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bleach", + "name": "Bleach", + "category_id": "household", + "aliases": [ + "bleach", + "bleachs", + "janola" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 5.47, + "brands": [ + "Co-op", + "Domestos", + "Lidl UK", + "Sainsbury's", + "Janola" + ], + "image_hint": "bleach", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bin_bags", + "name": "Bin Bags", + "category_id": "household", + "aliases": [ + "bin bag", + "bin bags", + "garbage bags", + "rubbish bags" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 8.61, + "brands": [ + "Tesco", + "Glad", + "Ecostore", + "Marks & Spencer", + "Morrisons" + ], + "image_hint": "bin_bags", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cling_film", + "name": "Cling Film", + "category_id": "household", + "aliases": [ + "cling film", + "cling films", + "glad wrap", + "plastic wrap" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 5.69, + "brands": [ + "Co-op", + "Lidl UK", + "Multix", + "Waitrose", + "Glad" + ], + "image_hint": "cling_film", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_aluminium_foil", + "name": "Aluminium Foil", + "category_id": "household", + "aliases": [ + "alfoil", + "aluminium foil", + "aluminium foils", + "tin foil" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 6.6, + "brands": [ + "Co-op", + "ASDA", + "Multix", + "Alfoil", + "Morrisons" + ], + "image_hint": "aluminium_foil", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baking_paper", + "name": "Baking Paper", + "category_id": "household", + "aliases": [ + "baking paper", + "baking papers", + "parchment paper" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 5.17, + "brands": [ + "Tesco", + "Co-op", + "Alfoil", + "Waitrose", + "Multix" + ], + "image_hint": "baking_paper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_shampoo", + "name": "Shampoo", + "category_id": "health", + "aliases": [ + "hair shampoo", + "shampoo", + "shampoos" + ], + "default_unit": "mL", + "default_quantity": 400, + "price": 8.18, + "brands": [ + "Head & Shoulders", + "Tesco", + "Iceland", + "Sainsbury's", + "Garnier", + "Pantene" + ], + "image_hint": "shampoo", + "tags": [], + "collections": [ + "christmas" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_conditioner", + "name": "Conditioner", + "category_id": "health", + "aliases": [ + "conditioner", + "conditioners", + "hair conditioner" + ], + "default_unit": "mL", + "default_quantity": 400, + "price": 8.72, + "brands": [ + "Head & Shoulders", + "Lidl UK", + "Aldi UK", + "Garnier", + "Pantene", + "Morrisons" + ], + "image_hint": "conditioner", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_body_wash", + "name": "Body Wash", + "category_id": "health", + "aliases": [ + "body wash", + "body washs", + "shower gel" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 7.87, + "brands": [ + "Iceland", + "Dove", + "Lidl UK", + "Palmolive", + "Marks & Spencer", + "Nivea" + ], + "image_hint": "body_wash", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soap_bar", + "name": "Bar Soap", + "category_id": "health", + "aliases": [ + "bar soap", + "bar soaps", + "bath soap", + "hand soap" + ], + "default_unit": "bar", + "default_quantity": 4, + "price": 5.2, + "brands": [ + "Tesco", + "Dove", + "Lidl UK", + "Aldi UK", + "Palmolive" + ], + "image_hint": "soap_bar", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toothpaste", + "name": "Toothpaste", + "category_id": "health", + "aliases": [ + "colgate", + "toothpaste", + "toothpastes" + ], + "default_unit": "g", + "default_quantity": 110, + "price": 5.9, + "brands": [ + "Iceland", + "Co-op", + "Sensodyne", + "Colgate", + "Marks & Spencer" + ], + "image_hint": "toothpaste", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toothbrush", + "name": "Toothbrush", + "category_id": "health", + "aliases": [ + "tooth brush", + "toothbrush", + "toothbrushs" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 7.09, + "brands": [ + "Oral-B", + "Waitrose", + "Sainsbury's", + "Colgate", + "Marks & Spencer" + ], + "image_hint": "toothbrush", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_deodorant", + "name": "Deodorant", + "category_id": "health", + "aliases": [ + "antiperspirant", + "deodorant", + "deodorants" + ], + "default_unit": "g", + "default_quantity": 50, + "price": 7.78, + "brands": [ + "Dove", + "Rexona", + "Co-op", + "Lynx", + "Waitrose", + "Aldi UK" + ], + "image_hint": "deodorant", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_razor_blades", + "name": "Razor Blades", + "category_id": "health", + "aliases": [ + "gillette", + "razor blade", + "razor blades", + "shaving blades" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 19.6, + "brands": [ + "Lidl UK", + "Waitrose", + "Schick", + "Gillette", + "Sainsbury's" + ], + "image_hint": "razor_blades", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_shaving_cream", + "name": "Shaving Cream", + "category_id": "health", + "aliases": [ + "shave gel", + "shaving cream", + "shaving creams" + ], + "default_unit": "mL", + "default_quantity": 200, + "price": 7.27, + "brands": [ + "Iceland", + "ASDA", + "Gillette", + "Nivea", + "Morrisons" + ], + "image_hint": "shaving_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_sunscreen", + "name": "Sunscreen SPF50", + "category_id": "health", + "aliases": [ + "sun cream", + "sunblock", + "sunscreen spf50", + "sunscreen spf50s" + ], + "default_unit": "mL", + "default_quantity": 200, + "price": 14.3, + "brands": [ + "Cancer Society", + "ASDA", + "Neutrogena", + "Aldi UK", + "Marks & Spencer" + ], + "image_hint": "sunscreen", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_paracetamol", + "name": "Paracetamol", + "category_id": "health", + "aliases": [ + "pain relief", + "panadol", + "paracetamol", + "paracetamols" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 9.37, + "brands": [ + "Sainsbury's", + "Marks & Spencer", + "Aldi UK", + "Panadol" + ], + "image_hint": "paracetamol", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ibuprofen", + "name": "Ibuprofen", + "category_id": "health", + "aliases": [ + "ibuprofen", + "ibuprofens", + "nurofen", + "pain relief" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 9.6, + "brands": [ + "Nurofen", + "Lidl UK", + "ASDA", + "Waitrose" + ], + "image_hint": "ibuprofen", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bandaids", + "name": "Band-Aids", + "category_id": "health", + "aliases": [ + "band aids", + "band-aid", + "band-aids", + "bandages", + "plasters" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.88, + "brands": [ + "Iceland", + "Co-op", + "Band-Aid", + "Aldi UK", + "Elastoplast" + ], + "image_hint": "bandaids", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_vitamins_c", + "name": "Vitamin C", + "category_id": "health", + "aliases": [ + "vitamin c", + "vitamin c tablets", + "vitamin cs" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 13.15, + "brands": [ + "Tesco", + "Blackmores", + "ASDA", + "Sainsbury's", + "Healtheries" + ], + "image_hint": "vitamins_c", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_nappies", + "name": "Nappies", + "category_id": "baby", + "aliases": [ + "baby nappies", + "diapers", + "nappie", + "nappies" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 30.46, + "brands": [ + "Co-op", + "Lidl UK", + "Huggies", + "Aldi UK" + ], + "image_hint": "nappies", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baby_wipes", + "name": "Baby Wipes", + "category_id": "baby", + "aliases": [ + "baby wipe", + "baby wipes", + "wet wipes" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.83, + "brands": [ + "Co-op", + "Sainsbury's", + "Huggies", + "Marks & Spencer" + ], + "image_hint": "baby_wipes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baby_formula", + "name": "Baby Formula", + "category_id": "baby", + "aliases": [ + "baby formula", + "baby formulas", + "infant formula" + ], + "default_unit": "g", + "default_quantity": 900, + "price": 29.61, + "brands": [ + "Tesco", + "Aldi UK", + "Karicare", + "Sainsbury's", + "Aptamil" + ], + "image_hint": "baby_formula", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dog_food_dry", + "name": "Dog Food - Dry", + "category_id": "pet", + "aliases": [ + "dog biscuits", + "dog food", + "dog food dry", + "dog food - drys", + "dog food dry", + "dog kibble" + ], + "default_unit": "kg", + "default_quantity": 3, + "price": 25.7, + "brands": [ + "Pedigree", + "Tesco", + "Eukanuba", + "Sainsbury's", + "Morrisons" + ], + "image_hint": "dog_food_dry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dog_food_wet", + "name": "Dog Food - Wet", + "category_id": "pet", + "aliases": [ + "canned dog food", + "dog food", + "dog food wet", + "dog food - wets", + "dog food wet" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 19.37, + "brands": [ + "Pedigree", + "Tesco", + "Waitrose", + "Champ", + "Marks & Spencer" + ], + "image_hint": "dog_food_wet", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_food_dry", + "name": "Cat Food - Dry", + "category_id": "pet", + "aliases": [ + "cat biscuits", + "cat food", + "cat food dry", + "cat food - drys", + "cat food dry" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 20.12, + "brands": [ + "Iceland", + "ASDA", + "Waitrose", + "Whiskas", + "Fancy Feast" + ], + "image_hint": "cat_food_dry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_food_wet", + "name": "Cat Food - Wet", + "category_id": "pet", + "aliases": [ + "canned cat food", + "cat food", + "cat food wet", + "cat food - wets", + "cat food wet" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 13.95, + "brands": [ + "Iceland", + "Co-op", + "ASDA", + "Whiskas", + "Fancy Feast" + ], + "image_hint": "cat_food_wet", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_litter", + "name": "Cat Litter", + "category_id": "pet", + "aliases": [ + "cat litter", + "cat litters", + "kitty litter" + ], + "default_unit": "kg", + "default_quantity": 5, + "price": 13.53, + "brands": [ + "Catlove", + "Waitrose", + "Aldi UK", + "Paws", + "Morrisons" + ], + "image_hint": "cat_litter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + } + ], + "country": "United Kingdom" +} \ No newline at end of file diff --git a/custom_components/shopping_list_manager/data/products_catalog_nz.json b/custom_components/shopping_list_manager/data/products_catalog_nz.json new file mode 100644 index 0000000..5007aa0 --- /dev/null +++ b/custom_components/shopping_list_manager/data/products_catalog_nz.json @@ -0,0 +1,5133 @@ +{ + "version": "2.1.0", + "region": "NZ", + "currency": "NZD", + "last_updated": "2026-02-13", + "description": "Advanced NZ grocery catalog with structured taxonomy, allergens, substitution groups, and automation-ready metadata", + "products": [ + { + "id": "prod_milk_trim", + "name": "Milk - Trim", + "category_id": "dairy", + "aliases": [ + "low fat milk", + "milk", + "milk trim", + "milk - trims", + "milk trim", + "skim milk", + "trim milk" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 3.99, + "brands": [ + "Anchor", + "Pams", + "Meadow Fresh" + ], + "barcode": "9400547000019", + "image_hint": "milk_trim", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "milk" + ], + "substitution_group": "milk_group", + "priority_level": 5 + }, + { + "id": "prod_milk_whole", + "name": "Milk - Whole", + "category_id": "dairy", + "aliases": [ + "blue top milk", + "full cream milk", + "milk", + "milk whole", + "milk - wholes", + "milk whole", + "whole milk" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 4.29, + "brands": [ + "Anchor", + "Pams", + "Meadow Fresh" + ], + "barcode": "9400547000026", + "image_hint": "milk_whole", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "milk" + ], + "substitution_group": "milk_group", + "priority_level": 5 + }, + { + "id": "prod_butter_salted", + "name": "Butter - Salted", + "category_id": "dairy", + "aliases": [ + "butter", + "butter salted", + "butter - salteds", + "butter salted", + "salted butter" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 6.99, + "brands": [ + "Anchor", + "Mainland", + "Westgold" + ], + "image_hint": "butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_butter_unsalted", + "name": "Butter - Unsalted", + "category_id": "dairy", + "aliases": [ + "butter", + "butter unsalted", + "butter - unsalteds", + "butter unsalted", + "unsalted butter" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 7.49, + "brands": [ + "Anchor", + "Mainland" + ], + "image_hint": "butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cheese_tasty", + "name": "Cheese - Tasty", + "category_id": "dairy", + "aliases": [ + "cheddar", + "cheese", + "cheese tasty", + "cheese - tastys", + "cheese block", + "cheese tasty", + "tasty cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 9.99, + "brands": [ + "Mainland", + "Anchor", + "Pams" + ], + "image_hint": "cheese_tasty", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_edam", + "name": "Cheese - Edam", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese edam", + "cheese - edams", + "cheese edam", + "edam cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 9.49, + "brands": [ + "Mainland", + "Anchor" + ], + "image_hint": "cheese_edam", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_colby", + "name": "Cheese - Colby", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese colby", + "cheese - colbys", + "cheese colby", + "colby cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 9.49, + "brands": [ + "Mainland", + "Anchor" + ], + "image_hint": "cheese_colby", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_grated", + "name": "Cheese - Grated", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese grated", + "cheese - grateds", + "cheese grated", + "grated cheese", + "shredded cheese" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 6.99, + "brands": [ + "Mainland", + "Anchor", + "Pams" + ], + "image_hint": "cheese_grated", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_yogurt_plain", + "name": "Yogurt - Plain", + "category_id": "dairy", + "aliases": [ + "natural yogurt", + "plain yogurt", + "yogurt", + "yogurt plain", + "yogurt - plains", + "yogurt plain" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Anchor", + "Meadow Fresh", + "Cyclone" + ], + "image_hint": "yogurt_plain", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "yogurt_group", + "priority_level": 4 + }, + { + "id": "prod_yogurt_greek", + "name": "Yogurt - Greek", + "category_id": "dairy", + "aliases": [ + "greek yogurt", + "yogurt", + "yogurt greek", + "yogurt - greeks", + "yogurt greek" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 7.99, + "brands": [ + "Farmers Union", + "Anchor", + "Chobani" + ], + "image_hint": "yogurt_greek", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "yogurt_group", + "priority_level": 4 + }, + { + "id": "prod_eggs_free_range", + "name": "Eggs - Free Range", + "category_id": "dairy", + "aliases": [ + "eggs", + "eggs free range", + "eggs - free ranges", + "eggs free range", + "free range eggs" + ], + "default_unit": "ea", + "default_quantity": 12, + "price": 9.99, + "brands": [ + "Woodland", + "Frenz", + "Farmer Brown" + ], + "image_hint": "eggs_free_range", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "eggs" + ], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_eggs_cage", + "name": "Eggs - Cage", + "category_id": "dairy", + "aliases": [ + "budget eggs", + "cage eggs", + "eggs", + "eggs cage", + "eggs - cages", + "eggs cage" + ], + "default_unit": "ea", + "default_quantity": 12, + "price": 6.49, + "brands": [ + "Pams", + "Value" + ], + "image_hint": "eggs", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "eggs" + ], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cream", + "name": "Cream - Fresh", + "category_id": "dairy", + "aliases": [ + "cream", + "cream fresh", + "cream - freshs", + "cream fresh", + "fresh cream", + "pouring cream" + ], + "default_unit": "mL", + "default_quantity": 300, + "price": 4.99, + "brands": [ + "Anchor", + "Meadow Fresh" + ], + "image_hint": "cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_sour_cream", + "name": "Sour Cream", + "category_id": "dairy", + "aliases": [ + "sour cream", + "sour creams" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.49, + "brands": [ + "Anchor", + "Meadow Fresh" + ], + "image_hint": "sour_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_apples_gala", + "name": "Apples - Gala", + "category_id": "produce", + "aliases": [ + "apples", + "apples gala", + "apples - galas", + "apples gala", + "gala apples" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.99, + "image_hint": "apples_gala", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_apples_granny_smith", + "name": "Apples - Granny Smith", + "category_id": "produce", + "aliases": [ + "apples", + "apples granny smith", + "apples - granny smiths", + "apples granny smith", + "granny smith", + "green apples" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.99, + "image_hint": "apples_granny_smith", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_bananas", + "name": "Bananas", + "category_id": "produce", + "aliases": [ + "banana", + "bananas" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.99, + "image_hint": "bananas", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_oranges", + "name": "Oranges", + "category_id": "produce", + "aliases": [ + "orange", + "oranges" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.49, + "image_hint": "oranges", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_mandarins", + "name": "Mandarins", + "category_id": "produce", + "aliases": [ + "easy peelers", + "mandarin", + "mandarins" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.99, + "image_hint": "mandarins", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kiwifruit_green", + "name": "Kiwifruit - Green", + "category_id": "produce", + "aliases": [ + "green kiwifruit", + "kiwi", + "kiwifruit", + "kiwifruit green", + "kiwifruit - greens", + "kiwifruit green" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 6.99, + "image_hint": "kiwifruit_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kiwifruit_gold", + "name": "Kiwifruit - Gold", + "category_id": "produce", + "aliases": [ + "gold kiwifruit", + "kiwifruit", + "kiwifruit gold", + "kiwifruit - golds", + "kiwifruit gold", + "sungold" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 8.99, + "image_hint": "kiwifruit_gold", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_strawberries", + "name": "Strawberries", + "category_id": "produce", + "aliases": [ + "strawberrie", + "strawberries", + "strawberry" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.99, + "image_hint": "strawberries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_blueberries", + "name": "Blueberries", + "category_id": "produce", + "aliases": [ + "blueberrie", + "blueberries", + "blueberry" + ], + "default_unit": "g", + "default_quantity": 125, + "price": 6.99, + "image_hint": "blueberries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_grapes_green", + "name": "Grapes - Green", + "category_id": "produce", + "aliases": [ + "grapes", + "grapes green", + "grapes - greens", + "grapes green", + "green grapes", + "white grapes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 7.99, + "image_hint": "grapes_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_grapes_red", + "name": "Grapes - Red", + "category_id": "produce", + "aliases": [ + "grapes", + "grapes red", + "grapes - reds", + "grapes red", + "red grapes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 7.99, + "image_hint": "grapes_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_avocado", + "name": "Avocados", + "category_id": "produce", + "aliases": [ + "avo", + "avocado", + "avocados" + ], + "default_unit": "ea", + "default_quantity": 3, + "price": 2.99, + "image_hint": "avocado", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_tomatoes", + "name": "Tomatoes", + "category_id": "produce", + "aliases": [ + "tomato", + "tomatoe", + "tomatoes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 6.99, + "image_hint": "tomatoes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_tomatoes_cherry", + "name": "Cherry Tomatoes", + "category_id": "produce", + "aliases": [ + "cherry tomato", + "cherry tomatoe", + "cherry tomatoes" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.99, + "image_hint": "tomatoes_cherry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cucumber", + "name": "Cucumber", + "category_id": "produce", + "aliases": [ + "cucumber", + "cucumbers" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 2.99, + "image_hint": "cucumber", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_lettuce_iceberg", + "name": "Lettuce - Iceberg", + "category_id": "produce", + "aliases": [ + "iceberg lettuce", + "lettuce", + "lettuce iceberg", + "lettuce - icebergs", + "lettuce iceberg" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.99, + "image_hint": "lettuce_iceberg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_lettuce_cos", + "name": "Lettuce - Cos", + "category_id": "produce", + "aliases": [ + "cos lettuce", + "lettuce", + "lettuce cos", + "lettuce - co", + "lettuce cos", + "romaine" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.99, + "image_hint": "lettuce_cos", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_capsicum_red", + "name": "Capsicum - Red", + "category_id": "produce", + "aliases": [ + "capsicum", + "capsicum red", + "capsicum - reds", + "capsicum red", + "red capsicum", + "red pepper" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 2.49, + "image_hint": "capsicum_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_capsicum_green", + "name": "Capsicum - Green", + "category_id": "produce", + "aliases": [ + "capsicum", + "capsicum green", + "capsicum - greens", + "capsicum green", + "green capsicum", + "green pepper" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 1.99, + "image_hint": "capsicum_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_broccoli", + "name": "Broccoli", + "category_id": "produce", + "aliases": [ + "broccoli", + "broccoli head", + "broccolis" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.99, + "image_hint": "broccoli", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cauliflower", + "name": "Cauliflower", + "category_id": "produce", + "aliases": [ + "cauli", + "cauliflower", + "cauliflowers" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 4.99, + "image_hint": "cauliflower", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_carrots", + "name": "Carrots", + "category_id": "produce", + "aliases": [ + "carrot", + "carrots" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 2.99, + "image_hint": "carrots", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_potatoes", + "name": "Potatoes", + "category_id": "produce", + "aliases": [ + "potato", + "potatoe", + "potatoes", + "spuds" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 4.99, + "image_hint": "potatoes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kumara", + "name": "Kumara", + "category_id": "produce", + "aliases": [ + "kumara", + "kumaras", + "kumera", + "sweet potato" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.99, + "image_hint": "kumara", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_onions_brown", + "name": "Onions - Brown", + "category_id": "produce", + "aliases": [ + "brown onions", + "onions", + "onions brown", + "onions - browns", + "onions brown" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.99, + "image_hint": "onions_brown", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_onions_red", + "name": "Onions - Red", + "category_id": "produce", + "aliases": [ + "onions", + "onions red", + "onions - reds", + "onions red", + "red onions" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.99, + "image_hint": "onions_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_garlic", + "name": "Garlic", + "category_id": "produce", + "aliases": [ + "garlic", + "garlic bulb", + "garlics" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 1.99, + "image_hint": "garlic", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_ginger", + "name": "Ginger", + "category_id": "produce", + "aliases": [ + "fresh ginger", + "ginger", + "gingers" + ], + "default_unit": "g", + "default_quantity": 100, + "price": 2.99, + "image_hint": "ginger", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_mushrooms_button", + "name": "Mushrooms - Button", + "category_id": "produce", + "aliases": [ + "button mushrooms", + "mushrooms", + "mushrooms button", + "mushrooms - buttons", + "mushrooms button" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.99, + "image_hint": "mushrooms_button", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_courgette", + "name": "Courgette", + "category_id": "produce", + "aliases": [ + "courgette", + "courgettes", + "zucchini" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 1.99, + "image_hint": "courgette", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_pumpkin", + "name": "Pumpkin", + "category_id": "produce", + "aliases": [ + "butternut", + "pumpkin", + "pumpkins", + "squash" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.99, + "image_hint": "pumpkin", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_spinach", + "name": "Spinach", + "category_id": "produce", + "aliases": [ + "baby spinach", + "spinach", + "spinachs" + ], + "default_unit": "g", + "default_quantity": 120, + "price": 3.99, + "image_hint": "spinach", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_chicken_breast", + "name": "Chicken Breast", + "category_id": "meat", + "aliases": [ + "chicken breast", + "chicken breast fillets", + "chicken breasts" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 16.99, + "brands": [ + "Tegel", + "Inghams" + ], + "image_hint": "chicken_breast", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_thigh", + "name": "Chicken Thighs", + "category_id": "meat", + "aliases": [ + "chicken thigh", + "chicken thigh fillets", + "chicken thighs" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 14.99, + "brands": [ + "Tegel", + "Inghams" + ], + "image_hint": "chicken_thigh", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_drumsticks", + "name": "Chicken Drumsticks", + "category_id": "meat", + "aliases": [ + "chicken drumstick", + "chicken drumsticks", + "drumsticks" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 11.99, + "brands": [ + "Tegel", + "Inghams" + ], + "image_hint": "chicken_drumsticks", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_whole", + "name": "Whole Chicken", + "category_id": "meat", + "aliases": [ + "whole chicken", + "whole chickens", + "whole roasting chicken" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 13.99, + "brands": [ + "Tegel", + "Inghams" + ], + "image_hint": "chicken_whole", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beef_mince", + "name": "Beef Mince", + "category_id": "meat", + "aliases": [ + "beef mince", + "beef minces", + "ground beef", + "mince" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 15.99, + "brands": [ + "Hellers", + "Angus" + ], + "image_hint": "beef_mince", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beef_steak", + "name": "Beef Steak", + "category_id": "meat", + "aliases": [ + "beef steak", + "beef steaks", + "scotch fillet", + "sirloin" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 29.99, + "brands": [ + "Angus", + "Premium" + ], + "image_hint": "beef_steak", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "bbq_meat_group", + "priority_level": 1 + }, + { + "id": "prod_lamb_chops", + "name": "Lamb Chops", + "category_id": "meat", + "aliases": [ + "lamb chop", + "lamb chops", + "lamb loin chops" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 24.99, + "brands": [ + "Coastal Spring", + "Silver Fern Farms" + ], + "image_hint": "lamb_chops", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_lamb_leg", + "name": "Lamb Leg", + "category_id": "meat", + "aliases": [ + "lamb leg", + "lamb legs", + "leg of lamb" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 19.99, + "brands": [ + "Coastal Spring", + "Silver Fern Farms" + ], + "image_hint": "lamb_leg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_pork_chops", + "name": "Pork Chops", + "category_id": "meat", + "aliases": [ + "pork chop", + "pork chops", + "pork loin chops" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 17.99, + "image_hint": "pork_chops", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bacon", + "name": "Bacon", + "category_id": "meat", + "aliases": [ + "bacon", + "bacons", + "middle bacon", + "streaky bacon" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 7.99, + "brands": [ + "Hellers", + "Beehive", + "Freedom Farms" + ], + "image_hint": "bacon", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_sausages", + "name": "Sausages", + "category_id": "meat", + "aliases": [ + "bangers", + "pork sausages", + "sausage", + "sausages" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 11.99, + "brands": [ + "Hellers", + "Farmers Union" + ], + "image_hint": "sausages", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "bbq_meat_group", + "priority_level": 1 + }, + { + "id": "prod_salami", + "name": "Salami", + "category_id": "meat", + "aliases": [ + "italian salami", + "salami", + "salamis" + ], + "default_unit": "g", + "default_quantity": 100, + "price": 5.99, + "brands": [ + "Hellers", + "Continental" + ], + "image_hint": "salami", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ham", + "name": "Ham", + "category_id": "meat", + "aliases": [ + "deli ham", + "ham", + "hams", + "leg ham" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 7.99, + "brands": [ + "Hellers", + "Beehive" + ], + "image_hint": "ham", + "tags": [], + "collections": [ + "christmas" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_salmon_fresh", + "name": "Salmon - Fresh", + "category_id": "meat", + "aliases": [ + "fresh salmon", + "salmon", + "salmon fresh", + "salmon - freshs", + "salmon fillet", + "salmon fresh" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 39.99, + "brands": [ + "Regal", + "Sealord" + ], + "image_hint": "salmon_fresh", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_fish_hoki", + "name": "Hoki Fillets", + "category_id": "meat", + "aliases": [ + "hoki", + "hoki fillet", + "hoki fillets", + "white fish" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 19.99, + "brands": [ + "Sealord", + "Sanford" + ], + "image_hint": "fish_hoki", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_prawns", + "name": "Prawns - Cooked", + "category_id": "meat", + "aliases": [ + "cooked prawns", + "prawns", + "prawns cooked", + "prawns - cookeds", + "prawns cooked", + "shrimp" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 29.99, + "brands": [ + "Sealord" + ], + "image_hint": "prawns", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_mussels", + "name": "Mussels - Green Lipped", + "category_id": "meat", + "aliases": [ + "green lipped mussels", + "mussels", + "mussels green lipped", + "mussels - green lippeds", + "mussels green lipped" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 14.99, + "brands": [ + "Sanford" + ], + "image_hint": "mussels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bread_white", + "name": "Bread - White", + "category_id": "bakery", + "aliases": [ + "bread", + "bread white", + "bread - whites", + "bread white", + "sandwich bread", + "white bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 2.99, + "brands": [ + "Tip Top", + "Freyas", + "Vogels" + ], + "image_hint": "bread_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_wholemeal", + "name": "Bread - Wholemeal", + "category_id": "bakery", + "aliases": [ + "bread", + "bread wholemeal", + "bread - wholemeals", + "bread wholemeal", + "brown bread", + "wholemeal bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 3.49, + "brands": [ + "Tip Top", + "Vogels" + ], + "image_hint": "bread_wholemeal", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [ + "wholegrain" + ], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_vogels", + "name": "Bread - Vogels", + "category_id": "bakery", + "aliases": [ + "bread", + "bread vogels", + "bread - vogel", + "bread vogels", + "seed bread", + "vogels bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 4.99, + "brands": [ + "Vogels" + ], + "image_hint": "bread_vogels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_rolls", + "name": "Bread Rolls", + "category_id": "bakery", + "aliases": [ + "bread roll", + "bread rolls", + "dinner rolls", + "white rolls" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 3.99, + "brands": [ + "Tip Top", + "Bakery" + ], + "image_hint": "bread_rolls", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bagels", + "name": "Bagels", + "category_id": "bakery", + "aliases": [ + "bagel", + "bagels", + "plain bagels" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.99, + "brands": [ + "Tip Top" + ], + "image_hint": "bagels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_english_muffins", + "name": "English Muffins", + "category_id": "bakery", + "aliases": [ + "english muffin", + "english muffins", + "muffins" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.49, + "brands": [ + "Tip Top" + ], + "image_hint": "english_muffins", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wraps", + "name": "Wraps", + "category_id": "bakery", + "aliases": [ + "flour tortillas", + "tortilla wraps", + "wrap", + "wraps" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.99, + "brands": [ + "Mission", + "Farrah's" + ], + "image_hint": "wraps", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_pita_bread", + "name": "Pita Bread", + "category_id": "bakery", + "aliases": [ + "pita bread", + "pita breads", + "pita pocket" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 3.99, + "brands": [ + "Farrah's" + ], + "image_hint": "pita_bread", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_croissants", + "name": "Croissants", + "category_id": "bakery", + "aliases": [ + "butter croissants", + "croissant", + "croissants" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Bakery" + ], + "image_hint": "croissants", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_peas", + "name": "Frozen Peas", + "category_id": "frozen", + "aliases": [ + "frozen pea", + "frozen peas", + "peas frozen" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.99, + "brands": [ + "Watties", + "Pams" + ], + "image_hint": "frozen_peas", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_mixed_veg", + "name": "Frozen Mixed Vegetables", + "category_id": "frozen", + "aliases": [ + "frozen mixed vegetable", + "frozen mixed vegetables", + "frozen vegetables", + "mixed veg" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.49, + "brands": [ + "Watties", + "Pams" + ], + "image_hint": "frozen_mixed_veg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_chips", + "name": "Frozen Chips", + "category_id": "frozen", + "aliases": [ + "french fries", + "frozen chip", + "frozen chips", + "oven chips" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "McCain", + "Watties" + ], + "image_hint": "frozen_chips", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ice_cream_vanilla", + "name": "Ice Cream - Vanilla", + "category_id": "frozen", + "aliases": [ + "ice cream", + "ice cream vanilla", + "ice cream - vanillas", + "ice cream vanilla", + "vanilla ice cream" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 7.99, + "brands": [ + "Tip Top", + "Much Moore" + ], + "image_hint": "ice_cream_vanilla", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ice_cream_hokey_pokey", + "name": "Ice Cream - Hokey Pokey", + "category_id": "frozen", + "aliases": [ + "hokey pokey ice cream", + "ice cream", + "ice cream hokey pokey", + "ice cream - hokey pokeys", + "ice cream hokey pokey" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 8.99, + "brands": [ + "Tip Top" + ], + "image_hint": "ice_cream_hokey_pokey", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_pizza", + "name": "Frozen Pizza", + "category_id": "frozen", + "aliases": [ + "frozen pizza", + "frozen pizzas", + "pizza" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 6.99, + "brands": [ + "Dr Oetker", + "McCain" + ], + "image_hint": "frozen_pizza", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_fish_fingers", + "name": "Fish Fingers", + "category_id": "frozen", + "aliases": [ + "fish finger", + "fish fingers", + "fish sticks" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 7.99, + "brands": [ + "Birds Eye", + "Sealord" + ], + "image_hint": "fish_fingers", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [ + "fish" + ], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_berries", + "name": "Frozen Mixed Berries", + "category_id": "frozen", + "aliases": [ + "frozen berries", + "frozen mixed berrie", + "frozen mixed berries" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 6.99, + "brands": [ + "Pams", + "Value" + ], + "image_hint": "frozen_berries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_rice_white", + "name": "Rice - White", + "category_id": "pantry", + "aliases": [ + "long grain rice", + "rice", + "rice white", + "rice - whites", + "rice white", + "white rice" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.99, + "brands": [ + "Sunrice", + "Pams" + ], + "image_hint": "rice_white", + "tags": [ + "gluten_free", + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [ + "gluten_free" + ], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "rice_group", + "priority_level": 3 + }, + { + "id": "prod_rice_basmati", + "name": "Rice - Basmati", + "category_id": "pantry", + "aliases": [ + "basmati rice", + "rice", + "rice basmati", + "rice - basmatis", + "rice basmati" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Sunrice", + "Tilda" + ], + "image_hint": "rice_basmati", + "tags": [ + "gluten_free", + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [ + "gluten_free" + ], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "rice_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_spaghetti", + "name": "Pasta - Spaghetti", + "category_id": "pantry", + "aliases": [ + "pasta", + "pasta spaghetti", + "pasta - spaghettis", + "pasta spaghetti", + "spaghetti" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 2.99, + "brands": [ + "Barilla", + "Pams", + "San Remo" + ], + "image_hint": "pasta_spaghetti", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_penne", + "name": "Pasta - Penne", + "category_id": "pantry", + "aliases": [ + "pasta", + "pasta penne", + "pasta - pennes", + "pasta penne", + "penne pasta" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 2.99, + "brands": [ + "Barilla", + "Pams", + "San Remo" + ], + "image_hint": "pasta_penne", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_sauce", + "name": "Pasta Sauce", + "category_id": "pantry", + "aliases": [ + "bolognese sauce", + "pasta sauce", + "pasta sauces", + "tomato pasta sauce" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 3.99, + "brands": [ + "Dolmio", + "Watties", + "Barilla" + ], + "image_hint": "pasta_sauce", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_flour_plain", + "name": "Flour - Plain", + "category_id": "pantry", + "aliases": [ + "flour", + "flour plain", + "flour - plains", + "flour plain", + "plain flour", + "white flour" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.49, + "brands": [ + "Champion", + "Edmonds" + ], + "image_hint": "flour_plain", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_flour_self_raising", + "name": "Flour - Self Raising", + "category_id": "pantry", + "aliases": [ + "flour", + "flour self raising", + "flour - self raisings", + "flour self raising", + "self raising flour" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.49, + "brands": [ + "Champion", + "Edmonds" + ], + "image_hint": "flour_self_raising", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_sugar_white", + "name": "Sugar - White", + "category_id": "pantry", + "aliases": [ + "caster sugar", + "sugar", + "sugar white", + "sugar - whites", + "sugar white", + "white sugar" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.99, + "brands": [ + "Chelsea" + ], + "image_hint": "sugar_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_sugar_brown", + "name": "Sugar - Brown", + "category_id": "pantry", + "aliases": [ + "brown sugar", + "soft brown", + "sugar", + "sugar brown", + "sugar - browns", + "sugar brown" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.49, + "brands": [ + "Chelsea" + ], + "image_hint": "sugar_brown", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_oil_olive", + "name": "Olive Oil", + "category_id": "pantry", + "aliases": [ + "EVOO", + "extra virgin olive oil", + "olive oil", + "olive oils" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 12.99, + "brands": [ + "Olivado", + "Pams" + ], + "image_hint": "oil_olive", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_oil_vegetable", + "name": "Vegetable Oil", + "category_id": "pantry", + "aliases": [ + "canola oil", + "cooking oil", + "vegetable oil", + "vegetable oils" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 6.99, + "brands": [ + "Pams", + "Olivani" + ], + "image_hint": "oil_vegetable", + "tags": [ + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tomatoes_canned", + "name": "Canned Tomatoes", + "category_id": "pantry", + "aliases": [ + "canned tomatoe", + "canned tomatoes", + "chopped tomatoes", + "tinned tomatoes" + ], + "default_unit": "can", + "default_quantity": 4, + "price": 1.99, + "brands": [ + "Watties", + "Pams" + ], + "image_hint": "tomatoes_canned", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_baked_beans", + "name": "Baked Beans", + "category_id": "pantry", + "aliases": [ + "baked bean", + "baked beans", + "beans in tomato sauce" + ], + "default_unit": "can", + "default_quantity": 1, + "price": 2.49, + "brands": [ + "Watties", + "Heinz" + ], + "image_hint": "baked_beans", + "tags": [ + "gluten_free" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tuna", + "name": "Tuna in Oil", + "category_id": "pantry", + "aliases": [ + "canned tuna", + "tinned tuna", + "tuna in oil", + "tuna in oils" + ], + "default_unit": "can", + "default_quantity": 3, + "price": 2.99, + "brands": [ + "Sealord", + "John West" + ], + "image_hint": "tuna", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_coconut_cream", + "name": "Coconut Cream", + "category_id": "pantry", + "aliases": [ + "coconut cream", + "coconut creams", + "coconut milk" + ], + "default_unit": "can", + "default_quantity": 2, + "price": 2.99, + "brands": [ + "Ayam", + "Pams" + ], + "image_hint": "coconut_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_peanut_butter", + "name": "Peanut Butter", + "category_id": "pantry", + "aliases": [ + "crunchy peanut butter", + "peanut butter", + "peanut butters", + "smooth peanut butter" + ], + "default_unit": "g", + "default_quantity": 380, + "price": 5.99, + "brands": [ + "Pic's", + "ETA", + "Kraft" + ], + "image_hint": "peanut_butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_jam_strawberry", + "name": "Jam - Strawberry", + "category_id": "pantry", + "aliases": [ + "jam", + "jam strawberry", + "jam - strawberrys", + "jam strawberry", + "strawberry jam" + ], + "default_unit": "g", + "default_quantity": 340, + "price": 4.99, + "brands": [ + "Barker's", + "Anathoth" + ], + "image_hint": "jam_strawberry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_honey", + "name": "Honey", + "category_id": "pantry", + "aliases": [ + "clover honey", + "honey", + "honeys", + "manuka honey" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 8.99, + "brands": [ + "Airborne", + "Manuka Health" + ], + "image_hint": "honey", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_marmite", + "name": "Marmite", + "category_id": "pantry", + "aliases": [ + "marmite", + "marmites", + "yeast spread" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.99, + "brands": [ + "Sanitarium" + ], + "image_hint": "marmite", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_vegemite", + "name": "Vegemite", + "category_id": "pantry", + "aliases": [ + "vegemite", + "vegemites", + "yeast spread" + ], + "default_unit": "g", + "default_quantity": 220, + "price": 5.49, + "brands": [ + "Bega" + ], + "image_hint": "vegemite", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_soy_sauce", + "name": "Soy Sauce", + "category_id": "pantry", + "aliases": [ + "kikkoman", + "soy sauce", + "soy sauces" + ], + "default_unit": "mL", + "default_quantity": 250, + "price": 4.99, + "brands": [ + "Kikkoman", + "Pams" + ], + "image_hint": "soy_sauce", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [ + "soy" + ], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tomato_sauce", + "name": "Tomato Sauce", + "category_id": "pantry", + "aliases": [ + "ketchup", + "tomato ketchup", + "tomato sauce", + "tomato sauces" + ], + "default_unit": "mL", + "default_quantity": 560, + "price": 4.99, + "brands": [ + "Watties", + "Heinz" + ], + "image_hint": "tomato_sauce", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_bbq_sauce", + "name": "BBQ Sauce", + "category_id": "pantry", + "aliases": [ + "barbecue sauce", + "bbq sauce", + "bbq sauces" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 4.99, + "brands": [ + "Watties", + "Masterfoods" + ], + "image_hint": "bbq_sauce", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_mayonnaise", + "name": "Mayonnaise", + "category_id": "pantry", + "aliases": [ + "mayo", + "mayonnaise", + "mayonnaises" + ], + "default_unit": "mL", + "default_quantity": 440, + "price": 5.99, + "brands": [ + "Best Foods", + "Pams" + ], + "image_hint": "mayonnaise", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_mustard", + "name": "Mustard", + "category_id": "pantry", + "aliases": [ + "american mustard", + "dijon mustard", + "mustard", + "mustards" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 3.99, + "brands": [ + "Masterfoods", + "French's" + ], + "image_hint": "mustard", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_salt", + "name": "Salt", + "category_id": "pantry", + "aliases": [ + "cooking salt", + "salt", + "salts", + "table salt" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 1.99, + "brands": [ + "Cerebos" + ], + "image_hint": "salt", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_pepper", + "name": "Black Pepper", + "category_id": "pantry", + "aliases": [ + "black pepper", + "black peppers", + "ground pepper" + ], + "default_unit": "g", + "default_quantity": 50, + "price": 3.99, + "brands": [ + "Masterfoods" + ], + "image_hint": "pepper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_stock_cubes_chicken", + "name": "Stock Cubes - Chicken", + "category_id": "pantry", + "aliases": [ + "bouillon", + "chicken stock", + "stock cubes", + "stock cubes chicken", + "stock cubes - chickens", + "stock cubes chicken" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 2.99, + "brands": [ + "Maggi", + "Continental" + ], + "image_hint": "stock_cubes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_stock_cubes_beef", + "name": "Stock Cubes - Beef", + "category_id": "pantry", + "aliases": [ + "beef stock", + "stock cubes", + "stock cubes beef", + "stock cubes - beefs", + "stock cubes beef" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 2.99, + "brands": [ + "Maggi", + "Continental" + ], + "image_hint": "stock_cubes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_coffee_instant", + "name": "Instant Coffee", + "category_id": "beverages", + "aliases": [ + "coffee", + "instant coffee", + "instant coffees", + "nescafe" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 12.99, + "brands": [ + "Nescafe", + "Gregg's", + "Robert Harris" + ], + "image_hint": "coffee_instant", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_coffee_ground", + "name": "Ground Coffee", + "category_id": "beverages", + "aliases": [ + "filter coffee", + "ground coffee", + "ground coffees" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 8.99, + "brands": [ + "Vittoria", + "Robert Harris", + "L'affare" + ], + "image_hint": "coffee_ground", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tea_black", + "name": "Tea - Black", + "category_id": "beverages", + "aliases": [ + "black tea", + "tea", + "tea black", + "tea - blacks", + "tea bags", + "tea black" + ], + "default_unit": "ea", + "default_quantity": 100, + "price": 6.99, + "brands": [ + "Bell", + "Dilmah", + "Twinings" + ], + "image_hint": "tea_black", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tea_green", + "name": "Tea - Green", + "category_id": "beverages", + "aliases": [ + "green tea", + "tea", + "tea green", + "tea - greens", + "tea green" + ], + "default_unit": "ea", + "default_quantity": 40, + "price": 5.99, + "brands": [ + "Dilmah", + "Twinings" + ], + "image_hint": "tea_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_juice_orange", + "name": "Orange Juice", + "category_id": "beverages", + "aliases": [ + "OJ", + "fresh orange juice", + "orange juice", + "orange juices" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 6.99, + "brands": [ + "Just Juice", + "Charlies" + ], + "image_hint": "juice_orange", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_juice_apple", + "name": "Apple Juice", + "category_id": "beverages", + "aliases": [ + "apple juice", + "apple juices", + "fresh apple juice" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 6.99, + "brands": [ + "Just Juice", + "Charlies" + ], + "image_hint": "juice_apple", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soft_drink_coke", + "name": "Coca Cola", + "category_id": "beverages", + "aliases": [ + "coca cola", + "coca colas", + "coke", + "cola" + ], + "default_unit": "L", + "default_quantity": 2.25, + "price": 4.99, + "brands": [ + "Coca-Cola" + ], + "image_hint": "coke", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soft_drink_lemonade", + "name": "Lemonade", + "category_id": "beverages", + "aliases": [ + "7up", + "lemonade", + "lemonades", + "sprite" + ], + "default_unit": "L", + "default_quantity": 2.25, + "price": 4.99, + "brands": [ + "Schweppes", + "Sprite" + ], + "image_hint": "lemonade", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_water_still", + "name": "Water - Still", + "category_id": "beverages", + "aliases": [ + "bottled water", + "spring water", + "water", + "water still", + "water - stills", + "water still" + ], + "default_unit": "L", + "default_quantity": 1.5, + "price": 2.49, + "brands": [ + "Pump", + "Evian" + ], + "image_hint": "water_still", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_water_sparkling", + "name": "Water - Sparkling", + "category_id": "beverages", + "aliases": [ + "soda water", + "sparkling water", + "water", + "water sparkling", + "water - sparklings", + "water sparkling" + ], + "default_unit": "L", + "default_quantity": 1.5, + "price": 2.99, + "brands": [ + "Schweppes", + "San Pellegrino" + ], + "image_hint": "water_sparkling", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beer", + "name": "Beer", + "category_id": "beverages", + "aliases": [ + "ale", + "beer", + "beers", + "lager" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 24.99, + "brands": [ + "Steinlager", + "DB Export", + "Speights" + ], + "image_hint": "beer", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wine_red", + "name": "Wine - Red", + "category_id": "beverages", + "aliases": [ + "red wine", + "wine", + "wine red", + "wine - reds", + "wine red" + ], + "default_unit": "bottle", + "default_quantity": 1, + "price": 15.99, + "brands": [ + "Oyster Bay", + "Villa Maria" + ], + "image_hint": "wine_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wine_white", + "name": "Wine - White", + "category_id": "beverages", + "aliases": [ + "sauvignon blanc", + "white wine", + "wine", + "wine white", + "wine - whites", + "wine white" + ], + "default_unit": "bottle", + "default_quantity": 1, + "price": 15.99, + "brands": [ + "Oyster Bay", + "Villa Maria", + "Cloudy Bay" + ], + "image_hint": "wine_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_cornflakes", + "name": "Cornflakes", + "category_id": "snacks", + "aliases": [ + "cornflake", + "cornflakes", + "kelloggs cornflakes" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 6.99, + "brands": [ + "Kelloggs", + "Pams" + ], + "image_hint": "cereal_cornflakes", + "tags": [ + "gluten_free" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_weet_bix", + "name": "Weet-Bix", + "category_id": "snacks", + "aliases": [ + "weet bix", + "weet-bix", + "weet-bixs", + "weetbix", + "wheat biscuits" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 7.99, + "brands": [ + "Sanitarium" + ], + "image_hint": "cereal_weet_bix", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_muesli", + "name": "Muesli", + "category_id": "snacks", + "aliases": [ + "muesli", + "mueslis", + "toasted muesli" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 8.99, + "brands": [ + "Hubbards", + "Pams" + ], + "image_hint": "cereal_muesli", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_oats_rolled", + "name": "Rolled Oats", + "category_id": "snacks", + "aliases": [ + "oats", + "porridge oats", + "rolled oat", + "rolled oats" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Harraways", + "Pams" + ], + "image_hint": "oats_rolled", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chips_salt", + "name": "Potato Chips - Salt", + "category_id": "snacks", + "aliases": [ + "crisps", + "potato chips", + "potato chips salt", + "potato chips - salts", + "potato chips salt", + "ready salted chips" + ], + "default_unit": "g", + "default_quantity": 150, + "price": 3.99, + "brands": [ + "Bluebird", + "Eta" + ], + "image_hint": "chips_salt", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chips_chicken", + "name": "Potato Chips - Chicken", + "category_id": "snacks", + "aliases": [ + "chicken chips", + "potato chips", + "potato chips chicken", + "potato chips - chickens", + "potato chips chicken" + ], + "default_unit": "g", + "default_quantity": 150, + "price": 3.99, + "brands": [ + "Bluebird", + "Eta" + ], + "image_hint": "chips_chicken", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_crackers", + "name": "Crackers", + "category_id": "snacks", + "aliases": [ + "cracker", + "crackers", + "savoy", + "water crackers" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 3.99, + "brands": [ + "Griffin's", + "Arnott's" + ], + "image_hint": "crackers", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cookies_chocolate_chip", + "name": "Chocolate Chip Cookies", + "category_id": "snacks", + "aliases": [ + "choc chip biscuits", + "chocolate chip cookie", + "chocolate chip cookies", + "cookies" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.99, + "brands": [ + "Griffin's", + "Cookie Time" + ], + "image_hint": "cookies_chocolate_chip", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tim_tams", + "name": "Tim Tams", + "category_id": "snacks", + "aliases": [ + "chocolate biscuits", + "tim tam", + "tim tams" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.49, + "brands": [ + "Arnott's" + ], + "image_hint": "tim_tams", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chocolate_whittakers", + "name": "Chocolate - Whittaker's", + "category_id": "snacks", + "aliases": [ + "chocolate", + "chocolate whittaker's", + "chocolate - whittaker'", + "chocolate bar", + "chocolate whittaker's", + "whittakers block" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.99, + "brands": [ + "Whittaker's" + ], + "image_hint": "chocolate_whittakers", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chocolate_cadbury", + "name": "Chocolate - Cadbury", + "category_id": "snacks", + "aliases": [ + "cadbury block", + "chocolate", + "chocolate cadbury", + "chocolate - cadburys", + "chocolate cadbury" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 4.99, + "brands": [ + "Cadbury" + ], + "image_hint": "chocolate_cadbury", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_muesli_bars", + "name": "Muesli Bars", + "category_id": "snacks", + "aliases": [ + "granola bars", + "muesli bar", + "muesli bars" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Uncle Tobys", + "Nice & Natural" + ], + "image_hint": "muesli_bars", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_popcorn", + "name": "Popcorn", + "category_id": "snacks", + "aliases": [ + "microwave popcorn", + "popcorn", + "popcorns" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.99, + "brands": [ + "Eta", + "Proper" + ], + "image_hint": "popcorn", + "tags": [ + "gluten_free" + ], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_nuts_mixed", + "name": "Mixed Nuts", + "category_id": "snacks", + "aliases": [ + "mixed nut", + "mixed nuts", + "roasted nuts" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 6.99, + "brands": [ + "Eta", + "Pams" + ], + "image_hint": "nuts_mixed", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toilet_paper", + "name": "Toilet Paper", + "category_id": "household", + "aliases": [ + "TP", + "bathroom tissue", + "toilet paper", + "toilet papers" + ], + "default_unit": "roll", + "default_quantity": 12, + "price": 12.99, + "brands": [ + "Sorbent", + "Purex" + ], + "image_hint": "toilet_paper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_paper_towels", + "name": "Paper Towels", + "category_id": "household", + "aliases": [ + "kitchen paper", + "paper towel", + "paper towels" + ], + "default_unit": "roll", + "default_quantity": 4, + "price": 8.99, + "brands": [ + "Handee", + "Sorbent" + ], + "image_hint": "paper_towels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tissues", + "name": "Tissues", + "category_id": "household", + "aliases": [ + "facial tissues", + "kleenex", + "tissue", + "tissues" + ], + "default_unit": "box", + "default_quantity": 4, + "price": 7.99, + "brands": [ + "Kleenex", + "Sorbent" + ], + "image_hint": "tissues", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dishwashing_liquid", + "name": "Dishwashing Liquid", + "category_id": "household", + "aliases": [ + "dish soap", + "dishwash", + "dishwashing liquid", + "dishwashing liquids" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 4.99, + "brands": [ + "Sunlight", + "Morning Fresh" + ], + "image_hint": "dishwashing_liquid", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dishwasher_tablets", + "name": "Dishwasher Tablets", + "category_id": "household", + "aliases": [ + "dishwasher pods", + "dishwasher tablet", + "dishwasher tablets" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 14.99, + "brands": [ + "Finish", + "Earthwise" + ], + "image_hint": "dishwasher_tablets", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_laundry_powder", + "name": "Laundry Powder", + "category_id": "household", + "aliases": [ + "laundry powder", + "laundry powders", + "washing powder" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 16.99, + "brands": [ + "Persil", + "OMO", + "Earthwise" + ], + "image_hint": "laundry_powder", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_laundry_liquid", + "name": "Laundry Liquid", + "category_id": "household", + "aliases": [ + "laundry liquid", + "laundry liquids", + "washing liquid" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 14.99, + "brands": [ + "Persil", + "OMO", + "Earthwise" + ], + "image_hint": "laundry_liquid", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_fabric_softener", + "name": "Fabric Softener", + "category_id": "household", + "aliases": [ + "comfort", + "downy", + "fabric softener", + "fabric softeners" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 9.99, + "brands": [ + "Comfort", + "Earthwise" + ], + "image_hint": "fabric_softener", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_spray_cleaner", + "name": "Spray Cleaner", + "category_id": "household", + "aliases": [ + "multi-purpose cleaner", + "spray cleaner", + "spray cleaners", + "spray n wipe" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 6.99, + "brands": [ + "Spray n Wipe", + "Jif" + ], + "image_hint": "spray_cleaner", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bleach", + "name": "Bleach", + "category_id": "household", + "aliases": [ + "bleach", + "bleachs", + "janola" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Janola", + "Domestos" + ], + "image_hint": "bleach", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bin_bags", + "name": "Bin Bags", + "category_id": "household", + "aliases": [ + "bin bag", + "bin bags", + "garbage bags", + "rubbish bags" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 8.99, + "brands": [ + "Glad", + "Ecostore" + ], + "image_hint": "bin_bags", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cling_film", + "name": "Cling Film", + "category_id": "household", + "aliases": [ + "cling film", + "cling films", + "glad wrap", + "plastic wrap" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Glad", + "Multix" + ], + "image_hint": "cling_film", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_aluminium_foil", + "name": "Aluminium Foil", + "category_id": "household", + "aliases": [ + "alfoil", + "aluminium foil", + "aluminium foils", + "tin foil" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 6.99, + "brands": [ + "Alfoil", + "Multix" + ], + "image_hint": "aluminium_foil", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baking_paper", + "name": "Baking Paper", + "category_id": "household", + "aliases": [ + "baking paper", + "baking papers", + "parchment paper" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 4.99, + "brands": [ + "Multix", + "Alfoil" + ], + "image_hint": "baking_paper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_shampoo", + "name": "Shampoo", + "category_id": "health", + "aliases": [ + "hair shampoo", + "shampoo", + "shampoos" + ], + "default_unit": "mL", + "default_quantity": 400, + "price": 8.99, + "brands": [ + "Pantene", + "Head & Shoulders", + "Garnier" + ], + "image_hint": "shampoo", + "tags": [], + "collections": [ + "christmas" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_conditioner", + "name": "Conditioner", + "category_id": "health", + "aliases": [ + "conditioner", + "conditioners", + "hair conditioner" + ], + "default_unit": "mL", + "default_quantity": 400, + "price": 8.99, + "brands": [ + "Pantene", + "Head & Shoulders", + "Garnier" + ], + "image_hint": "conditioner", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_body_wash", + "name": "Body Wash", + "category_id": "health", + "aliases": [ + "body wash", + "body washs", + "shower gel" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 7.99, + "brands": [ + "Dove", + "Palmolive", + "Nivea" + ], + "image_hint": "body_wash", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soap_bar", + "name": "Bar Soap", + "category_id": "health", + "aliases": [ + "bar soap", + "bar soaps", + "bath soap", + "hand soap" + ], + "default_unit": "bar", + "default_quantity": 4, + "price": 4.99, + "brands": [ + "Dove", + "Palmolive" + ], + "image_hint": "soap_bar", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toothpaste", + "name": "Toothpaste", + "category_id": "health", + "aliases": [ + "colgate", + "toothpaste", + "toothpastes" + ], + "default_unit": "g", + "default_quantity": 110, + "price": 5.99, + "brands": [ + "Colgate", + "Sensodyne" + ], + "image_hint": "toothpaste", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toothbrush", + "name": "Toothbrush", + "category_id": "health", + "aliases": [ + "tooth brush", + "toothbrush", + "toothbrushs" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 6.99, + "brands": [ + "Colgate", + "Oral-B" + ], + "image_hint": "toothbrush", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_deodorant", + "name": "Deodorant", + "category_id": "health", + "aliases": [ + "antiperspirant", + "deodorant", + "deodorants" + ], + "default_unit": "g", + "default_quantity": 50, + "price": 7.99, + "brands": [ + "Rexona", + "Dove", + "Lynx" + ], + "image_hint": "deodorant", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_razor_blades", + "name": "Razor Blades", + "category_id": "health", + "aliases": [ + "gillette", + "razor blade", + "razor blades", + "shaving blades" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 19.99, + "brands": [ + "Gillette", + "Schick" + ], + "image_hint": "razor_blades", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_shaving_cream", + "name": "Shaving Cream", + "category_id": "health", + "aliases": [ + "shave gel", + "shaving cream", + "shaving creams" + ], + "default_unit": "mL", + "default_quantity": 200, + "price": 6.99, + "brands": [ + "Gillette", + "Nivea" + ], + "image_hint": "shaving_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_sunscreen", + "name": "Sunscreen SPF50", + "category_id": "health", + "aliases": [ + "sun cream", + "sunblock", + "sunscreen spf50", + "sunscreen spf50s" + ], + "default_unit": "mL", + "default_quantity": 200, + "price": 14.99, + "brands": [ + "Neutrogena", + "Cancer Society" + ], + "image_hint": "sunscreen", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_paracetamol", + "name": "Paracetamol", + "category_id": "health", + "aliases": [ + "pain relief", + "panadol", + "paracetamol", + "paracetamols" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 8.99, + "brands": [ + "Panadol", + "Pams" + ], + "image_hint": "paracetamol", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ibuprofen", + "name": "Ibuprofen", + "category_id": "health", + "aliases": [ + "ibuprofen", + "ibuprofens", + "nurofen", + "pain relief" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 9.99, + "brands": [ + "Nurofen", + "Pams" + ], + "image_hint": "ibuprofen", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bandaids", + "name": "Band-Aids", + "category_id": "health", + "aliases": [ + "band aids", + "band-aid", + "band-aids", + "bandages", + "plasters" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Band-Aid", + "Elastoplast" + ], + "image_hint": "bandaids", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_vitamins_c", + "name": "Vitamin C", + "category_id": "health", + "aliases": [ + "vitamin c", + "vitamin c tablets", + "vitamin cs" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 12.99, + "brands": [ + "Healtheries", + "Blackmores" + ], + "image_hint": "vitamins_c", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_nappies", + "name": "Nappies", + "category_id": "baby", + "aliases": [ + "baby nappies", + "diapers", + "nappie", + "nappies" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 29.99, + "brands": [ + "Huggies", + "Pams" + ], + "image_hint": "nappies", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baby_wipes", + "name": "Baby Wipes", + "category_id": "baby", + "aliases": [ + "baby wipe", + "baby wipes", + "wet wipes" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.99, + "brands": [ + "Huggies", + "Pams" + ], + "image_hint": "baby_wipes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baby_formula", + "name": "Baby Formula", + "category_id": "baby", + "aliases": [ + "baby formula", + "baby formulas", + "infant formula" + ], + "default_unit": "g", + "default_quantity": 900, + "price": 29.99, + "brands": [ + "Karicare", + "Aptamil" + ], + "image_hint": "baby_formula", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dog_food_dry", + "name": "Dog Food - Dry", + "category_id": "pet", + "aliases": [ + "dog biscuits", + "dog food", + "dog food dry", + "dog food - drys", + "dog food dry", + "dog kibble" + ], + "default_unit": "kg", + "default_quantity": 3, + "price": 24.99, + "brands": [ + "Eukanuba", + "Pedigree" + ], + "image_hint": "dog_food_dry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dog_food_wet", + "name": "Dog Food - Wet", + "category_id": "pet", + "aliases": [ + "canned dog food", + "dog food", + "dog food wet", + "dog food - wets", + "dog food wet" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 19.99, + "brands": [ + "Pedigree", + "Champ" + ], + "image_hint": "dog_food_wet", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_food_dry", + "name": "Cat Food - Dry", + "category_id": "pet", + "aliases": [ + "cat biscuits", + "cat food", + "cat food dry", + "cat food - drys", + "cat food dry" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 19.99, + "brands": [ + "Whiskas", + "Fancy Feast" + ], + "image_hint": "cat_food_dry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_food_wet", + "name": "Cat Food - Wet", + "category_id": "pet", + "aliases": [ + "canned cat food", + "cat food", + "cat food wet", + "cat food - wets", + "cat food wet" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 14.99, + "brands": [ + "Whiskas", + "Fancy Feast" + ], + "image_hint": "cat_food_wet", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_litter", + "name": "Cat Litter", + "category_id": "pet", + "aliases": [ + "cat litter", + "cat litters", + "kitty litter" + ], + "default_unit": "kg", + "default_quantity": 5, + "price": 12.99, + "brands": [ + "Catlove", + "Paws" + ], + "image_hint": "cat_litter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + } + ] +} \ No newline at end of file diff --git a/custom_components/shopping_list_manager/data/products_catalog_us.json b/custom_components/shopping_list_manager/data/products_catalog_us.json new file mode 100644 index 0000000..4aa1450 --- /dev/null +++ b/custom_components/shopping_list_manager/data/products_catalog_us.json @@ -0,0 +1,6471 @@ +{ + "version": "2.2.0", + "region": "US", + "currency": "USD", + "last_updated": "2026-02-13", + "description": "Clean US grocery catalog with expanded US supermarket brands", + "products": [ + { + "id": "prod_milk_trim", + "name": "Milk - Trim", + "category_id": "dairy", + "aliases": [ + "low fat milk", + "milk", + "milk trim", + "milk - trims", + "milk trim", + "skim milk", + "trim milk" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 4.12, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "Kroger", + "Meadow Fresh", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "barcode": "9400547000019", + "image_hint": "milk_trim", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "milk" + ], + "substitution_group": "milk_group", + "priority_level": 5 + }, + { + "id": "prod_milk_whole", + "name": "Milk - Whole", + "category_id": "dairy", + "aliases": [ + "blue top milk", + "full cream milk", + "milk", + "milk whole", + "milk - wholes", + "milk whole", + "whole milk" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 3.92, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "Kroger", + "Meadow Fresh", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "barcode": "9400547000026", + "image_hint": "milk_whole", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "milk" + ], + "substitution_group": "milk_group", + "priority_level": 5 + }, + { + "id": "prod_butter_salted", + "name": "Butter - Salted", + "category_id": "dairy", + "aliases": [ + "butter", + "butter salted", + "butter - salteds", + "butter salted", + "salted butter" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 6.37, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Westgold", + "Whole Foods" + ], + "image_hint": "butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_butter_unsalted", + "name": "Butter - Unsalted", + "category_id": "dairy", + "aliases": [ + "butter", + "butter unsalted", + "butter - unsalteds", + "butter unsalted", + "unsalted butter" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 8.18, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cheese_tasty", + "name": "Cheese - Tasty", + "category_id": "dairy", + "aliases": [ + "cheddar", + "cheese", + "cheese tasty", + "cheese - tastys", + "cheese block", + "cheese tasty", + "tasty cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 9.87, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "cheese_tasty", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_edam", + "name": "Cheese - Edam", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese edam", + "cheese - edams", + "cheese edam", + "edam cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 9.51, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "cheese_edam", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_colby", + "name": "Cheese - Colby", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese colby", + "cheese - colbys", + "cheese colby", + "colby cheese" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 8.85, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "cheese_colby", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_cheese_grated", + "name": "Cheese - Grated", + "category_id": "dairy", + "aliases": [ + "cheese", + "cheese grated", + "cheese - grateds", + "cheese grated", + "grated cheese", + "shredded cheese" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 6.43, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "cheese_grated", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "cheese_group", + "priority_level": 4 + }, + { + "id": "prod_yogurt_plain", + "name": "Yogurt - Plain", + "category_id": "dairy", + "aliases": [ + "natural yogurt", + "plain yogurt", + "yogurt", + "yogurt plain", + "yogurt - plains", + "yogurt plain" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.94, + "brands": [ + "Costco", + "Cyclone", + "Great Value", + "H-E-B", + "Kroger", + "Meadow Fresh", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "yogurt_plain", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "yogurt_group", + "priority_level": 4 + }, + { + "id": "prod_yogurt_greek", + "name": "Yogurt - Greek", + "category_id": "dairy", + "aliases": [ + "greek yogurt", + "yogurt", + "yogurt greek", + "yogurt - greeks", + "yogurt greek" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 7.84, + "brands": [ + "Chobani", + "Costco", + "Farmers Union", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "yogurt_greek", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "yogurt_group", + "priority_level": 4 + }, + { + "id": "prod_eggs_free_range", + "name": "Eggs - Free Range", + "category_id": "dairy", + "aliases": [ + "eggs", + "eggs free range", + "eggs - free ranges", + "eggs free range", + "free range eggs" + ], + "default_unit": "ea", + "default_quantity": 12, + "price": 9.84, + "brands": [ + "365 by Whole Foods", + "Costco", + "Farmer Brown", + "Frenz", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods", + "Woodland" + ], + "image_hint": "eggs_free_range", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "eggs" + ], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_eggs_cage", + "name": "Eggs - Cage", + "category_id": "dairy", + "aliases": [ + "budget eggs", + "cage eggs", + "eggs", + "eggs cage", + "eggs - cages", + "eggs cage" + ], + "default_unit": "ea", + "default_quantity": 12, + "price": 6.79, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Value", + "Walmart", + "Whole Foods" + ], + "image_hint": "eggs", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [ + "eggs" + ], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cream", + "name": "Cream - Fresh", + "category_id": "dairy", + "aliases": [ + "cream", + "cream fresh", + "cream - freshs", + "cream fresh", + "fresh cream", + "pouring cream" + ], + "default_unit": "mL", + "default_quantity": 300, + "price": 4.72, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Meadow Fresh", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_sour_cream", + "name": "Sour Cream", + "category_id": "dairy", + "aliases": [ + "sour cream", + "sour creams" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.28, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Meadow Fresh", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "sour_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_apples_gala", + "name": "Apples - Gala", + "category_id": "produce", + "aliases": [ + "apples", + "apples gala", + "apples - galas", + "apples gala", + "gala apples" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.51, + "image_hint": "apples_gala", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_apples_granny_smith", + "name": "Apples - Granny Smith", + "category_id": "produce", + "aliases": [ + "apples", + "apples granny smith", + "apples - granny smiths", + "apples granny smith", + "granny smith", + "green apples" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.22, + "image_hint": "apples_granny_smith", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_bananas", + "name": "Bananas", + "category_id": "produce", + "aliases": [ + "banana", + "bananas" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.68, + "image_hint": "bananas", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_oranges", + "name": "Oranges", + "category_id": "produce", + "aliases": [ + "orange", + "oranges" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.24, + "image_hint": "oranges", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_mandarins", + "name": "Mandarins", + "category_id": "produce", + "aliases": [ + "easy peelers", + "mandarin", + "mandarins" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.49, + "image_hint": "mandarins", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kiwifruit_green", + "name": "Kiwifruit - Green", + "category_id": "produce", + "aliases": [ + "green kiwifruit", + "kiwi", + "kiwifruit", + "kiwifruit green", + "kiwifruit - greens", + "kiwifruit green" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 7.13, + "image_hint": "kiwifruit_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kiwifruit_gold", + "name": "Kiwifruit - Gold", + "category_id": "produce", + "aliases": [ + "gold kiwifruit", + "kiwifruit", + "kiwifruit gold", + "kiwifruit - golds", + "kiwifruit gold", + "sungold" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 8.82, + "image_hint": "kiwifruit_gold", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_strawberries", + "name": "Strawberries", + "category_id": "produce", + "aliases": [ + "strawberrie", + "strawberries", + "strawberry" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.62, + "image_hint": "strawberries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_blueberries", + "name": "Blueberries", + "category_id": "produce", + "aliases": [ + "blueberrie", + "blueberries", + "blueberry" + ], + "default_unit": "g", + "default_quantity": 125, + "price": 6.64, + "image_hint": "blueberries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_grapes_green", + "name": "Grapes - Green", + "category_id": "produce", + "aliases": [ + "grapes", + "grapes green", + "grapes - greens", + "grapes green", + "green grapes", + "white grapes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 7.32, + "image_hint": "grapes_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_grapes_red", + "name": "Grapes - Red", + "category_id": "produce", + "aliases": [ + "grapes", + "grapes red", + "grapes - reds", + "grapes red", + "red grapes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 8.53, + "image_hint": "grapes_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_avocado", + "name": "Avocados", + "category_id": "produce", + "aliases": [ + "avo", + "avocado", + "avocados" + ], + "default_unit": "ea", + "default_quantity": 3, + "price": 3.0, + "image_hint": "avocado", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_tomatoes", + "name": "Tomatoes", + "category_id": "produce", + "aliases": [ + "tomato", + "tomatoe", + "tomatoes" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 6.85, + "image_hint": "tomatoes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_tomatoes_cherry", + "name": "Cherry Tomatoes", + "category_id": "produce", + "aliases": [ + "cherry tomato", + "cherry tomatoe", + "cherry tomatoes" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.05, + "image_hint": "tomatoes_cherry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cucumber", + "name": "Cucumber", + "category_id": "produce", + "aliases": [ + "cucumber", + "cucumbers" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.12, + "image_hint": "cucumber", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_lettuce_iceberg", + "name": "Lettuce - Iceberg", + "category_id": "produce", + "aliases": [ + "iceberg lettuce", + "lettuce", + "lettuce iceberg", + "lettuce - icebergs", + "lettuce iceberg" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 4.18, + "image_hint": "lettuce_iceberg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_lettuce_cos", + "name": "Lettuce - Cos", + "category_id": "produce", + "aliases": [ + "cos lettuce", + "lettuce", + "lettuce cos", + "lettuce - co", + "lettuce cos", + "romaine" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 4.25, + "image_hint": "lettuce_cos", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_capsicum_red", + "name": "Capsicum - Red", + "category_id": "produce", + "aliases": [ + "capsicum", + "capsicum red", + "capsicum - reds", + "capsicum red", + "red capsicum", + "red pepper" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 2.61, + "image_hint": "capsicum_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_capsicum_green", + "name": "Capsicum - Green", + "category_id": "produce", + "aliases": [ + "capsicum", + "capsicum green", + "capsicum - greens", + "capsicum green", + "green capsicum", + "green pepper" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 1.9, + "image_hint": "capsicum_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_broccoli", + "name": "Broccoli", + "category_id": "produce", + "aliases": [ + "broccoli", + "broccoli head", + "broccolis" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 3.71, + "image_hint": "broccoli", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_cauliflower", + "name": "Cauliflower", + "category_id": "produce", + "aliases": [ + "cauli", + "cauliflower", + "cauliflowers" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 4.91, + "image_hint": "cauliflower", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_carrots", + "name": "Carrots", + "category_id": "produce", + "aliases": [ + "carrot", + "carrots" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.19, + "image_hint": "carrots", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_potatoes", + "name": "Potatoes", + "category_id": "produce", + "aliases": [ + "potato", + "potatoe", + "potatoes", + "spuds" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 5.3, + "image_hint": "potatoes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_kumara", + "name": "Sweet Potato", + "category_id": "produce", + "aliases": [ + "kumara", + "kumaras", + "kumera", + "sweet potato", + "sweet potato" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.56, + "image_hint": "kumara", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_onions_brown", + "name": "Onions - Brown", + "category_id": "produce", + "aliases": [ + "brown onions", + "onions", + "onions brown", + "onions - browns", + "onions brown" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.84, + "image_hint": "onions_brown", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_onions_red", + "name": "Onions - Red", + "category_id": "produce", + "aliases": [ + "onions", + "onions red", + "onions - reds", + "onions red", + "red onions" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.82, + "image_hint": "onions_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_garlic", + "name": "Garlic", + "category_id": "produce", + "aliases": [ + "garlic", + "garlic bulb", + "garlics" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 2.1, + "image_hint": "garlic", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_ginger", + "name": "Ginger", + "category_id": "produce", + "aliases": [ + "fresh ginger", + "ginger", + "gingers" + ], + "default_unit": "g", + "default_quantity": 100, + "price": 3.05, + "image_hint": "ginger", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_mushrooms_button", + "name": "Mushrooms - Button", + "category_id": "produce", + "aliases": [ + "button mushrooms", + "mushrooms", + "mushrooms button", + "mushrooms - buttons", + "mushrooms button" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.09, + "image_hint": "mushrooms_button", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_courgette", + "name": "Courgette", + "category_id": "produce", + "aliases": [ + "courgette", + "courgettes", + "zucchini" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 2.17, + "image_hint": "courgette", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_pumpkin", + "name": "Pumpkin", + "category_id": "produce", + "aliases": [ + "butternut", + "pumpkin", + "pumpkins", + "squash" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.72, + "image_hint": "pumpkin", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_spinach", + "name": "Spinach", + "category_id": "produce", + "aliases": [ + "baby spinach", + "spinach", + "spinachs" + ], + "default_unit": "g", + "default_quantity": 120, + "price": 3.76, + "image_hint": "spinach", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 4 + }, + { + "id": "prod_chicken_breast", + "name": "Chicken Breast", + "category_id": "meat", + "aliases": [ + "chicken breast", + "chicken breast fillets", + "chicken breasts" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 17.37, + "brands": [ + "Costco", + "H-E-B", + "Inghams", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Tegel", + "Walmart", + "Whole Foods" + ], + "image_hint": "chicken_breast", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_thigh", + "name": "Chicken Thighs", + "category_id": "meat", + "aliases": [ + "chicken thigh", + "chicken thigh fillets", + "chicken thighs" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 14.61, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Inghams", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Tegel", + "Walmart", + "Whole Foods" + ], + "image_hint": "chicken_thigh", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_drumsticks", + "name": "Chicken Drumsticks", + "category_id": "meat", + "aliases": [ + "chicken drumstick", + "chicken drumsticks", + "drumsticks" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 12.75, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Inghams", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Tegel", + "Walmart", + "Whole Foods" + ], + "image_hint": "chicken_drumsticks", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chicken_whole", + "name": "Whole Chicken", + "category_id": "meat", + "aliases": [ + "whole chicken", + "whole chickens", + "whole roasting chicken" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 15.27, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "Inghams", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Tegel", + "Walmart", + "Whole Foods" + ], + "image_hint": "chicken_whole", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beef_mince", + "name": "Beef Mince", + "category_id": "meat", + "aliases": [ + "beef mince", + "beef minces", + "ground beef", + "mince" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 17.06, + "brands": [ + "365 by Whole Foods", + "Angus", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "beef_mince", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beef_steak", + "name": "Beef Steak", + "category_id": "meat", + "aliases": [ + "beef steak", + "beef steaks", + "scotch fillet", + "sirloin" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 27.61, + "brands": [ + "Angus", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Premium", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "beef_steak", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "bbq_meat_group", + "priority_level": 1 + }, + { + "id": "prod_lamb_chops", + "name": "Lamb Chops", + "category_id": "meat", + "aliases": [ + "lamb chop", + "lamb chops", + "lamb loin chops" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 23.76, + "brands": [ + "Coastal Spring", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Silver Fern Farms", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "lamb_chops", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_lamb_leg", + "name": "Lamb Leg", + "category_id": "meat", + "aliases": [ + "lamb leg", + "lamb legs", + "leg of lamb" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 18.51, + "brands": [ + "Coastal Spring", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Silver Fern Farms", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "lamb_leg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_pork_chops", + "name": "Pork Chops", + "category_id": "meat", + "aliases": [ + "pork chop", + "pork chops", + "pork loin chops" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 18.37, + "image_hint": "pork_chops", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bacon", + "name": "Bacon", + "category_id": "meat", + "aliases": [ + "bacon", + "bacons", + "middle bacon", + "streaky bacon" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 8.41, + "brands": [ + "Beehive", + "Costco", + "Freedom Farms", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "bacon", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_sausages", + "name": "Sausages", + "category_id": "meat", + "aliases": [ + "bangers", + "pork sausages", + "sausage", + "sausages" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 11.09, + "brands": [ + "365 by Whole Foods", + "Costco", + "Farmers Union", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "sausages", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": "bbq_meat_group", + "priority_level": 1 + }, + { + "id": "prod_salami", + "name": "Salami", + "category_id": "meat", + "aliases": [ + "italian salami", + "salami", + "salamis" + ], + "default_unit": "g", + "default_quantity": 100, + "price": 6.2, + "brands": [ + "Continental", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "salami", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ham", + "name": "Ham", + "category_id": "meat", + "aliases": [ + "deli ham", + "ham", + "hams", + "leg ham" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 7.96, + "brands": [ + "Beehive", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "ham", + "tags": [], + "collections": [ + "christmas" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_salmon_fresh", + "name": "Salmon - Fresh", + "category_id": "meat", + "aliases": [ + "fresh salmon", + "salmon", + "salmon fresh", + "salmon - freshs", + "salmon fillet", + "salmon fresh" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 41.49, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Regal", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "salmon_fresh", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_fish_hoki", + "name": "Hoki Fillets", + "category_id": "meat", + "aliases": [ + "hoki", + "hoki fillet", + "hoki fillets", + "white fish" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 19.94, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Sanford", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "fish_hoki", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_prawns", + "name": "Prawns - Cooked", + "category_id": "meat", + "aliases": [ + "cooked prawns", + "prawns", + "prawns cooked", + "prawns - cookeds", + "prawns cooked", + "shrimp" + ], + "default_unit": "kg", + "default_quantity": 0.5, + "price": 30.24, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "prawns", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_mussels", + "name": "Mussels - Green Lipped", + "category_id": "meat", + "aliases": [ + "green lipped mussels", + "mussels", + "mussels green lipped", + "mussels - green lippeds", + "mussels green lipped" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 15.38, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Sanford", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "mussels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "fridge" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bread_white", + "name": "Bread - White", + "category_id": "bakery", + "aliases": [ + "bread", + "bread white", + "bread - whites", + "bread white", + "sandwich bread", + "white bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 3.03, + "brands": [ + "365 by Whole Foods", + "Costco", + "Freyas", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Vogels", + "Walmart", + "Whole Foods" + ], + "image_hint": "bread_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_wholemeal", + "name": "Bread - Wholemeal", + "category_id": "bakery", + "aliases": [ + "bread", + "bread wholemeal", + "bread - wholemeals", + "bread wholemeal", + "brown bread", + "wholemeal bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 3.83, + "brands": [ + "365 by Whole Foods", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Vogels", + "Walmart", + "Whole Foods" + ], + "image_hint": "bread_wholemeal", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [ + "wholegrain" + ], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_vogels", + "name": "Bread - Vogels", + "category_id": "bakery", + "aliases": [ + "bread", + "bread vogels", + "bread - vogel", + "bread vogels", + "seed bread", + "vogels bread" + ], + "default_unit": "loaf", + "default_quantity": 1, + "price": 5.23, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Vogels", + "Walmart", + "Whole Foods" + ], + "image_hint": "bread_vogels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bread_rolls", + "name": "Bread Rolls", + "category_id": "bakery", + "aliases": [ + "bread roll", + "bread rolls", + "dinner rolls", + "white rolls" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.26, + "brands": [ + "Bakery", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "bread_rolls", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_bagels", + "name": "Bagels", + "category_id": "bakery", + "aliases": [ + "bagel", + "bagels", + "plain bagels" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.8, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "bagels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_english_muffins", + "name": "English Muffins", + "category_id": "bakery", + "aliases": [ + "english muffin", + "english muffins", + "muffins" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.64, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "english_muffins", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wraps", + "name": "Wraps", + "category_id": "bakery", + "aliases": [ + "flour tortillas", + "tortilla wraps", + "wrap", + "wraps" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.53, + "brands": [ + "Costco", + "Farrah's", + "H-E-B", + "Kroger", + "Mission", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "wraps", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_pita_bread", + "name": "Pita Bread", + "category_id": "bakery", + "aliases": [ + "pita bread", + "pita breads", + "pita pocket" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.11, + "brands": [ + "365 by Whole Foods", + "Costco", + "Farrah's", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "pita_bread", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "bread_group", + "priority_level": 1 + }, + { + "id": "prod_croissants", + "name": "Croissants", + "category_id": "bakery", + "aliases": [ + "butter croissants", + "croissant", + "croissants" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.76, + "brands": [ + "365 by Whole Foods", + "Bakery", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "croissants", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_peas", + "name": "Frozen Peas", + "category_id": "frozen", + "aliases": [ + "frozen pea", + "frozen peas", + "peas frozen" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.57, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "frozen_peas", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_mixed_veg", + "name": "Frozen Mixed Vegetables", + "category_id": "frozen", + "aliases": [ + "frozen mixed vegetable", + "frozen mixed vegetables", + "frozen vegetables", + "mixed veg" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.12, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "frozen_mixed_veg", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_chips", + "name": "Frozen Chips", + "category_id": "frozen", + "aliases": [ + "french fries", + "frozen chip", + "frozen chips", + "oven chips" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.84, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "Kroger", + "McCain", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "frozen_chips", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ice_cream_vanilla", + "name": "Ice Cream - Vanilla", + "category_id": "frozen", + "aliases": [ + "ice cream", + "ice cream vanilla", + "ice cream - vanillas", + "ice cream vanilla", + "vanilla ice cream" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 8.73, + "brands": [ + "365 by Whole Foods", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Much Moore", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "ice_cream_vanilla", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ice_cream_hokey_pokey", + "name": "Ice Cream - Hokey Pokey", + "category_id": "frozen", + "aliases": [ + "hokey pokey ice cream", + "ice cream", + "ice cream hokey pokey", + "ice cream - hokey pokeys", + "ice cream hokey pokey" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 9.63, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "ice_cream_hokey_pokey", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_pizza", + "name": "Frozen Pizza", + "category_id": "frozen", + "aliases": [ + "frozen pizza", + "frozen pizzas", + "pizza" + ], + "default_unit": "ea", + "default_quantity": 1, + "price": 6.89, + "brands": [ + "Costco", + "Dr Oetker", + "H-E-B", + "Kroger", + "McCain", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "frozen_pizza", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_fish_fingers", + "name": "Fish Fingers", + "category_id": "frozen", + "aliases": [ + "fish finger", + "fish fingers", + "fish sticks" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 7.61, + "brands": [ + "365 by Whole Foods", + "Birds Eye", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "fish_fingers", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [ + "fish" + ], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_frozen_berries", + "name": "Frozen Mixed Berries", + "category_id": "frozen", + "aliases": [ + "frozen berries", + "frozen mixed berrie", + "frozen mixed berries" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 7.24, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Value", + "Walmart", + "Whole Foods" + ], + "image_hint": "frozen_berries", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "freezer" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_rice_white", + "name": "Rice - White", + "category_id": "pantry", + "aliases": [ + "long grain rice", + "rice", + "rice white", + "rice - whites", + "rice white", + "white rice" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 3.88, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Sunrice", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "rice_white", + "tags": [ + "gluten_free", + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [ + "gluten_free" + ], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "rice_group", + "priority_level": 3 + }, + { + "id": "prod_rice_basmati", + "name": "Rice - Basmati", + "category_id": "pantry", + "aliases": [ + "basmati rice", + "rice", + "rice basmati", + "rice - basmatis", + "rice basmati" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 6.3, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Sunrice", + "Target", + "Tilda", + "Walmart", + "Whole Foods" + ], + "image_hint": "rice_basmati", + "tags": [ + "gluten_free", + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [ + "gluten_free" + ], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "rice_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_spaghetti", + "name": "Pasta - Spaghetti", + "category_id": "pantry", + "aliases": [ + "pasta", + "pasta spaghetti", + "pasta - spaghettis", + "pasta spaghetti", + "spaghetti" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 2.88, + "brands": [ + "Barilla", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "San Remo", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "pasta_spaghetti", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_penne", + "name": "Pasta - Penne", + "category_id": "pantry", + "aliases": [ + "pasta", + "pasta penne", + "pasta - pennes", + "pasta penne", + "penne pasta" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 2.7, + "brands": [ + "Barilla", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "San Remo", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "pasta_penne", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_pasta_sauce", + "name": "Pasta Sauce", + "category_id": "pantry", + "aliases": [ + "bolognese sauce", + "pasta sauce", + "pasta sauces", + "tomato pasta sauce" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 3.85, + "brands": [ + "Barilla", + "Costco", + "Dolmio", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "pasta_sauce", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": "pasta_group", + "priority_level": 3 + }, + { + "id": "prod_flour_plain", + "name": "Flour - Plain", + "category_id": "pantry", + "aliases": [ + "flour", + "flour plain", + "flour - plains", + "flour plain", + "plain flour", + "white flour" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.23, + "brands": [ + "365 by Whole Foods", + "Champion", + "Costco", + "Edmonds", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "flour_plain", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_flour_self_raising", + "name": "Flour - Self Raising", + "category_id": "pantry", + "aliases": [ + "flour", + "flour self raising", + "flour - self raisings", + "flour self raising", + "self raising flour" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.79, + "brands": [ + "Champion", + "Costco", + "Edmonds", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "flour_self_raising", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_sugar_white", + "name": "Sugar - White", + "category_id": "pantry", + "aliases": [ + "caster sugar", + "sugar", + "sugar white", + "sugar - whites", + "sugar white", + "white sugar" + ], + "default_unit": "kg", + "default_quantity": 1.5, + "price": 3.83, + "brands": [ + "Chelsea", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "sugar_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_sugar_brown", + "name": "Sugar - Brown", + "category_id": "pantry", + "aliases": [ + "brown sugar", + "soft brown", + "sugar", + "sugar brown", + "sugar - browns", + "sugar brown" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 4.79, + "brands": [ + "Chelsea", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "sugar_brown", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_oil_olive", + "name": "Olive Oil", + "category_id": "pantry", + "aliases": [ + "EVOO", + "extra virgin olive oil", + "olive oil", + "olive oils" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 11.84, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Olivado", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "oil_olive", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_oil_vegetable", + "name": "Vegetable Oil", + "category_id": "pantry", + "aliases": [ + "canola oil", + "cooking oil", + "vegetable oil", + "vegetable oils" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 7.57, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Olivani", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "oil_vegetable", + "tags": [ + "vegan" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tomatoes_canned", + "name": "Canned Tomatoes", + "category_id": "pantry", + "aliases": [ + "canned tomatoe", + "canned tomatoes", + "chopped tomatoes", + "tinned tomatoes" + ], + "default_unit": "can", + "default_quantity": 4, + "price": 1.81, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "tomatoes_canned", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_baked_beans", + "name": "Baked Beans", + "category_id": "pantry", + "aliases": [ + "baked bean", + "baked beans", + "beans in tomato sauce" + ], + "default_unit": "can", + "default_quantity": 1, + "price": 2.45, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Heinz", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "baked_beans", + "tags": [ + "gluten_free" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tuna", + "name": "Tuna in Oil", + "category_id": "pantry", + "aliases": [ + "canned tuna", + "tinned tuna", + "tuna in oil", + "tuna in oils" + ], + "default_unit": "can", + "default_quantity": 3, + "price": 3.08, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "John West", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "tuna", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_coconut_cream", + "name": "Coconut Cream", + "category_id": "pantry", + "aliases": [ + "coconut cream", + "coconut creams", + "coconut milk" + ], + "default_unit": "can", + "default_quantity": 2, + "price": 3.22, + "brands": [ + "Ayam", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "coconut_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_peanut_butter", + "name": "Peanut Butter", + "category_id": "pantry", + "aliases": [ + "crunchy peanut butter", + "peanut butter", + "peanut butters", + "smooth peanut butter" + ], + "default_unit": "g", + "default_quantity": 380, + "price": 5.83, + "brands": [ + "Costco", + "ETA", + "H-E-B", + "Kraft", + "Kroger", + "Pic's", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "peanut_butter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_jam_strawberry", + "name": "Jam - Strawberry", + "category_id": "pantry", + "aliases": [ + "jam", + "jam strawberry", + "jam - strawberrys", + "jam strawberry", + "strawberry jam" + ], + "default_unit": "g", + "default_quantity": 340, + "price": 5.26, + "brands": [ + "Anathoth", + "Barker's", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "jam_strawberry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_honey", + "name": "Honey", + "category_id": "pantry", + "aliases": [ + "clover honey", + "honey", + "honeys", + "manuka honey" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 8.72, + "brands": [ + "Airborne", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Manuka Health", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "honey", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_marmite", + "name": "Marmite", + "category_id": "pantry", + "aliases": [ + "marmite", + "marmites", + "yeast spread" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 6.37, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "marmite", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_vegemite", + "name": "Vegemite", + "category_id": "pantry", + "aliases": [ + "vegemite", + "vegemites", + "yeast spread" + ], + "default_unit": "g", + "default_quantity": 220, + "price": 5.51, + "brands": [ + "365 by Whole Foods", + "Bega", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "vegemite", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_soy_sauce", + "name": "Soy Sauce", + "category_id": "pantry", + "aliases": [ + "kikkoman", + "soy sauce", + "soy sauces" + ], + "default_unit": "mL", + "default_quantity": 250, + "price": 5.3, + "brands": [ + "365 by Whole Foods", + "Costco", + "Great Value", + "H-E-B", + "Kikkoman", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "soy_sauce", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [ + "soy" + ], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_tomato_sauce", + "name": "Tomato Sauce", + "category_id": "pantry", + "aliases": [ + "ketchup", + "tomato ketchup", + "tomato sauce", + "tomato sauces" + ], + "default_unit": "mL", + "default_quantity": 560, + "price": 4.61, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Heinz", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "tomato_sauce", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_bbq_sauce", + "name": "BBQ Sauce", + "category_id": "pantry", + "aliases": [ + "barbecue sauce", + "bbq sauce", + "bbq sauces" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 5.12, + "brands": [ + "365 by Whole Foods", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Masterfoods", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "bbq_sauce", + "tags": [], + "collections": [ + "bbq" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_mayonnaise", + "name": "Mayonnaise", + "category_id": "pantry", + "aliases": [ + "mayo", + "mayonnaise", + "mayonnaises" + ], + "default_unit": "mL", + "default_quantity": 440, + "price": 6.37, + "brands": [ + "Best Foods", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "mayonnaise", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_mustard", + "name": "Mustard", + "category_id": "pantry", + "aliases": [ + "american mustard", + "dijon mustard", + "mustard", + "mustards" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 4.22, + "brands": [ + "Costco", + "French's", + "Great Value", + "H-E-B", + "Kroger", + "Masterfoods", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "mustard", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_salt", + "name": "Salt", + "category_id": "pantry", + "aliases": [ + "cooking salt", + "salt", + "salts", + "table salt" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 1.98, + "brands": [ + "Cerebos", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "salt", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_pepper", + "name": "Black Pepper", + "category_id": "pantry", + "aliases": [ + "black pepper", + "black peppers", + "ground pepper" + ], + "default_unit": "g", + "default_quantity": 50, + "price": 4.13, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Masterfoods", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "pepper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_stock_cubes_chicken", + "name": "Stock Cubes - Chicken", + "category_id": "pantry", + "aliases": [ + "bouillon", + "chicken stock", + "stock cubes", + "stock cubes chicken", + "stock cubes - chickens", + "stock cubes chicken" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 2.82, + "brands": [ + "365 by Whole Foods", + "Continental", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Maggi", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "stock_cubes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_stock_cubes_beef", + "name": "Stock Cubes - Beef", + "category_id": "pantry", + "aliases": [ + "beef stock", + "stock cubes", + "stock cubes beef", + "stock cubes - beefs", + "stock cubes beef" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 3.0, + "brands": [ + "Continental", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Maggi", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "stock_cubes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 3 + }, + { + "id": "prod_coffee_instant", + "name": "Instant Coffee", + "category_id": "beverages", + "aliases": [ + "coffee", + "instant coffee", + "instant coffees", + "nescafe" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 13.25, + "brands": [ + "365 by Whole Foods", + "Costco", + "Gregg's", + "H-E-B", + "Kroger", + "Nescafe", + "Publix", + "Robert Harris", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "coffee_instant", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_coffee_ground", + "name": "Ground Coffee", + "category_id": "beverages", + "aliases": [ + "filter coffee", + "ground coffee", + "ground coffees" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 9.25, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "L'affare", + "Publix", + "Robert Harris", + "Safeway", + "Sam's Club", + "Target", + "Vittoria", + "Walmart", + "Whole Foods" + ], + "image_hint": "coffee_ground", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tea_black", + "name": "Tea - Black", + "category_id": "beverages", + "aliases": [ + "black tea", + "tea", + "tea black", + "tea - blacks", + "tea bags", + "tea black" + ], + "default_unit": "ea", + "default_quantity": 100, + "price": 6.63, + "brands": [ + "Bell", + "Costco", + "Dilmah", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Twinings", + "Walmart", + "Whole Foods" + ], + "image_hint": "tea_black", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tea_green", + "name": "Tea - Green", + "category_id": "beverages", + "aliases": [ + "green tea", + "tea", + "tea green", + "tea - greens", + "tea green" + ], + "default_unit": "ea", + "default_quantity": 40, + "price": 5.62, + "brands": [ + "Costco", + "Dilmah", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Twinings", + "Walmart", + "Whole Foods" + ], + "image_hint": "tea_green", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_juice_orange", + "name": "Orange Juice", + "category_id": "beverages", + "aliases": [ + "OJ", + "fresh orange juice", + "orange juice", + "orange juices" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 7.14, + "brands": [ + "365 by Whole Foods", + "Charlies", + "Costco", + "Great Value", + "H-E-B", + "Just Juice", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "juice_orange", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_juice_apple", + "name": "Apple Juice", + "category_id": "beverages", + "aliases": [ + "apple juice", + "apple juices", + "fresh apple juice" + ], + "default_unit": "L", + "default_quantity": 2, + "price": 7.43, + "brands": [ + "Charlies", + "Costco", + "H-E-B", + "Just Juice", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "juice_apple", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soft_drink_coke", + "name": "Coca Cola", + "category_id": "beverages", + "aliases": [ + "coca cola", + "coca colas", + "coke", + "cola" + ], + "default_unit": "L", + "default_quantity": 2.25, + "price": 4.95, + "brands": [ + "Coca-Cola", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "coke", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soft_drink_lemonade", + "name": "Lemonade", + "category_id": "beverages", + "aliases": [ + "7up", + "lemonade", + "lemonades", + "sprite" + ], + "default_unit": "L", + "default_quantity": 2.25, + "price": 4.87, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Schweppes", + "Sprite", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "lemonade", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_water_still", + "name": "Water - Still", + "category_id": "beverages", + "aliases": [ + "bottled water", + "spring water", + "water", + "water still", + "water - stills", + "water still" + ], + "default_unit": "L", + "default_quantity": 1.5, + "price": 2.26, + "brands": [ + "Costco", + "Evian", + "H-E-B", + "Kroger", + "Publix", + "Pump", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "water_still", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_water_sparkling", + "name": "Water - Sparkling", + "category_id": "beverages", + "aliases": [ + "soda water", + "sparkling water", + "water", + "water sparkling", + "water - sparklings", + "water sparkling" + ], + "default_unit": "L", + "default_quantity": 1.5, + "price": 2.7, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "San Pellegrino", + "Schweppes", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "water_sparkling", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_beer", + "name": "Beer", + "category_id": "beverages", + "aliases": [ + "ale", + "beer", + "beers", + "lager" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 24.99, + "brands": [ + "Costco", + "DB Export", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Speights", + "Steinlager", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "beer", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wine_red", + "name": "Wine - Red", + "category_id": "beverages", + "aliases": [ + "red wine", + "wine", + "wine red", + "wine - reds", + "wine red" + ], + "default_unit": "bottle", + "default_quantity": 1, + "price": 16.05, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "Kroger", + "Oyster Bay", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Villa Maria", + "Walmart", + "Whole Foods" + ], + "image_hint": "wine_red", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_wine_white", + "name": "Wine - White", + "category_id": "beverages", + "aliases": [ + "sauvignon blanc", + "white wine", + "wine", + "wine white", + "wine - whites", + "wine white" + ], + "default_unit": "bottle", + "default_quantity": 1, + "price": 16.77, + "brands": [ + "Cloudy Bay", + "Costco", + "H-E-B", + "Kroger", + "Oyster Bay", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Villa Maria", + "Walmart", + "Whole Foods" + ], + "image_hint": "wine_white", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_cornflakes", + "name": "Cornflakes", + "category_id": "snacks", + "aliases": [ + "cornflake", + "cornflakes", + "kelloggs cornflakes" + ], + "default_unit": "g", + "default_quantity": 500, + "price": 7.61, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Kelloggs", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "cereal_cornflakes", + "tags": [ + "gluten_free" + ], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_weet_bix", + "name": "Weet-Bix", + "category_id": "snacks", + "aliases": [ + "weet bix", + "weet-bix", + "weet-bixs", + "weetbix", + "wheat biscuits" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 7.28, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "cereal_weet_bix", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cereal_muesli", + "name": "Muesli", + "category_id": "snacks", + "aliases": [ + "muesli", + "mueslis", + "toasted muesli" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 9.48, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Hubbards", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "cereal_muesli", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_oats_rolled", + "name": "Rolled Oats", + "category_id": "snacks", + "aliases": [ + "oats", + "porridge oats", + "rolled oat", + "rolled oats" + ], + "default_unit": "kg", + "default_quantity": 1, + "price": 5.51, + "brands": [ + "Costco", + "H-E-B", + "Harraways", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "oats_rolled", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chips_salt", + "name": "Potato Chips - Salt", + "category_id": "snacks", + "aliases": [ + "crisps", + "potato chips", + "potato chips salt", + "potato chips - salts", + "potato chips salt", + "ready salted chips" + ], + "default_unit": "g", + "default_quantity": 150, + "price": 3.77, + "brands": [ + "Bluebird", + "Costco", + "Eta", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "chips_salt", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chips_chicken", + "name": "Potato Chips - Chicken", + "category_id": "snacks", + "aliases": [ + "chicken chips", + "potato chips", + "potato chips chicken", + "potato chips - chickens", + "potato chips chicken" + ], + "default_unit": "g", + "default_quantity": 150, + "price": 4.04, + "brands": [ + "Bluebird", + "Costco", + "Eta", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "chips_chicken", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_crackers", + "name": "Crackers", + "category_id": "snacks", + "aliases": [ + "cracker", + "crackers", + "savoy", + "water crackers" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 3.93, + "brands": [ + "Arnott's", + "Costco", + "Griffin's", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "crackers", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cookies_chocolate_chip", + "name": "Chocolate Chip Cookies", + "category_id": "snacks", + "aliases": [ + "choc chip biscuits", + "chocolate chip cookie", + "chocolate chip cookies", + "cookies" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.35, + "brands": [ + "Cookie Time", + "Costco", + "Great Value", + "Griffin's", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "cookies_chocolate_chip", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tim_tams", + "name": "Tim Tams", + "category_id": "snacks", + "aliases": [ + "chocolate biscuits", + "tim tam", + "tim tams" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.03, + "brands": [ + "Arnott's", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "tim_tams", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chocolate_whittakers", + "name": "Chocolate - Whittaker's", + "category_id": "snacks", + "aliases": [ + "chocolate", + "chocolate whittaker's", + "chocolate - whittaker'", + "chocolate bar", + "chocolate whittaker's", + "whittakers block" + ], + "default_unit": "g", + "default_quantity": 250, + "price": 5.51, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "chocolate_whittakers", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_chocolate_cadbury", + "name": "Chocolate - Cadbury", + "category_id": "snacks", + "aliases": [ + "cadbury block", + "chocolate", + "chocolate cadbury", + "chocolate - cadburys", + "chocolate cadbury" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 4.89, + "brands": [ + "365 by Whole Foods", + "Cadbury", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "chocolate_cadbury", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_muesli_bars", + "name": "Muesli Bars", + "category_id": "snacks", + "aliases": [ + "granola bars", + "muesli bar", + "muesli bars" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 6.31, + "brands": [ + "365 by Whole Foods", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Nice & Natural", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Uncle Tobys", + "Walmart", + "Whole Foods" + ], + "image_hint": "muesli_bars", + "tags": [], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_popcorn", + "name": "Popcorn", + "category_id": "snacks", + "aliases": [ + "microwave popcorn", + "popcorn", + "popcorns" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 4.75, + "brands": [ + "365 by Whole Foods", + "Costco", + "Eta", + "Great Value", + "H-E-B", + "Kroger", + "Proper", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "popcorn", + "tags": [ + "gluten_free" + ], + "collections": [ + "school_lunch" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_nuts_mixed", + "name": "Mixed Nuts", + "category_id": "snacks", + "aliases": [ + "mixed nut", + "mixed nuts", + "roasted nuts" + ], + "default_unit": "g", + "default_quantity": 200, + "price": 7.62, + "brands": [ + "Costco", + "Eta", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "nuts_mixed", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toilet_paper", + "name": "Toilet Paper", + "category_id": "household", + "aliases": [ + "TP", + "bathroom tissue", + "toilet paper", + "toilet papers" + ], + "default_unit": "roll", + "default_quantity": 12, + "price": 12.27, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Purex", + "Safeway", + "Sam's Club", + "Sorbent", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "toilet_paper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_paper_towels", + "name": "Paper Towels", + "category_id": "household", + "aliases": [ + "kitchen paper", + "paper towel", + "paper towels" + ], + "default_unit": "roll", + "default_quantity": 4, + "price": 8.98, + "brands": [ + "Costco", + "H-E-B", + "Handee", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Sorbent", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "paper_towels", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_tissues", + "name": "Tissues", + "category_id": "household", + "aliases": [ + "facial tissues", + "kleenex", + "tissue", + "tissues" + ], + "default_unit": "box", + "default_quantity": 4, + "price": 8.23, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "Kleenex", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Sorbent", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "tissues", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dishwashing_liquid", + "name": "Dishwashing Liquid", + "category_id": "household", + "aliases": [ + "dish soap", + "dishwash", + "dishwashing liquid", + "dishwashing liquids" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 4.74, + "brands": [ + "365 by Whole Foods", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Morning Fresh", + "Publix", + "Safeway", + "Sam's Club", + "Sunlight", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "dishwashing_liquid", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dishwasher_tablets", + "name": "Dishwasher Tablets", + "category_id": "household", + "aliases": [ + "dishwasher pods", + "dishwasher tablet", + "dishwasher tablets" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 14.12, + "brands": [ + "Costco", + "Earthwise", + "Finish", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "dishwasher_tablets", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_laundry_powder", + "name": "Laundry Powder", + "category_id": "household", + "aliases": [ + "laundry powder", + "laundry powders", + "washing powder" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 16.35, + "brands": [ + "365 by Whole Foods", + "Costco", + "Earthwise", + "H-E-B", + "Kroger", + "OMO", + "Persil", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "laundry_powder", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_laundry_liquid", + "name": "Laundry Liquid", + "category_id": "household", + "aliases": [ + "laundry liquid", + "laundry liquids", + "washing liquid" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 15.19, + "brands": [ + "Costco", + "Earthwise", + "H-E-B", + "Kroger", + "OMO", + "Persil", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "laundry_liquid", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_fabric_softener", + "name": "Fabric Softener", + "category_id": "household", + "aliases": [ + "comfort", + "downy", + "fabric softener", + "fabric softeners" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 10.44, + "brands": [ + "Comfort", + "Costco", + "Earthwise", + "Great Value", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "fabric_softener", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_spray_cleaner", + "name": "Spray Cleaner", + "category_id": "household", + "aliases": [ + "multi-purpose cleaner", + "spray cleaner", + "spray cleaners", + "spray n wipe" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 7.53, + "brands": [ + "Costco", + "H-E-B", + "Jif", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Spray n Wipe", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "spray_cleaner", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bleach", + "name": "Bleach", + "category_id": "household", + "aliases": [ + "bleach", + "bleachs", + "janola" + ], + "default_unit": "L", + "default_quantity": 1, + "price": 6.3, + "brands": [ + "Costco", + "Domestos", + "H-E-B", + "Janola", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "bleach", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bin_bags", + "name": "Bin Bags", + "category_id": "household", + "aliases": [ + "bin bag", + "bin bags", + "garbage bags", + "rubbish bags" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 8.69, + "brands": [ + "Costco", + "Ecostore", + "Glad", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "bin_bags", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cling_film", + "name": "Cling Film", + "category_id": "household", + "aliases": [ + "cling film", + "cling films", + "glad wrap", + "plastic wrap" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 5.46, + "brands": [ + "Costco", + "Glad", + "Great Value", + "H-E-B", + "Kroger", + "Multix", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "cling_film", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_aluminium_foil", + "name": "Aluminium Foil", + "category_id": "household", + "aliases": [ + "alfoil", + "aluminium foil", + "aluminium foils", + "tin foil" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 7.06, + "brands": [ + "Alfoil", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Multix", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "aluminium_foil", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baking_paper", + "name": "Baking Paper", + "category_id": "household", + "aliases": [ + "baking paper", + "baking papers", + "parchment paper" + ], + "default_unit": "roll", + "default_quantity": 1, + "price": 4.87, + "brands": [ + "365 by Whole Foods", + "Alfoil", + "Costco", + "Great Value", + "H-E-B", + "Kroger", + "Multix", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "baking_paper", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_shampoo", + "name": "Shampoo", + "category_id": "health", + "aliases": [ + "hair shampoo", + "shampoo", + "shampoos" + ], + "default_unit": "mL", + "default_quantity": 400, + "price": 9.01, + "brands": [ + "Costco", + "Garnier", + "Great Value", + "H-E-B", + "Head & Shoulders", + "Kroger", + "Pantene", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "shampoo", + "tags": [], + "collections": [ + "christmas" + ], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_conditioner", + "name": "Conditioner", + "category_id": "health", + "aliases": [ + "conditioner", + "conditioners", + "hair conditioner" + ], + "default_unit": "mL", + "default_quantity": 400, + "price": 8.44, + "brands": [ + "365 by Whole Foods", + "Costco", + "Garnier", + "H-E-B", + "Head & Shoulders", + "Kroger", + "Pantene", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "conditioner", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_body_wash", + "name": "Body Wash", + "category_id": "health", + "aliases": [ + "body wash", + "body washs", + "shower gel" + ], + "default_unit": "mL", + "default_quantity": 500, + "price": 7.32, + "brands": [ + "365 by Whole Foods", + "Costco", + "Dove", + "H-E-B", + "Kroger", + "Nivea", + "Palmolive", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "body_wash", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_soap_bar", + "name": "Bar Soap", + "category_id": "health", + "aliases": [ + "bar soap", + "bar soaps", + "bath soap", + "hand soap" + ], + "default_unit": "bar", + "default_quantity": 4, + "price": 5.09, + "brands": [ + "365 by Whole Foods", + "Costco", + "Dove", + "Great Value", + "H-E-B", + "Kroger", + "Palmolive", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "soap_bar", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toothpaste", + "name": "Toothpaste", + "category_id": "health", + "aliases": [ + "colgate", + "toothpaste", + "toothpastes" + ], + "default_unit": "g", + "default_quantity": 110, + "price": 5.85, + "brands": [ + "365 by Whole Foods", + "Colgate", + "Costco", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Sensodyne", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "toothpaste", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_toothbrush", + "name": "Toothbrush", + "category_id": "health", + "aliases": [ + "tooth brush", + "toothbrush", + "toothbrushs" + ], + "default_unit": "ea", + "default_quantity": 2, + "price": 7.38, + "brands": [ + "365 by Whole Foods", + "Colgate", + "Costco", + "H-E-B", + "Kroger", + "Oral-B", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "toothbrush", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_deodorant", + "name": "Deodorant", + "category_id": "health", + "aliases": [ + "antiperspirant", + "deodorant", + "deodorants" + ], + "default_unit": "g", + "default_quantity": 50, + "price": 7.37, + "brands": [ + "365 by Whole Foods", + "Costco", + "Dove", + "H-E-B", + "Kroger", + "Lynx", + "Publix", + "Rexona", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "deodorant", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_razor_blades", + "name": "Razor Blades", + "category_id": "health", + "aliases": [ + "gillette", + "razor blade", + "razor blades", + "shaving blades" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 21.96, + "brands": [ + "365 by Whole Foods", + "Costco", + "Gillette", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Schick", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "razor_blades", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_shaving_cream", + "name": "Shaving Cream", + "category_id": "health", + "aliases": [ + "shave gel", + "shaving cream", + "shaving creams" + ], + "default_unit": "mL", + "default_quantity": 200, + "price": 6.67, + "brands": [ + "365 by Whole Foods", + "Costco", + "Gillette", + "H-E-B", + "Kroger", + "Nivea", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "shaving_cream", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_sunscreen", + "name": "Sunscreen SPF50", + "category_id": "health", + "aliases": [ + "sun cream", + "sunblock", + "sunscreen spf50", + "sunscreen spf50s" + ], + "default_unit": "mL", + "default_quantity": 200, + "price": 14.07, + "brands": [ + "365 by Whole Foods", + "Cancer Society", + "Costco", + "H-E-B", + "Kroger", + "Neutrogena", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "sunscreen", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_paracetamol", + "name": "Paracetamol", + "category_id": "health", + "aliases": [ + "pain relief", + "panadol", + "paracetamol", + "paracetamols" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 9.21, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Panadol", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "paracetamol", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_ibuprofen", + "name": "Ibuprofen", + "category_id": "health", + "aliases": [ + "ibuprofen", + "ibuprofens", + "nurofen", + "pain relief" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 10.61, + "brands": [ + "Costco", + "H-E-B", + "Kroger", + "Nurofen", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "ibuprofen", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_bandaids", + "name": "Band-Aids", + "category_id": "health", + "aliases": [ + "band aids", + "band-aid", + "band-aids", + "bandages", + "plasters" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.46, + "brands": [ + "365 by Whole Foods", + "Band-Aid", + "Costco", + "Elastoplast", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "bandaids", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_vitamins_c", + "name": "Vitamin C", + "category_id": "health", + "aliases": [ + "vitamin c", + "vitamin c tablets", + "vitamin cs" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 14.21, + "brands": [ + "Blackmores", + "Costco", + "Great Value", + "H-E-B", + "Healtheries", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "vitamins_c", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_nappies", + "name": "Nappies", + "category_id": "baby", + "aliases": [ + "baby nappies", + "diapers", + "nappie", + "nappies" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 30.11, + "brands": [ + "Costco", + "Great Value", + "H-E-B", + "Huggies", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "nappies", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baby_wipes", + "name": "Baby Wipes", + "category_id": "baby", + "aliases": [ + "baby wipe", + "baby wipes", + "wet wipes" + ], + "default_unit": "pack", + "default_quantity": 1, + "price": 5.91, + "brands": [ + "365 by Whole Foods", + "Costco", + "H-E-B", + "Huggies", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "baby_wipes", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_baby_formula", + "name": "Baby Formula", + "category_id": "baby", + "aliases": [ + "baby formula", + "baby formulas", + "infant formula" + ], + "default_unit": "g", + "default_quantity": 900, + "price": 30.92, + "brands": [ + "Aptamil", + "Costco", + "Great Value", + "H-E-B", + "Karicare", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whole Foods" + ], + "image_hint": "baby_formula", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dog_food_dry", + "name": "Dog Food - Dry", + "category_id": "pet", + "aliases": [ + "dog biscuits", + "dog food", + "dog food dry", + "dog food - drys", + "dog food dry", + "dog kibble" + ], + "default_unit": "kg", + "default_quantity": 3, + "price": 23.73, + "brands": [ + "365 by Whole Foods", + "Costco", + "Eukanuba", + "H-E-B", + "Kroger", + "Pedigree", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "dog_food_dry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_dog_food_wet", + "name": "Dog Food - Wet", + "category_id": "pet", + "aliases": [ + "canned dog food", + "dog food", + "dog food wet", + "dog food - wets", + "dog food wet" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 21.33, + "brands": [ + "Champ", + "Costco", + "H-E-B", + "Kroger", + "Pedigree", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "dog_food_wet", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_food_dry", + "name": "Cat Food - Dry", + "category_id": "pet", + "aliases": [ + "cat biscuits", + "cat food", + "cat food dry", + "cat food - drys", + "cat food dry" + ], + "default_unit": "kg", + "default_quantity": 2, + "price": 20.55, + "brands": [ + "Costco", + "Fancy Feast", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whiskas", + "Whole Foods" + ], + "image_hint": "cat_food_dry", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_food_wet", + "name": "Cat Food - Wet", + "category_id": "pet", + "aliases": [ + "canned cat food", + "cat food", + "cat food wet", + "cat food - wets", + "cat food wet" + ], + "default_unit": "can", + "default_quantity": 12, + "price": 14.91, + "brands": [ + "365 by Whole Foods", + "Costco", + "Fancy Feast", + "H-E-B", + "Kroger", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Walmart", + "Whiskas", + "Whole Foods" + ], + "image_hint": "cat_food_wet", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + }, + { + "id": "prod_cat_litter", + "name": "Cat Litter", + "category_id": "pet", + "aliases": [ + "cat litter", + "cat litters", + "kitty litter" + ], + "default_unit": "kg", + "default_quantity": 5, + "price": 12.13, + "brands": [ + "Catlove", + "Costco", + "H-E-B", + "Kroger", + "Paws", + "Publix", + "Safeway", + "Sam's Club", + "Target", + "Target Good & Gather", + "Walmart", + "Whole Foods" + ], + "image_hint": "cat_litter", + "tags": [], + "collections": [], + "taxonomy": { + "dietary": [], + "nutrition": [], + "lifestyle": [], + "storage": "pantry" + }, + "allergens": [], + "substitution_group": null, + "priority_level": 1 + } + ], + "country": "United States" +} \ No newline at end of file diff --git a/custom_components/shopping_list_manager/manager.py b/custom_components/shopping_list_manager/manager.py deleted file mode 100644 index 2dfd07f..0000000 --- a/custom_components/shopping_list_manager/manager.py +++ /dev/null @@ -1,406 +0,0 @@ -"""Core Shopping List Manager with invariant enforcement.""" -import asyncio -import logging -from typing import Dict, Optional, List - -from homeassistant.core import HomeAssistant -from homeassistant.helpers import storage -from homeassistant.helpers.storage import Store - - -from .const import ( - DOMAIN, - EVENT_SHOPPING_LIST_UPDATED, - STORAGE_KEY_ACTIVE, - STORAGE_KEY_PRODUCTS, - STORAGE_VERSION, -) -from .models import Product, ActiveItem, InvariantError, validate_invariant - -_LOGGER = logging.getLogger(__name__) - - -class ShoppingListManager: - """ - Manages multiple independent shopping lists. - - Each list_id gets its own pair of storage files: - - shopping_list_manager.{list_id}.products - - shopping_list_manager.{list_id}.active_list - - The default "groceries" list uses the original flat keys for backward compat: - - shopping_list_manager.products → groceries products - - shopping_list_manager.active_list → groceries active - - Architecture principles: - 1. Products and active_list are separate concerns per list - 2. Products are authoritative, persistent data - 3. Active list is ephemeral state - 4. Invariant (active ⊆ products) enforced on every mutation - 5. Lock ensures atomic operations per list - """ - - def __init__(self, hass: HomeAssistant): - """Initialize the manager.""" - self.hass = hass - # Per-list in-memory caches: list_id -> {key: Product} - self._products: Dict[str, Dict[str, Product]] = {} - self._active_list: Dict[str, Dict[str, ActiveItem]] = {} - # Per-list locks - self._locks: Dict[str, asyncio.Lock] = {} - # Per-list storage Store instances (created lazily, except groceries) - self._store_products: Dict[str, storage.Store] = {} - self._store_active: Dict[str, storage.Store] = {} - - # Pre-create stores for the default "groceries" list using the original flat keys - # for backward compatibility — existing data just works - self._store_products["groceries"] = storage.Store( - hass, STORAGE_VERSION, STORAGE_KEY_PRODUCTS # "shopping_list_manager.products" - ) - self._store_active["groceries"] = storage.Store( - hass, STORAGE_VERSION, STORAGE_KEY_ACTIVE # "shopping_list_manager.active_list" - ) - # --- Catalogue + list metadata (NEW, additive) --- - self._store_catalogues = Store( - hass, - STORAGE_VERSION, - f"{DOMAIN}.catalogues", - ) - self._catalogues: Dict[str, dict] = {} - - self._store_lists = Store( - hass, - STORAGE_VERSION, - f"{DOMAIN}.lists", - ) - self._lists: Dict[str, dict] = {} - - def _lock_for(self, list_id: str) -> asyncio.Lock: - """Get or create lock for a list.""" - if list_id not in self._locks: - self._locks[list_id] = asyncio.Lock() - return self._locks[list_id] - - def _store_products_for(self, list_id: str) -> storage.Store: - """Get or create products Store for a list.""" - if list_id not in self._store_products: - catalogue_id = self._lists.get(list_id, {}).get("catalogue", list_id) - catalogue = self._catalogues.get(catalogue_id) - - key = ( - catalogue["products_store"] - if catalogue - else f"{DOMAIN}.{list_id}.products" - ) - - self._store_products[list_id] = storage.Store( - self.hass, STORAGE_VERSION, key - ) - return self._store_products[list_id] - - - def _store_active_for(self, list_id: str) -> storage.Store: - """Get or create active Store for a list.""" - if list_id not in self._store_active: - key = f"{DOMAIN}.{list_id}.active_list" - self._store_active[list_id] = storage.Store(self.hass, STORAGE_VERSION, key) - return self._store_active[list_id] - - async def _ensure_loaded(self, list_id: str) -> None: - """Lazily load a list from storage if not yet in memory.""" - await self._ensure_catalogues_loaded() - await self._ensure_lists_loaded() - - # Register list if it does not exist yet - if list_id not in self._lists: - self._lists[list_id] = { - "catalogue": list_id - } - await self._store_lists.async_save(self._lists) - - - if list_id in self._products: - return # already loaded - - products_data = await self._store_products_for(list_id).async_load() - self._products[list_id] = { - key: Product.from_dict(data) for key, data in (products_data or {}).items() - } - - active_data = await self._store_active_for(list_id).async_load() - self._active_list[list_id] = { - key: ActiveItem.from_dict(data) for key, data in (active_data or {}).items() - } - - # Repair any orphaned active items - await self._async_repair_invariant(list_id) - - _LOGGER.info( - "Loaded list '%s': %d products, %d active", - list_id, len(self._products[list_id]), len(self._active_list[list_id]) - ) - - async def _ensure_catalogues_loaded(self) -> None: - data = await self._store_catalogues.async_load() - if isinstance(data, dict): - self._catalogues = data - return - - # Bootstrap from existing behavior (no changes) - self._catalogues = { - "groceries": { - "name": "Groceries", - "icon": "🛒", - "products_store": f"{DOMAIN}.products", - } - } - - await self._store_catalogues.async_save(self._catalogues) - - async def _ensure_lists_loaded(self) -> None: - data = await self._store_lists.async_load() - if isinstance(data, dict): - self._lists = data - return - - # Default: list_id == catalogue_id (current behavior) - self._lists = { - "groceries": { - "catalogue": "groceries", - } - } - - await self._store_lists.async_save(self._lists) - - async def async_load(self) -> None: - """Pre-load the default groceries list for backward compat.""" - async with self._lock_for("groceries"): - await self._ensure_loaded("groceries") - - async def _async_repair_invariant(self, list_id: str) -> None: - """Remove active items whose product no longer exists.""" - orphaned = [k for k in self._active_list[list_id] if k not in self._products[list_id]] - if orphaned: - _LOGGER.warning( - "List '%s': removing %d orphaned active items: %s", - list_id, len(orphaned), orphaned - ) - for k in orphaned: - del self._active_list[list_id][k] - await self._async_save_active(list_id) - - async def _async_save_products(self, list_id: str) -> None: - """Persist products to storage.""" - data = {key: p.to_dict() for key, p in self._products[list_id].items()} - await self._store_products_for(list_id).async_save(data) - - async def _async_save_active(self, list_id: str) -> None: - """Persist active list to storage.""" - data = {key: a.to_dict() for key, a in self._active_list[list_id].items()} - await self._store_active_for(list_id).async_save(data) - - def _fire_update_event(self) -> None: - """Fire event to notify listeners of changes.""" - self.hass.bus.async_fire(EVENT_SHOPPING_LIST_UPDATED) - - # ======================================================================== - # PUBLIC API - All operations enforce invariants - # ======================================================================== - - import time - - async def async_create_list( - self, - list_id: str, - catalogue: str, - owner: str, - visibility: str = "shared", - ): - await self._ensure_catalogues_loaded() - await self._ensure_lists_loaded() - - if list_id in self._lists: - raise ValueError(f"List '{list_id}' already exists") - - if catalogue not in self._catalogues: - raise ValueError(f"Catalogue '{catalogue}' does not exist") - - self._lists[list_id] = { - "catalogue": catalogue, - "owner": owner, - "visibility": visibility, - "created_at": time.time(), - "updated_at": time.time(), - } - - await self._store_lists.async_save(self._lists) - - async def async_add_product( - self, - list_id: str, - key: str, - name: str, - category: str = "other", - unit: str = "pcs", - image: str = "" - ) -> Product: - """ - Add or update a product in a list's catalog. - - This operation: - - Creates/updates product metadata - - Does NOT modify quantities - - Is idempotent - - Persists to storage - - Args: - list_id: List identifier - key: Unique product identifier - name: Display name - category: Product category - unit: Unit of measurement - image: Image URL - - Returns: - The created/updated Product - """ - async with self._lock_for(list_id): - await self._ensure_loaded(list_id) - - product = Product( - key=key, - name=name, - category=category, - unit=unit, - image=image - ) - - self._products[list_id][key] = product - await self._async_save_products(list_id) - - _LOGGER.debug("List '%s': added/updated product %s (%s)", list_id, name, key) - self._fire_update_event() - - return product - - async def async_set_qty(self, list_id: str, key: str, qty: int) -> None: - """ - Set quantity for a product on the shopping list. - - This operation: - - REQUIRES product to exist (enforces invariant) - - qty > 0: adds/updates active_list - - qty == 0: removes from active_list - - Persists state - - Fires update event - - Args: - list_id: List identifier - key: Product key (must exist in catalog) - qty: New quantity (0 to remove, >0 to add/update) - - Raises: - InvariantError: If product doesn't exist - ValueError: If qty is negative - """ - if qty < 0: - raise ValueError(f"Quantity cannot be negative: {qty}") - - async with self._lock_for(list_id): - await self._ensure_loaded(list_id) - - # INVARIANT ENFORCEMENT: Product must exist - if key not in self._products[list_id]: - raise InvariantError( - f"Cannot set quantity for unknown product '{key}' in list '{list_id}'. " - f"Product must be created first with add_product." - ) - - # Update or remove from active list - if qty > 0: - self._active_list[list_id][key] = ActiveItem(qty=qty) - _LOGGER.debug("List '%s': set qty for %s: %d", list_id, key, qty) - else: - # qty == 0: remove from list - if key in self._active_list[list_id]: - del self._active_list[list_id][key] - _LOGGER.debug("List '%s': removed %s from active list", list_id, key) - - await self._async_save_active(list_id) - self._fire_update_event() - - async def async_delete_product(self, list_id: str, key: str) -> None: - """ - Delete a product from the catalog. - - This operation: - - Removes product from catalog - - Removes from active list (maintains invariant) - - Persists both changes - - Args: - list_id: List identifier - key: Product key to delete - """ - async with self._lock_for(list_id): - await self._ensure_loaded(list_id) - - if key not in self._products[list_id]: - _LOGGER.warning("List '%s': attempted to delete non-existent product: %s", list_id, key) - return - - # Remove from catalog - del self._products[list_id][key] - - # Remove from active list (maintain invariant) - if key in self._active_list[list_id]: - del self._active_list[list_id][key] - - await self._async_save_products(list_id) - await self._async_save_active(list_id) - - _LOGGER.debug("List '%s': deleted product: %s", list_id, key) - self._fire_update_event() - - def get_catalogues(self) -> Dict[str, dict]: - return self._catalogues - - async def async_get_lists(self) -> Dict[str, dict]: - await self._ensure_catalogues_loaded() - await self._ensure_lists_loaded() - return self._lists - - - async def async_get_products(self, list_id: str) -> Dict[str, dict]: - """ - Get all products in a list's catalog. - - Args: - list_id: List identifier - - Returns: - Dictionary of product key -> product data - """ - async with self._lock_for(list_id): - await self._ensure_loaded(list_id) - return {key: product.to_dict() for key, product in self._products[list_id].items()} - - async def async_get_active(self, list_id: str) -> Dict[str, dict]: - """ - Get active shopping list (quantities only). - - Args: - list_id: List identifier - - Returns: - Dictionary of product key -> active item data (qty only) - """ - async with self._lock_for(list_id): - await self._ensure_loaded(list_id) - return {key: item.to_dict() for key, item in self._active_list[list_id].items()} - - # NOTE: The following methods were removed as they're not used by the websocket API - # and would need updating to support per-list structure: - # - async_get_full_state() - # - get_product() - # - get_active_qty() diff --git a/custom_components/shopping_list_manager/manifest.json b/custom_components/shopping_list_manager/manifest.json index 0e2d5c9..f78d1a4 100644 --- a/custom_components/shopping_list_manager/manifest.json +++ b/custom_components/shopping_list_manager/manifest.json @@ -1,12 +1,17 @@ { "domain": "shopping_list_manager", "name": "Shopping List Manager", - "version": "1.5.0", + "version": "2.0.0", "documentation": "https://github.com/thekiwismarthome/shopping-list-manager", "issue_tracker": "https://github.com/thekiwismarthome/shopping-list-manager/issues", - "requirements": [], + "requirements": [ + "Pillow>=10.0.0", + "aiofiles>=23.0.0", + "rapidfuzz>=3.0.0" + ], "dependencies": [], "codeowners": ["@thekiwismarthome"], "config_flow": true, - "iot_class": "local_push" + "iot_class": "local_push", + "integration_type": "service" } diff --git a/custom_components/shopping_list_manager/models.py b/custom_components/shopping_list_manager/models.py index d7ceef5..013a823 100644 --- a/custom_components/shopping_list_manager/models.py +++ b/custom_components/shopping_list_manager/models.py @@ -1,104 +1,113 @@ """Data models for Shopping List Manager.""" -from dataclasses import dataclass, asdict -from typing import Dict +from dataclasses import dataclass, field, asdict +from datetime import datetime +from typing import Optional, List, Dict, Any +import uuid + + +def generate_id() -> str: + """Generate a unique ID.""" + return str(uuid.uuid4()) + + +def current_timestamp() -> str: + """Get current ISO timestamp.""" + return datetime.utcnow().isoformat() + "Z" + + +@dataclass +class Category: + """Category model.""" + id: str + name: str + icon: str + color: str + sort_order: int + system: bool = True + + def to_dict(self) -> Dict[str, Any]: + """Convert to dictionary.""" + return asdict(self) @dataclass class Product: - """ - Product catalog entry - authoritative product definition. - - Products exist independently of the shopping list. - They define WHAT can be shopped, not HOW MUCH is needed. - """ - key: str + """Product model.""" + id: str name: str - category: str = "other" - unit: str = "pcs" - image: str = "" + category_id: str + aliases: List[str] = field(default_factory=list) + default_unit: str = "units" + default_quantity: float = 1 + price: Optional[float] = None + currency: Optional[str] = None + price_per_unit: Optional[float] = None + price_updated: Optional[str] = None + image_url: Optional[str] = None + image_source: Optional[str] = None + barcode: Optional[str] = None + brands: List[str] = field(default_factory=list) + nutrition: Optional[Dict[str, Any]] = None + user_frequency: int = 0 + last_used: Optional[str] = None + custom: bool = False + source: str = "user" + tags: List[str] = field(default_factory=list) + collections: List[str] = field(default_factory=list) + taxonomy: Dict[str, Any] = field(default_factory=dict) + allergens: List[str] = field(default_factory=list) + substitution_group: str = "" + priority_level: int = 0 + image_hint: str = "" - def to_dict(self) -> dict: - """Convert to dictionary for storage/transmission.""" - return { - "key": self.key, - "name": self.name, - "category": self.category, - "unit": self.unit, - "image": self.image - } - - @staticmethod - def from_dict(data: dict) -> 'Product': - """Create Product from dictionary.""" - return Product( - key=data["key"], - name=data["name"], - category=data.get("category", "other"), - unit=data.get("unit", "pcs"), - image=data.get("image", "") - ) - - def __post_init__(self): - """Validate product data.""" - if not self.key: - raise ValueError("Product key cannot be empty") - if not self.name: - raise ValueError("Product name cannot be empty") + def to_dict(self) -> Dict[str, Any]: + """Convert to dictionary.""" + return asdict(self) @dataclass -class ActiveItem: - """ - Shopping list state - quantity only. +class Item: + """Shopping list item model.""" + id: str + list_id: str + name: str + category_id: str + product_id: Optional[str] = None + quantity: float = 1 + unit: str = "units" + note: Optional[str] = None + checked: bool = False + checked_at: Optional[str] = None + created_at: str = field(default_factory=current_timestamp) + updated_at: str = field(default_factory=current_timestamp) + image_url: Optional[str] = None + order_index: int = 0 + price: Optional[float] = None + estimated_total: Optional[float] = None + barcode: Optional[str] = None - Contains NO product metadata, only references products by key. - qty > 0 means "on the list" - qty == 0 means "not on the list" (should be removed) - """ - qty: int + def to_dict(self) -> Dict[str, Any]: + """Convert to dictionary.""" + return asdict(self) - def to_dict(self) -> dict: - """Convert to dictionary for storage/transmission.""" - return {"qty": self.qty} - - @staticmethod - def from_dict(data: dict) -> 'ActiveItem': - """Create ActiveItem from dictionary.""" - return ActiveItem(qty=data["qty"]) - - def __post_init__(self): - """Validate quantity.""" - if self.qty < 0: - raise ValueError("Quantity cannot be negative") + def calculate_total(self) -> None: + """Calculate estimated total from quantity and price.""" + if self.price is not None: + self.estimated_total = self.quantity * self.price -class InvariantError(Exception): - """ - Raised when the core data model invariant is violated. +@dataclass +class ShoppingList: + """Shopping list model.""" + id: str + name: str + icon: str = "mdi:cart" + created_at: str = field(default_factory=current_timestamp) + updated_at: str = field(default_factory=current_timestamp) + item_order: List[str] = field(default_factory=list) + category_order: List[str] = field(default_factory=list) + active: bool = False - Invariant: Every key in active_list MUST exist in products. - - If this exception is raised, the system is in an inconsistent state - and must be repaired before continuing. - """ - pass - - -def validate_invariant(products: Dict[str, Product], - active_list: Dict[str, ActiveItem]) -> None: - """ - Validate the core data model invariant. - - Args: - products: Product catalog dictionary - active_list: Active shopping list dictionary - - Raises: - InvariantError: If any key in active_list doesn't exist in products - """ - for key in active_list: - if key not in products: - raise InvariantError( - f"Invariant violated: active_list contains unknown product key '{key}'. " - f"This product must be added to the catalog first." - ) + def to_dict(self) -> Dict[str, Any]: + """Convert to dictionary.""" + return asdict(self) diff --git a/custom_components/shopping_list_manager/storage.py b/custom_components/shopping_list_manager/storage.py new file mode 100644 index 0000000..d55734a --- /dev/null +++ b/custom_components/shopping_list_manager/storage.py @@ -0,0 +1,488 @@ +"""Storage management for Shopping List Manager.""" +import logging +from typing import Dict, List, Optional, Any +from .utils.search import ProductSearch +from homeassistant.core import HomeAssistant +from homeassistant.helpers.storage import Store + +from .const import ( + STORAGE_VERSION, + STORAGE_KEY_LISTS, + STORAGE_KEY_ITEMS, + STORAGE_KEY_PRODUCTS, + STORAGE_KEY_CATEGORIES, +) +from .data.catalog_loader import load_product_catalog +from .models import ShoppingList, Item, Product, Category, generate_id +from .data.category_loader import load_categories + +_LOGGER = logging.getLogger(__name__) + + +class ShoppingListStorage: + """Handle storage for shopping lists.""" + + def __init__(self, hass: HomeAssistant, component_path: str, country: str = "NZ") -> None: + """Initialize storage. + + Args: + hass: Home Assistant instance + component_path: Path to the component directory + country: Country code (NZ, AU, US, GB, CA, etc.) + """ + self.hass = hass + self._component_path = component_path + self._country = country # Store country + self._store_lists = Store(hass, STORAGE_VERSION, STORAGE_KEY_LISTS) + self._store_items = Store(hass, STORAGE_VERSION, STORAGE_KEY_ITEMS) + self._store_products = Store(hass, STORAGE_VERSION, STORAGE_KEY_PRODUCTS) + self._store_categories = Store(hass, STORAGE_VERSION, STORAGE_KEY_CATEGORIES) + + self._lists: Dict[str, ShoppingList] = {} + self._items: Dict[str, List[Item]] = {} + self._products: Dict[str, Product] = {} + self._categories: List[Category] = [] + self._search_engine: Optional[ProductSearch] = None + + async def async_load(self) -> None: + """Load data from storage.""" + # Load lists + lists_data = await self._store_lists.async_load() + if lists_data: + self._lists = { + list_id: ShoppingList(**list_data) + for list_id, list_data in lists_data.items() + } + _LOGGER.debug("Loaded %d lists", len(self._lists)) + else: + # Create default list if none exist + default_list = ShoppingList( + id=generate_id(), + name="Shopping List", + icon="mdi:cart", + active=True + ) + self._lists[default_list.id] = default_list + await self._save_lists() + _LOGGER.info("Created default shopping list") + + # Load items + items_data = await self._store_items.async_load() + if items_data: + self._items = { + list_id: [Item(**item_data) for item_data in items] + for list_id, items in items_data.items() + } + _LOGGER.debug("Loaded items for %d lists", len(self._items)) + + # Load products + products_data = await self._store_products.async_load() + if products_data: + self._products = { + product_id: Product(**product_data) + for product_id, product_data in products_data.items() + } + _LOGGER.debug("Loaded %d products", len(self._products)) + + # Load categories + categories_data = await self._store_categories.async_load() + if categories_data: + self._categories = [Category(**cat_data) for cat_data in categories_data] + _LOGGER.debug("Loaded %d categories", len(self._categories)) + else: + # Initialize with default categories from JSON file + default_categories = await load_categories(self._component_path, self._country) # Use self._country + self._categories = [Category(**cat) for cat in default_categories] + await self._save_categories() + _LOGGER.info( + "Initialized %d default categories for country: %s", + len(self._categories), + self._country # Use self._country + ) + + # Load product catalog if products are empty + if not self._products: + _LOGGER.info("Loading product catalog for country: %s", self._country) + catalog_products = await load_product_catalog(self._component_path, self._country) # Use self._country + + if catalog_products: + _LOGGER.info("Importing %d products from catalog", len(catalog_products)) + # ... rest of import code ... + for prod_data in catalog_products: + try: + # Create Product from catalog data + product = Product( + id=prod_data.get("id", generate_id()), + name=prod_data["name"], + category_id=prod_data.get("category_id", "other"), + aliases=prod_data.get("aliases", []), + default_unit=prod_data.get("default_unit", "units"), + default_quantity=prod_data.get("default_quantity", 1), + price=prod_data.get("price") or prod_data.get("typical_price"), + currency=self.hass.config.currency, + barcode=prod_data.get("barcode"), + brands=prod_data.get("brands", []), + image_url=prod_data.get("image_url", ""), + custom=False, + source="catalog", + tags=prod_data.get("tags", []), + collections=prod_data.get("collections", []), + taxonomy=prod_data.get("taxonomy", {}), + allergens=prod_data.get("allergens", []), + substitution_group=prod_data.get("substitution_group", ""), + priority_level=prod_data.get("priority_level", 0), + image_hint=prod_data.get("image_hint", "") + ) + self._products[product.id] = product + except Exception as err: + _LOGGER.error("Failed to import product %s: %s", prod_data.get("name"), err) + continue + + await self._save_products() + _LOGGER.info("Successfully imported %d products from catalog", len(self._products)) + +# Initialize search engine after products are loaded + if self._products: + products_dict = {pid: p.to_dict() for pid, p in self._products.items()} + self._search_engine = ProductSearch(products_dict) + _LOGGER.debug("Initialized product search engine with %d products", len(self._products)) + else: + self._search_engine = None + _LOGGER.warning("No products loaded, search engine not initialized") + + # Lists methods + async def _save_lists(self) -> None: + """Save lists to storage.""" + data = {list_id: lst.to_dict() for list_id, lst in self._lists.items()} + await self._store_lists.async_save(data) + + def get_lists(self) -> List[ShoppingList]: + """Get all lists.""" + return list(self._lists.values()) + + def get_list(self, list_id: str) -> Optional[ShoppingList]: + """Get a specific list.""" + return self._lists.get(list_id) + + def get_active_list(self) -> Optional[ShoppingList]: + """Get the active list.""" + for lst in self._lists.values(): + if lst.active: + return lst + return None + + async def create_list(self, name: str, icon: str = "mdi:cart") -> ShoppingList: + """Create a new list.""" + new_list = ShoppingList( + id=generate_id(), + name=name, + icon=icon, + category_order=[cat.id for cat in self._categories] + ) + self._lists[new_list.id] = new_list + self._items[new_list.id] = [] + await self._save_lists() + _LOGGER.info("Created new list: %s", name) + return new_list + + async def update_list(self, list_id: str, **kwargs) -> Optional[ShoppingList]: + """Update a list.""" + if list_id not in self._lists: + return None + + lst = self._lists[list_id] + for key, value in kwargs.items(): + if hasattr(lst, key): + setattr(lst, key, value) + + from .models import current_timestamp + lst.updated_at = current_timestamp() + + await self._save_lists() + _LOGGER.debug("Updated list: %s", list_id) + return lst + + async def delete_list(self, list_id: str) -> bool: + """Delete a list.""" + if list_id not in self._lists: + return False + + del self._lists[list_id] + if list_id in self._items: + del self._items[list_id] + + await self._save_lists() + await self._save_items() + _LOGGER.info("Deleted list: %s", list_id) + return True + + async def set_active_list(self, list_id: str) -> bool: + """Set the active list.""" + if list_id not in self._lists: + return False + + # Deactivate all lists + for lst in self._lists.values(): + lst.active = False + + # Activate the specified list + self._lists[list_id].active = True + + await self._save_lists() + _LOGGER.debug("Set active list: %s", list_id) + return True + + # Items methods + async def _save_items(self) -> None: + """Save items to storage.""" + data = { + list_id: [item.to_dict() for item in items] + for list_id, items in self._items.items() + } + await self._store_items.async_save(data) + + def get_items(self, list_id: str) -> List[Item]: + """Get items for a list.""" + return self._items.get(list_id, []) + + async def add_item(self, list_id: str, **kwargs) -> Optional[Item]: + """Add an item to a list.""" + if list_id not in self._lists: + return None + + new_item = Item( + id=generate_id(), + list_id=list_id, + **kwargs + ) + new_item.calculate_total() + + if list_id not in self._items: + self._items[list_id] = [] + + self._items[list_id].append(new_item) + + # Update product frequency if product_id provided + if new_item.product_id and new_item.product_id in self._products: + product = self._products[new_item.product_id] + product.user_frequency += 1 + from .models import current_timestamp + product.last_used = current_timestamp() + await self._save_products() + + await self._save_items() + _LOGGER.debug("Added item to list %s: %s", list_id, new_item.name) + return new_item + + async def update_item(self, item_id: str, **kwargs) -> Optional[Item]: + """Update an item.""" + for list_id, items in self._items.items(): + for item in items: + if item.id == item_id: + for key, value in kwargs.items(): + if hasattr(item, key): + setattr(item, key, value) + + from .models import current_timestamp + item.updated_at = current_timestamp() + item.calculate_total() + + await self._save_items() + _LOGGER.debug("Updated item: %s", item_id) + return item + + return None + + async def check_item(self, item_id: str, checked: bool) -> Optional[Item]: + """Check or uncheck an item.""" + for items in self._items.values(): + for item in items: + if item.id == item_id: + item.checked = checked + from .models import current_timestamp + item.checked_at = current_timestamp() if checked else None + item.updated_at = current_timestamp() + + await self._save_items() + _LOGGER.debug("Checked item: %s = %s", item_id, checked) + return item + + return None + + async def delete_item(self, item_id: str) -> bool: + """Delete an item.""" + for list_id, items in self._items.items(): + for i, item in enumerate(items): + if item.id == item_id: + del self._items[list_id][i] + await self._save_items() + _LOGGER.debug("Deleted item: %s", item_id) + return True + + return False + + async def bulk_check_items(self, item_ids: List[str], checked: bool) -> int: + """Bulk check/uncheck items.""" + count = 0 + from .models import current_timestamp + timestamp = current_timestamp() + + for items in self._items.values(): + for item in items: + if item.id in item_ids: + item.checked = checked + item.checked_at = timestamp if checked else None + item.updated_at = timestamp + count += 1 + + if count > 0: + await self._save_items() + _LOGGER.debug("Bulk checked %d items", count) + + return count + + async def clear_checked_items(self, list_id: str) -> int: + """Clear all checked items from a list.""" + if list_id not in self._items: + return 0 + + original_count = len(self._items[list_id]) + self._items[list_id] = [item for item in self._items[list_id] if not item.checked] + removed_count = original_count - len(self._items[list_id]) + + if removed_count > 0: + await self._save_items() + _LOGGER.info("Cleared %d checked items from list %s", removed_count, list_id) + + return removed_count + + def get_list_total(self, list_id: str) -> Dict[str, Any]: + """Get total price for a list.""" + items = self.get_items(list_id) + total = 0.0 + item_count = 0 + + for item in items: + if not item.checked and item.price is not None: + total += item.quantity * item.price + item_count += 1 + + return { + "total": round(total, 2), + "currency": self.hass.config.currency, + "item_count": item_count + } + + # Products methods + async def _save_products(self) -> None: + """Save products to storage.""" + data = {product_id: product.to_dict() for product_id, product in self._products.items()} + await self._store_products.async_save(data) + + def get_products(self) -> List[Product]: + """Get all products.""" + return list(self._products.values()) + + def get_product(self, product_id: str) -> Optional[Product]: + """Get a specific product.""" + return self._products.get(product_id) + + def search_products( + self, + query: str, + limit: int = 10, + exclude_allergens: Optional[List[str]] = None, + include_tags: Optional[List[str]] = None, + substitution_group: Optional[str] = None, + ) -> List[Product]: + """Search products with enhanced fuzzy matching and filters. + + Args: + query: Search query + limit: Maximum results + exclude_allergens: Allergens to exclude + include_tags: Tags to include + substitution_group: Filter by substitution group + + Returns: + List of matching products + """ + if not self._search_engine: + _LOGGER.warning("Search engine not initialized") + return [] + + # Convert products dict to format search engine expects + products_dict = {pid: p.to_dict() for pid, p in self._products.items()} + search_engine = ProductSearch(products_dict) + + results = search_engine.search( + query=query, + limit=limit, + exclude_allergens=exclude_allergens, + include_tags=include_tags, + substitution_group=substitution_group, + ) + + # Convert back to Product objects + return [self._products[r["id"]] for r in results if r["id"] in self._products] + + def find_product_substitutes(self, product_id: str, limit: int = 5) -> List[Product]: + """Find substitute products. + + Args: + product_id: Product to find substitutes for + limit: Maximum substitutes + + Returns: + List of substitute products + """ + if not self._search_engine: + return [] + + products_dict = {pid: p.to_dict() for pid, p in self._products.items()} + search_engine = ProductSearch(products_dict) + + results = search_engine.find_substitutes(product_id, limit) + return [self._products[r["id"]] for r in results if r["id"] in self._products] + + def get_product_suggestions(self, limit: int = 20) -> List[Product]: + """Get product suggestions based on usage frequency.""" + products = list(self._products.values()) + products.sort(key=lambda p: p.user_frequency, reverse=True) + return products[:limit] + + async def add_product(self, **kwargs) -> Product: + """Add a new product.""" + new_product = Product( + id=generate_id(), + currency=self.hass.config.currency, + **kwargs + ) + self._products[new_product.id] = new_product + await self._save_products() + _LOGGER.debug("Added product: %s", new_product.name) + return new_product + + async def update_product(self, product_id: str, **kwargs) -> Optional[Product]: + """Update a product.""" + if product_id not in self._products: + return None + + product = self._products[product_id] + for key, value in kwargs.items(): + if hasattr(product, key): + setattr(product, key, value) + + await self._save_products() + _LOGGER.debug("Updated product: %s", product_id) + return product + + # Categories methods + async def _save_categories(self) -> None: + """Save categories to storage.""" + data = [cat.to_dict() for cat in self._categories] + await self._store_categories.async_save(data) + + def get_categories(self) -> List[Category]: + """Get all categories.""" + return self._categories diff --git a/custom_components/shopping_list_manager/utils/__init__.py b/custom_components/shopping_list_manager/utils/__init__.py new file mode 100644 index 0000000..753d73b --- /dev/null +++ b/custom_components/shopping_list_manager/utils/__init__.py @@ -0,0 +1 @@ +"""Utilities for Shopping List Manager.""" diff --git a/custom_components/shopping_list_manager/utils/images.py b/custom_components/shopping_list_manager/utils/images.py new file mode 100644 index 0000000..42348ed --- /dev/null +++ b/custom_components/shopping_list_manager/utils/images.py @@ -0,0 +1,109 @@ +"""Image handling utilities for Shopping List Manager.""" +import logging +import os +from pathlib import Path +from typing import Optional + +_LOGGER = logging.getLogger(__name__) + + +class ImageHandler: + """Handle product images with URL and local file support.""" + + def __init__(self, hass, config_path: str): + """Initialize image handler. + + Args: + hass: Home Assistant instance + config_path: Path to HA config directory + """ + self.hass = hass + # Images stored in /config/www/shopping_list_manager/images/ + self._local_images_dir = Path(config_path) / "www" / "shopping_list_manager" / "images" + self._local_images_dir.mkdir(parents=True, exist_ok=True) + + _LOGGER.info("Image directory: %s", self._local_images_dir) + + def get_image_url(self, product_name: str, external_url: Optional[str] = None) -> str: + """Get image URL for a product. + + Priority: + 1. External URL (if provided) + 2. Local file match + 3. Placeholder + + Args: + product_name: Name of product to find image for + external_url: Optional external image URL + + Returns: + Image URL (external, local, or placeholder) + """ + # Priority 1: Use external URL if provided + if external_url: + return external_url + + # Priority 2: Look for local file + local_url = self._find_local_image(product_name) + if local_url: + return local_url + + # Priority 3: Placeholder + return self._get_placeholder_url() + + def _find_local_image(self, product_name: str) -> Optional[str]: + """Find local image file for product. + + Searches for files matching product name (case-insensitive). + Supports: .webp, .jpg, .jpeg, .png + + Args: + product_name: Product name to search for + + Returns: + Local URL if found, None otherwise + """ + # Normalize product name for filename matching + normalized_name = product_name.lower().replace(" ", "_") + + # Supported extensions + extensions = [".webp", ".jpg", ".jpeg", ".png"] + + for ext in extensions: + # Check exact match + image_file = self._local_images_dir / f"{normalized_name}{ext}" + if image_file.exists(): + return f"/local/shopping_list_manager/images/{normalized_name}{ext}" + + # Check for files starting with the product name + for file in self._local_images_dir.glob(f"{normalized_name}*{ext}"): + return f"/local/shopping_list_manager/images/{file.name}" + + return None + + def _get_placeholder_url(self) -> str: + """Get placeholder image URL. + + Returns: + URL to placeholder image + """ + # Use a simple colored placeholder + # You can replace this with a real placeholder image later + return "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Crect width='200' height='200' fill='%23f0f0f0'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' font-family='Arial' font-size='16' fill='%23999'%3ENo Image%3C/text%3E%3C/svg%3E" + + def list_available_images(self) -> list: + """List all available local images. + + Returns: + List of (filename, product_name_guess) tuples + """ + images = [] + extensions = [".webp", ".jpg", ".jpeg", ".png"] + + for ext in extensions: + for image_file in self._local_images_dir.glob(f"*{ext}"): + # Guess product name from filename + product_name = image_file.stem.replace("_", " ").title() + images.append((image_file.name, product_name)) + + return sorted(images) diff --git a/custom_components/shopping_list_manager/utils/search.py b/custom_components/shopping_list_manager/utils/search.py new file mode 100644 index 0000000..675aab6 --- /dev/null +++ b/custom_components/shopping_list_manager/utils/search.py @@ -0,0 +1,192 @@ +"""Enhanced product search utilities.""" +import logging +from typing import List, Dict, Any, Optional +from rapidfuzz import fuzz, process + +_LOGGER = logging.getLogger(__name__) + + +class ProductSearch: + """Advanced product search with fuzzy matching and filtering.""" + + def __init__(self, products: Dict[str, Any]): + """Initialize search with product catalog. + + Args: + products: Dictionary of product_id -> Product objects + """ + self.products = products + + def search( + self, + query: str, + limit: int = 10, + exclude_allergens: Optional[List[str]] = None, + include_tags: Optional[List[str]] = None, + substitution_group: Optional[str] = None, + taxonomy_filters: Optional[Dict[str, Any]] = None, + min_score: int = 60, + ) -> List[Dict[str, Any]]: + """Advanced product search with multiple filters. + + Args: + query: Search query string + limit: Maximum results to return + exclude_allergens: List of allergens to exclude (e.g., ["milk", "gluten"]) + include_tags: Only include products with these tags + substitution_group: Filter by substitution group + taxonomy_filters: Filter by taxonomy (e.g., {"dietary": ["vegan"]}) + min_score: Minimum fuzzy match score (0-100) + + Returns: + List of matching products with scores + """ + query_lower = query.lower().strip() + + if not query_lower: + return [] + + candidates = [] + + for product_id, product in self.products.items(): + # Apply allergen filter + if exclude_allergens: + if any( + allergen in product.get("allergens", []) + for allergen in exclude_allergens + ): + continue + + # Apply tag filter + if include_tags: + if not any( + tag in product.get("tags", []) + for tag in include_tags + ): + continue + + # Apply substitution group filter + if substitution_group: + if product.get("substitution_group") != substitution_group: + continue + + # Apply taxonomy filters + if taxonomy_filters: + product_taxonomy = product.get("taxonomy", {}) + matches_taxonomy = True + + for key, values in taxonomy_filters.items(): + if key not in product_taxonomy: + matches_taxonomy = False + break + + product_values = product_taxonomy[key] + if isinstance(product_values, list): + if not any(v in product_values for v in values): + matches_taxonomy = False + break + else: + if product_values not in values: + matches_taxonomy = False + break + + if not matches_taxonomy: + continue + + # Calculate match score + score = self._calculate_score(query_lower, product) + + if score >= min_score: + candidates.append({ + "product": product, + "score": score, + }) + + # Sort by score (descending), then by user frequency, then by priority + candidates.sort( + key=lambda x: ( + x["score"], + x["product"].get("user_frequency", 0), + x["product"].get("priority_level", 0), + ), + reverse=True + ) + + # Return top results + return [c["product"] for c in candidates[:limit]] + + def _calculate_score(self, query: str, product: Dict[str, Any]) -> int: + """Calculate fuzzy match score for a product. + + Args: + query: Search query + product: Product dictionary + + Returns: + Score from 0-100 + """ + product_name = product.get("name", "").lower() + aliases = [a.lower() for a in product.get("aliases", [])] + + # Exact match gets highest score + if query == product_name: + return 100 + + # Check aliases for exact match + if query in aliases: + return 95 + + # Check if query is substring of product name + if query in product_name: + return 90 + + # Check if query is substring of any alias + for alias in aliases: + if query in alias: + return 85 + + # Fuzzy match on product name + name_score = fuzz.WRatio(query, product_name) + + # Fuzzy match on aliases + alias_scores = [fuzz.WRatio(query, alias) for alias in aliases] + best_alias_score = max(alias_scores) if alias_scores else 0 + + # Return best score + return max(name_score, best_alias_score) + + def find_substitutes(self, product_id: str, limit: int = 5) -> List[Dict[str, Any]]: + """Find substitute products for a given product. + + Args: + product_id: ID of product to find substitutes for + limit: Maximum substitutes to return + + Returns: + List of substitute products + """ + if product_id not in self.products: + return [] + + product = self.products[product_id] + substitution_group = product.get("substitution_group") + + if not substitution_group: + return [] + + # Find all products in the same substitution group + substitutes = [] + for pid, p in self.products.items(): + if pid != product_id and p.get("substitution_group") == substitution_group: + substitutes.append(p) + + # Sort by priority and frequency + substitutes.sort( + key=lambda x: ( + x.get("priority_level", 0), + x.get("user_frequency", 0), + ), + reverse=True + ) + + return substitutes[:limit] diff --git a/custom_components/shopping_list_manager/websocket/__init__.py b/custom_components/shopping_list_manager/websocket/__init__.py new file mode 100644 index 0000000..3dea9e2 --- /dev/null +++ b/custom_components/shopping_list_manager/websocket/__init__.py @@ -0,0 +1 @@ +"""WebSocket API handlers for Shopping List Manager.""" diff --git a/custom_components/shopping_list_manager/websocket/handlers.py b/custom_components/shopping_list_manager/websocket/handlers.py new file mode 100644 index 0000000..10c8000 --- /dev/null +++ b/custom_components/shopping_list_manager/websocket/handlers.py @@ -0,0 +1,793 @@ +"""WebSocket API handlers for Shopping List Manager.""" +import logging +from typing import Any, Dict + +import voluptuous as vol + +from homeassistant.components import websocket_api +from homeassistant.core import HomeAssistant, callback + +from ..const import ( + WS_TYPE_LISTS_GET_ALL, + WS_TYPE_LISTS_CREATE, + WS_TYPE_LISTS_UPDATE, + WS_TYPE_LISTS_DELETE, + WS_TYPE_LISTS_SET_ACTIVE, + WS_TYPE_ITEMS_GET, + WS_TYPE_ITEMS_ADD, + WS_TYPE_ITEMS_UPDATE, + WS_TYPE_ITEMS_CHECK, + WS_TYPE_ITEMS_DELETE, + WS_TYPE_ITEMS_REORDER, + WS_TYPE_ITEMS_BULK_CHECK, + WS_TYPE_ITEMS_CLEAR_CHECKED, + WS_TYPE_ITEMS_GET_TOTAL, + WS_TYPE_PRODUCTS_SEARCH, + WS_TYPE_PRODUCTS_SUGGESTIONS, + WS_TYPE_PRODUCTS_ADD, + WS_TYPE_PRODUCTS_UPDATE, + WS_TYPE_CATEGORIES_GET_ALL, + EVENT_ITEM_ADDED, + EVENT_ITEM_UPDATED, + EVENT_ITEM_CHECKED, + EVENT_ITEM_DELETED, + EVENT_LIST_UPDATED, + EVENT_LIST_DELETED, +) +from .. import get_storage + +_LOGGER = logging.getLogger(__name__) + + +# ============================================================================= +# LIST HANDLERS +# ============================================================================= + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_LISTS_GET_ALL, + } +) +@callback +def websocket_get_lists( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle get all lists command.""" + storage = get_storage(hass) + lists = storage.get_lists() + + connection.send_result( + msg["id"], + { + "lists": [lst.to_dict() for lst in lists] + } + ) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_LISTS_CREATE, + vol.Required("name"): str, + vol.Optional("icon", default="mdi:cart"): str, + } +) +@websocket_api.async_response +async def websocket_create_list( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle create list command.""" + storage = get_storage(hass) + + new_list = await storage.create_list( + name=msg["name"], + icon=msg.get("icon", "mdi:cart") + ) + + # Fire event + hass.bus.async_fire( + EVENT_LIST_UPDATED, + {"list_id": new_list.id, "action": "created"} + ) + + connection.send_result( + msg["id"], + {"list": new_list.to_dict()} + ) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_LISTS_UPDATE, + vol.Required("list_id"): str, + vol.Optional("name"): str, + vol.Optional("icon"): str, + vol.Optional("category_order"): [str], + } +) +@websocket_api.async_response +async def websocket_update_list( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle update list command.""" + storage = get_storage(hass) + list_id = msg["list_id"] + + # Build update kwargs + update_data = {} + if "name" in msg: + update_data["name"] = msg["name"] + if "icon" in msg: + update_data["icon"] = msg["icon"] + if "category_order" in msg: + update_data["category_order"] = msg["category_order"] + + updated_list = await storage.update_list(list_id, **update_data) + + if updated_list is None: + connection.send_error(msg["id"], "not_found", "List not found") + return + + # Fire event + hass.bus.async_fire( + EVENT_LIST_UPDATED, + {"list_id": list_id, "action": "updated"} + ) + + connection.send_result( + msg["id"], + {"list": updated_list.to_dict()} + ) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_LISTS_DELETE, + vol.Required("list_id"): str, + } +) +@websocket_api.async_response +async def websocket_delete_list( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle delete list command.""" + storage = get_storage(hass) + list_id = msg["list_id"] + + success = await storage.delete_list(list_id) + + if not success: + connection.send_error(msg["id"], "not_found", "List not found") + return + + # Fire event + hass.bus.async_fire( + EVENT_LIST_DELETED, + {"list_id": list_id} + ) + + connection.send_result(msg["id"], {"success": True}) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_LISTS_SET_ACTIVE, + vol.Required("list_id"): str, + } +) +@websocket_api.async_response +async def websocket_set_active_list( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle set active list command.""" + storage = get_storage(hass) + list_id = msg["list_id"] + + success = await storage.set_active_list(list_id) + + if not success: + connection.send_error(msg["id"], "not_found", "List not found") + return + + # Fire event + hass.bus.async_fire( + EVENT_LIST_UPDATED, + {"list_id": list_id, "action": "set_active"} + ) + + connection.send_result(msg["id"], {"success": True}) + + +# ============================================================================= +# ITEM HANDLERS +# ============================================================================= + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_ITEMS_GET, + vol.Required("list_id"): str, + } +) +@callback +def websocket_get_items( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle get items command.""" + storage = get_storage(hass) + list_id = msg["list_id"] + + items = storage.get_items(list_id) + + connection.send_result( + msg["id"], + { + "items": [item.to_dict() for item in items] + } + ) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_ITEMS_ADD, + vol.Required("list_id"): str, + vol.Required("name"): str, + vol.Required("category_id"): str, + vol.Optional("product_id"): str, + vol.Optional("quantity", default=1): vol.Coerce(float), + vol.Optional("unit", default="units"): str, + vol.Optional("note"): str, + vol.Optional("price"): vol.Coerce(float), + vol.Optional("image_url"): str, + vol.Optional("barcode"): str, + } +) +@websocket_api.async_response +async def websocket_add_item( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle add item command.""" + storage = get_storage(hass) + list_id = msg["list_id"] + + # Build item data + item_data = { + "name": msg["name"], + "category_id": msg["category_id"], + "quantity": msg.get("quantity", 1), + "unit": msg.get("unit", "units"), + } + + # Optional fields + optional_fields = ["product_id", "note", "price", "image_url", "barcode"] + for field in optional_fields: + if field in msg: + item_data[field] = msg[field] + + new_item = await storage.add_item(list_id, **item_data) + + if new_item is None: + connection.send_error(msg["id"], "not_found", "List not found") + return + + # Fire event + hass.bus.async_fire( + EVENT_ITEM_ADDED, + { + "list_id": list_id, + "item_id": new_item.id, + "item": new_item.to_dict() + } + ) + + connection.send_result( + msg["id"], + {"item": new_item.to_dict()} + ) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_ITEMS_UPDATE, + vol.Required("item_id"): str, + vol.Optional("name"): str, + vol.Optional("quantity"): vol.Coerce(float), + vol.Optional("unit"): str, + vol.Optional("note"): str, + vol.Optional("price"): vol.Coerce(float), + vol.Optional("category_id"): str, + vol.Optional("image_url"): str, + } +) +@websocket_api.async_response +async def websocket_update_item( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle update item command.""" + storage = get_storage(hass) + item_id = msg["item_id"] + + # Build update data + update_data = {} + update_fields = ["name", "quantity", "unit", "note", "price", "category_id", "image_url"] + for field in update_fields: + if field in msg: + update_data[field] = msg[field] + + updated_item = await storage.update_item(item_id, **update_data) + + if updated_item is None: + connection.send_error(msg["id"], "not_found", "Item not found") + return + + # Fire event + hass.bus.async_fire( + EVENT_ITEM_UPDATED, + { + "list_id": updated_item.list_id, + "item_id": item_id, + "item": updated_item.to_dict() + } + ) + + connection.send_result( + msg["id"], + {"item": updated_item.to_dict()} + ) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_ITEMS_CHECK, + vol.Required("item_id"): str, + vol.Required("checked"): bool, + } +) +@websocket_api.async_response +async def websocket_check_item( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle check/uncheck item command.""" + storage = get_storage(hass) + item_id = msg["item_id"] + checked = msg["checked"] + + updated_item = await storage.check_item(item_id, checked) + + if updated_item is None: + connection.send_error(msg["id"], "not_found", "Item not found") + return + + # Fire event + hass.bus.async_fire( + EVENT_ITEM_CHECKED, + { + "list_id": updated_item.list_id, + "item_id": item_id, + "checked": checked + } + ) + + connection.send_result( + msg["id"], + {"item": updated_item.to_dict()} + ) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_ITEMS_DELETE, + vol.Required("item_id"): str, + } +) +@websocket_api.async_response +async def websocket_delete_item( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle delete item command.""" + storage = get_storage(hass) + item_id = msg["item_id"] + + success = await storage.delete_item(item_id) + + if not success: + connection.send_error(msg["id"], "not_found", "Item not found") + return + + # Fire event + hass.bus.async_fire( + EVENT_ITEM_DELETED, + {"item_id": item_id} + ) + + connection.send_result(msg["id"], {"success": True}) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_ITEMS_REORDER, + vol.Required("list_id"): str, + vol.Required("item_order"): [str], + } +) +@websocket_api.async_response +async def websocket_reorder_items( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle reorder items command.""" + storage = get_storage(hass) + list_id = msg["list_id"] + item_order = msg["item_order"] + + updated_list = await storage.update_list(list_id, item_order=item_order) + + if updated_list is None: + connection.send_error(msg["id"], "not_found", "List not found") + return + + # Fire event + hass.bus.async_fire( + EVENT_LIST_UPDATED, + {"list_id": list_id, "action": "reordered"} + ) + + connection.send_result(msg["id"], {"success": True}) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_ITEMS_BULK_CHECK, + vol.Required("item_ids"): [str], + vol.Required("checked"): bool, + } +) +@websocket_api.async_response +async def websocket_bulk_check_items( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle bulk check/uncheck items command.""" + storage = get_storage(hass) + item_ids = msg["item_ids"] + checked = msg["checked"] + + count = await storage.bulk_check_items(item_ids, checked) + + # Fire event + hass.bus.async_fire( + EVENT_ITEM_CHECKED, + { + "item_ids": item_ids, + "checked": checked, + "count": count + } + ) + + connection.send_result( + msg["id"], + {"success": True, "count": count} + ) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_ITEMS_CLEAR_CHECKED, + vol.Required("list_id"): str, + } +) +@websocket_api.async_response +async def websocket_clear_checked_items( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle clear checked items command.""" + storage = get_storage(hass) + list_id = msg["list_id"] + + count = await storage.clear_checked_items(list_id) + + # Fire event + hass.bus.async_fire( + EVENT_ITEM_DELETED, + {"list_id": list_id, "count": count, "action": "cleared_checked"} + ) + + connection.send_result( + msg["id"], + {"success": True, "count": count} + ) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_ITEMS_GET_TOTAL, + vol.Required("list_id"): str, + } +) +@callback +def websocket_get_list_total( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle get list total command.""" + storage = get_storage(hass) + list_id = msg["list_id"] + + total_data = storage.get_list_total(list_id) + + connection.send_result(msg["id"], total_data) + + +# ============================================================================= +# PRODUCT HANDLERS +# ============================================================================= + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_PRODUCTS_SEARCH, + vol.Required("query"): str, + vol.Optional("limit", default=10): int, + vol.Optional("exclude_allergens", default=None): vol.Any(None, [str]), + vol.Optional("include_tags", default=None): vol.Any(None, [str]), + vol.Optional("substitution_group", default=None): vol.Any(None, str), + } +) +@callback +def websocket_search_products( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle search products command with enhanced filters.""" + storage = get_storage(hass) + + try: + results = storage.search_products( + query=msg["query"], + limit=msg.get("limit", 10), + exclude_allergens=msg.get("exclude_allergens"), + include_tags=msg.get("include_tags"), + substitution_group=msg.get("substitution_group"), + ) + + connection.send_result( + msg["id"], + {"products": [product.to_dict() for product in results]} + ) + except Exception as err: + _LOGGER.error("Error searching products: %s", err) + connection.send_error(msg["id"], "search_failed", str(err)) + + +@websocket_api.websocket_command( + { + vol.Required("type"): "shopping_list_manager/products/substitutes", + vol.Required("product_id"): str, + vol.Optional("limit", default=5): int, + } +) +@callback +def websocket_get_product_substitutes( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle get product substitutes command.""" + storage = get_storage(hass) + + try: + substitutes = storage.find_product_substitutes( + product_id=msg["product_id"], + limit=msg.get("limit", 5), + ) + + connection.send_result( + msg["id"], + {"substitutes": [product.to_dict() for product in substitutes]} + ) + except Exception as err: + _LOGGER.error("Error finding substitutes: %s", err) + connection.send_error(msg["id"], "substitutes_failed", str(err)) + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_PRODUCTS_SEARCH, + vol.Required("query"): str, + vol.Optional("limit", default=10): int, + vol.Optional("exclude_allergens"): [str], + vol.Optional("include_tags"): [str], + vol.Optional("substitution_group"): str, + } +) +@callback +def websocket_search_products( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle search products command with enhanced filters.""" + storage = get_storage(hass) + + try: + results = storage.search_products( + query=msg["query"], + limit=msg.get("limit", 10), + exclude_allergens=msg.get("exclude_allergens"), + include_tags=msg.get("include_tags"), + substitution_group=msg.get("substitution_group"), + ) + + connection.send_result( + msg["id"], + {"products": [product.to_dict() for product in results]} + ) + except Exception as err: + _LOGGER.error("Error searching products: %s", err) + connection.send_error(msg["id"], "search_failed", str(err)) +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_PRODUCTS_SUGGESTIONS, + vol.Optional("limit", default=20): int, + } +) +@callback +def websocket_get_product_suggestions( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle get product suggestions command.""" + storage = get_storage(hass) + limit = msg.get("limit", 20) + + suggestions = storage.get_product_suggestions(limit) + + connection.send_result( + msg["id"], + { + "products": [product.to_dict() for product in suggestions] + } + ) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_PRODUCTS_ADD, + vol.Required("name"): str, + vol.Required("category_id"): str, + vol.Optional("aliases"): [str], + vol.Optional("default_unit", default="units"): str, + vol.Optional("default_quantity", default=1): vol.Coerce(float), + vol.Optional("price"): vol.Coerce(float), + vol.Optional("barcode"): str, + vol.Optional("image_url"): str, + } +) +@websocket_api.async_response +async def websocket_add_product( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle add product command.""" + storage = get_storage(hass) + + # Build product data + product_data = { + "name": msg["name"], + "category_id": msg["category_id"], + "default_unit": msg.get("default_unit", "units"), + "default_quantity": msg.get("default_quantity", 1), + "custom": True, + "source": "user" + } + + # Optional fields + optional_fields = ["aliases", "price", "barcode", "image_url"] + for field in optional_fields: + if field in msg: + product_data[field] = msg[field] + + new_product = await storage.add_product(**product_data) + + connection.send_result( + msg["id"], + {"product": new_product.to_dict()} + ) + + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_PRODUCTS_UPDATE, + vol.Required("product_id"): str, + vol.Optional("name"): str, + vol.Optional("category_id"): str, + vol.Optional("price"): vol.Coerce(float), + vol.Optional("default_unit"): str, + vol.Optional("default_quantity"): vol.Coerce(float), + vol.Optional("aliases"): [str], + vol.Optional("image_url"): str, + } +) +@websocket_api.async_response +async def websocket_update_product( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle update product command.""" + storage = get_storage(hass) + product_id = msg["product_id"] + + # Build update data + update_data = {} + update_fields = ["name", "category_id", "price", "default_unit", "default_quantity", "aliases", "image_url"] + for field in update_fields: + if field in msg: + update_data[field] = msg[field] + + # Add price_updated timestamp if price changed + if "price" in update_data: + from ..models import current_timestamp + update_data["price_updated"] = current_timestamp() + + updated_product = await storage.update_product(product_id, **update_data) + + if updated_product is None: + connection.send_error(msg["id"], "not_found", "Product not found") + return + + connection.send_result( + msg["id"], + {"product": updated_product.to_dict()} + ) + + +# ============================================================================= +# CATEGORY HANDLERS +# ============================================================================= + +@websocket_api.websocket_command( + { + vol.Required("type"): WS_TYPE_CATEGORIES_GET_ALL, + } +) +@callback +def websocket_get_categories( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: Dict[str, Any], +) -> None: + """Handle get all categories command.""" + storage = get_storage(hass) + categories = storage.get_categories() + + connection.send_result( + msg["id"], + { + "categories": [cat.to_dict() for cat in categories] + } + ) diff --git a/custom_components/shopping_list_manager/websocket_api.py b/custom_components/shopping_list_manager/websocket_api.py deleted file mode 100644 index da53906..0000000 --- a/custom_components/shopping_list_manager/websocket_api.py +++ /dev/null @@ -1,325 +0,0 @@ -"""WebSocket API for Shopping List Manager.""" -import logging -import voluptuous as vol - -from homeassistant.components import websocket_api -from homeassistant.core import HomeAssistant, callback - -from .const import DOMAIN -from .models import InvariantError - -_LOGGER = logging.getLogger(__name__) - -@websocket_api.websocket_command({ - vol.Required("type"): "shopping_list_manager/create_list", - vol.Required("list_id"): str, - vol.Required("catalogue"): str, - vol.Optional("visibility", default="shared"): vol.In(["shared", "private"]), -}) -@websocket_api.async_response -async def websocket_create_list( - hass: HomeAssistant, - connection: websocket_api.ActiveConnection, - msg: dict, -) -> None: - manager = hass.data[DOMAIN]["manager"] - - try: - await manager.async_create_list( - list_id=msg["list_id"], - catalogue=msg["catalogue"], - owner=connection.user.id, - visibility=msg.get("visibility", "shared"), - ) - - connection.send_result(msg["id"], {"success": True}) - - except Exception as err: - connection.send_error(msg["id"], "create_list_failed", str(err)) - - -@websocket_api.websocket_command({ - vol.Required("type"): "shopping_list_manager/add_product", - vol.Optional("list_id", default="groceries"): str, - vol.Required("key"): str, - vol.Required("name"): str, - vol.Optional("category", default="other"): str, - vol.Optional("unit", default="pcs"): str, - vol.Optional("image", default=""): str, -}) -@websocket_api.async_response -async def websocket_add_product( - hass: HomeAssistant, - connection: websocket_api.ActiveConnection, - msg: dict, -) -> None: - """ - Add or update a product in the catalog. - - Does NOT modify quantity - use set_qty for that. - - Request: - { - "type": "shopping_list_manager/add_product", - "list_id": "groceries", # optional, defaults to "groceries" - "key": "milk", - "name": "Milk", - "category": "dairy", - "unit": "pcs", - "image": "" - } - - Response: - { - "success": true, - "result": { - "key": "milk", - "name": "Milk", - "category": "dairy", - "unit": "pcs", - "image": "" - } - } - """ - manager = hass.data[DOMAIN]["manager"] - list_id = msg.get("list_id", "groceries") - - try: - product = await manager.async_add_product( - list_id=list_id, - key=msg["key"], - name=msg["name"], - category=msg.get("category", "other"), - unit=msg.get("unit", "pcs"), - image=msg.get("image", "") - ) - - connection.send_result(msg["id"], product.to_dict()) - - except Exception as err: - _LOGGER.error("Error adding product to list '%s': %s", list_id, err) - connection.send_error(msg["id"], "add_product_failed", str(err)) - - -@websocket_api.websocket_command({ - vol.Required("type"): "shopping_list_manager/get_catalogues", -}) -@websocket_api.async_response -async def ws_get_catalogues( - hass: HomeAssistant, - connection: websocket_api.ActiveConnection, - msg: dict, -) -> None: - """Return catalogue metadata (read-only).""" - manager = hass.data[DOMAIN]["manager"] - - try: - catalogues = manager.get_catalogues() - connection.send_result(msg["id"], catalogues) - except Exception as err: - _LOGGER.error("Error getting catalogues: %s", err) - connection.send_error(msg["id"], "get_catalogues_failed", str(err)) - - -@websocket_api.websocket_command({ - vol.Required("type"): "shopping_list_manager/get_lists", -}) -@websocket_api.async_response -async def ws_get_lists( - hass: HomeAssistant, - connection: websocket_api.ActiveConnection, - msg: dict, -) -> None: - """Return list → catalogue mapping (read-only).""" - manager = hass.data[DOMAIN]["manager"] - - try: - # Ensure lists are loaded - await manager._ensure_lists_loaded() - lists = manager._lists - connection.send_result(msg["id"], lists) - except Exception as err: - _LOGGER.error("Error getting lists: %s", err) - connection.send_error(msg["id"], "get_lists_failed", str(err)) - - -@websocket_api.websocket_command({ - vol.Required("type"): "shopping_list_manager/set_qty", - vol.Optional("list_id", default="groceries"): str, - vol.Required("key"): str, - vol.Required("qty"): vol.All(int, vol.Range(min=0)), -}) -@websocket_api.async_response -async def websocket_set_qty( - hass: HomeAssistant, - connection: websocket_api.ActiveConnection, - msg: dict, -) -> None: - """ - Set quantity for a product on the shopping list. - - Product MUST exist in catalog first. - qty = 0 removes from list. - qty > 0 adds/updates on list. - - Request: - { - "type": "shopping_list_manager/set_qty", - "list_id": "groceries", # optional, defaults to "groceries" - "key": "milk", - "qty": 2 - } - - Response: - { - "success": true - } - - Error (if product doesn't exist): - { - "success": false, - "error": { - "code": "invariant_violation", - "message": "Cannot set quantity for unknown product 'milk'..." - } - } - """ - manager = hass.data[DOMAIN]["manager"] - list_id = msg.get("list_id", "groceries") - - try: - await manager.async_set_qty( - list_id=list_id, - key=msg["key"], - qty=msg["qty"] - ) - - connection.send_result(msg["id"], {"success": True}) - - except InvariantError as err: - # This is expected if frontend tries to set qty for non-existent product - _LOGGER.warning("Invariant violation in set_qty (list '%s'): %s", list_id, err) - connection.send_error(msg["id"], "invariant_violation", str(err)) - - except Exception as err: - _LOGGER.error("Error setting quantity in list '%s': %s", list_id, err) - connection.send_error(msg["id"], "set_qty_failed", str(err)) - - -@websocket_api.websocket_command({ - vol.Required("type"): "shopping_list_manager/get_products", - vol.Optional("list_id", default="groceries"): str, -}) -@websocket_api.async_response -async def websocket_get_products( - hass: HomeAssistant, - connection: websocket_api.ActiveConnection, - msg: dict, -) -> None: - """ - Get all products in the catalog. - - Request: - { - "type": "shopping_list_manager/get_products", - "list_id": "groceries" # optional, defaults to "groceries" - } - - Response: - { - "milk": { - "key": "milk", - "name": "Milk", - "category": "dairy", - "unit": "pcs", - "image": "" - }, - ... - } - """ - manager = hass.data[DOMAIN]["manager"] - list_id = msg.get("list_id", "groceries") - - try: - products = await manager.async_get_products(list_id=list_id) - connection.send_result(msg["id"], products) - - except Exception as err: - _LOGGER.error("Error getting products for list '%s': %s", list_id, err) - connection.send_error(msg["id"], "get_products_failed", str(err)) - - -@websocket_api.websocket_command({ - vol.Required("type"): "shopping_list_manager/get_active", - vol.Optional("list_id", default="groceries"): str, -}) -@websocket_api.async_response -async def websocket_get_active( - hass: HomeAssistant, - connection: websocket_api.ActiveConnection, - msg: dict, -) -> None: - """ - Get active shopping list (quantities only). - - Request: - { - "type": "shopping_list_manager/get_active", - "list_id": "groceries" # optional, defaults to "groceries" - } - - Response: - { - "milk": {"qty": 2}, - "bread": {"qty": 1}, - ... - } - """ - manager = hass.data[DOMAIN]["manager"] - list_id = msg.get("list_id", "groceries") - - try: - active = await manager.async_get_active(list_id=list_id) - connection.send_result(msg["id"], active) - - except Exception as err: - _LOGGER.error("Error getting active list for '%s': %s", list_id, err) - connection.send_error(msg["id"], "get_active_failed", str(err)) - - -@websocket_api.websocket_command({ - vol.Required("type"): "shopping_list_manager/delete_product", - vol.Optional("list_id", default="groceries"): str, - vol.Required("key"): str, -}) -@websocket_api.async_response -async def websocket_delete_product( - hass: HomeAssistant, - connection: websocket_api.ActiveConnection, - msg: dict, -) -> None: - """ - Delete a product from catalog (and remove from active list). - - Request: - { - "type": "shopping_list_manager/delete_product", - "list_id": "groceries", # optional, defaults to "groceries" - "key": "milk" - } - - Response: - { - "success": true - } - """ - manager = hass.data[DOMAIN]["manager"] - list_id = msg.get("list_id", "groceries") - - try: - await manager.async_delete_product(list_id=list_id, key=msg["key"]) - connection.send_result(msg["id"], {"success": True}) - - except Exception as err: - _LOGGER.error("Error deleting product from list '%s': %s", list_id, err) - connection.send_error(msg["id"], "delete_product_failed", str(err))