From 5e2a7e8d3579d7a91c87fa2363cef0bcce79e7bd Mon Sep 17 00:00:00 2001 From: thekiwismarthome Date: Sun, 9 Aug 2026 10:29:26 +1200 Subject: [PATCH] feat: add currency_symbol and language fields to custom regions --- .../shopping_list_manager/storage.py | 24 +++++++++++++------ .../websocket/handlers.py | 11 ++++++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/custom_components/shopping_list_manager/storage.py b/custom_components/shopping_list_manager/storage.py index 4b20ca0..d026e1f 100644 --- a/custom_components/shopping_list_manager/storage.py +++ b/custom_components/shopping_list_manager/storage.py @@ -56,7 +56,7 @@ class ShoppingListStorage: self._products: Dict[str, Product] = {} self._categories: List[Category] = [] self._loyalty_cards: Dict[str, LoyaltyCard] = {} - self._custom_regions: Dict[str, str] = {} # code -> display name + self._custom_regions: Dict[str, Any] = {} # code -> {name, currency_symbol, language} self._search_engine: Optional[ProductSearch] = None self._images_dir = Path(hass.config.path(IMAGES_LOCAL_DIR)) self._legacy_images_dir = Path(hass.config.path(LEGACY_IMAGES_LOCAL_DIR)) @@ -158,10 +158,14 @@ class ShoppingListStorage: } _LOGGER.debug("Loaded %d loyalty cards", len(self._loyalty_cards)) - # Load custom regions + # Load custom regions (migrate old string-only format) custom_regions_data = await self._store_custom_regions.async_load() if custom_regions_data: - self._custom_regions = custom_regions_data.get("regions", {}) + raw = custom_regions_data.get("regions", {}) + self._custom_regions = { + k: (v if isinstance(v, dict) else {"name": v, "currency_symbol": None, "language": None}) + for k, v in raw.items() + } _LOGGER.debug("Loaded %d custom regions", len(self._custom_regions)) # Initialize search engine after products are loaded @@ -838,15 +842,21 @@ class ShoppingListStorage: # Custom Regions # ========================================================================== - def get_custom_regions(self) -> Dict[str, str]: - """Return all custom regions as {code: display_name}.""" + def get_custom_regions(self) -> Dict[str, Any]: + """Return all custom regions as {code: {name, currency_symbol, language}}.""" return dict(self._custom_regions) - async def create_custom_region(self, code: str, name: str) -> bool: + async def create_custom_region( + self, code: str, name: str, currency_symbol: Optional[str] = None, language: Optional[str] = None + ) -> bool: """Create a new custom region. Returns False if the code already exists.""" if code in self._custom_regions: return False - self._custom_regions[code] = name + self._custom_regions[code] = { + "name": name, + "currency_symbol": currency_symbol, + "language": language, + } await self._save_custom_regions() _LOGGER.debug("Created custom region: %s (%s)", code, name) return True diff --git a/custom_components/shopping_list_manager/websocket/handlers.py b/custom_components/shopping_list_manager/websocket/handlers.py index fdf6eda..fff5aa6 100644 --- a/custom_components/shopping_list_manager/websocket/handlers.py +++ b/custom_components/shopping_list_manager/websocket/handlers.py @@ -1217,12 +1217,13 @@ def websocket_get_integration_settings( "BE": "Belgium (Dutch)", } custom = storage.get_custom_regions() + custom_names = {code: region["name"] for code, region in custom.items()} connection.send_result( msg["id"], { "country": country, "version": version, - "available_countries": {**built_in, **custom}, + "available_countries": {**built_in, **custom_names}, "custom_regions": custom, } ) @@ -1272,6 +1273,8 @@ async def websocket_set_country( vol.Required("type"): "shopping_list_manager/regions/create", vol.Required("code"): vol.All(str, vol.Length(min=2, max=8), vol.Upper), vol.Required("name"): vol.All(str, vol.Length(min=1, max=64)), + vol.Optional("currency_symbol"): vol.Any(vol.All(str, vol.Length(min=1, max=5)), None), + vol.Optional("language"): vol.Any(vol.All(str, vol.Length(min=1, max=64)), None), } ) @websocket_api.async_response @@ -1283,20 +1286,22 @@ async def websocket_create_custom_region( """Create a custom region.""" code = msg["code"].upper() name = msg["name"].strip() + currency_symbol = msg.get("currency_symbol") + language = msg.get("language") storage = get_storage(hass) if code in _BUILT_IN_COUNTRIES: connection.send_error(msg["id"], "conflict", f"{code} is a built-in region") return - created = await storage.create_custom_region(code, name) + created = await storage.create_custom_region(code, name, currency_symbol, language) if not created: connection.send_error(msg["id"], "conflict", f"Region {code} already exists") return connection.send_result( msg["id"], - {"success": True, "code": code, "name": name, "custom_regions": storage.get_custom_regions()} + {"success": True, "code": code, "custom_regions": storage.get_custom_regions()} )