feat: add currency_symbol and language fields to custom regions

This commit is contained in:
thekiwismarthome
2026-08-09 10:29:26 +12:00
parent 78f857f8f9
commit 5e2a7e8d35
2 changed files with 25 additions and 10 deletions
@@ -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
@@ -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()}
)