Skip to content

Commit

Permalink
Workday add languages (#103127)
Browse files Browse the repository at this point in the history
  • Loading branch information
gjohansson-ST committed Nov 13, 2023
1 parent d4c5a93 commit 8e71086
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 26 deletions.
10 changes: 9 additions & 1 deletion homeassistant/components/workday/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""Sensor to indicate whether the current day is a workday."""
from __future__ import annotations

from holidays import list_supported_countries
from holidays import HolidayBase, country_holidays, list_supported_countries

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_LANGUAGE
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryError
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
Expand All @@ -17,6 +18,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
country: str | None = entry.options.get(CONF_COUNTRY)
province: str | None = entry.options.get(CONF_PROVINCE)

if country and CONF_LANGUAGE not in entry.options:
cls: HolidayBase = country_holidays(country, subdiv=province)
default_language = cls.default_language
new_options = entry.options.copy()
new_options[CONF_LANGUAGE] = default_language
hass.config_entries.async_update_entry(entry, options=new_options)

if country and country not in list_supported_countries():
async_create_issue(
hass,
Expand Down
6 changes: 3 additions & 3 deletions homeassistant/components/workday/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_NAME
from homeassistant.const import CONF_LANGUAGE, CONF_NAME
from homeassistant.core import HomeAssistant, ServiceResponse, SupportsResponse
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
Expand Down Expand Up @@ -72,16 +72,16 @@ async def async_setup_entry(
province: str | None = entry.options.get(CONF_PROVINCE)
sensor_name: str = entry.options[CONF_NAME]
workdays: list[str] = entry.options[CONF_WORKDAYS]
language: str | None = entry.options.get(CONF_LANGUAGE)

year: int = (dt_util.now() + timedelta(days=days_offset)).year

if country:
cls: HolidayBase = country_holidays(country, subdiv=province, years=year)
obj_holidays: HolidayBase = country_holidays(
country,
subdiv=province,
years=year,
language=cls.default_language,
language=language,
)
else:
obj_holidays = HolidayBase()
Expand Down
53 changes: 36 additions & 17 deletions homeassistant/components/workday/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
ConfigFlow,
OptionsFlowWithConfigEntry,
)
from homeassistant.const import CONF_NAME
from homeassistant.const import CONF_LANGUAGE, CONF_NAME
from homeassistant.core import callback
from homeassistant.data_entry_flow import AbortFlow, FlowResult
from homeassistant.exceptions import HomeAssistantError
Expand Down Expand Up @@ -46,7 +46,7 @@
)


def add_province_to_schema(
def add_province_and_language_to_schema(
schema: vol.Schema,
country: str | None,
) -> vol.Schema:
Expand All @@ -55,20 +55,36 @@ def add_province_to_schema(
return schema

all_countries = list_supported_countries(include_aliases=False)
if not all_countries.get(country):
return schema

add_schema = {
vol.Optional(CONF_PROVINCE): SelectSelector(
SelectSelectorConfig(
options=all_countries[country],
mode=SelectSelectorMode.DROPDOWN,
translation_key=CONF_PROVINCE,
language_schema = {}
province_schema = {}

_country = country_holidays(country=country)
if country_default_language := (_country.default_language):
selectable_languages = _country.supported_languages
language_schema = {
vol.Optional(
CONF_LANGUAGE, default=country_default_language
): SelectSelector(
SelectSelectorConfig(
options=list(selectable_languages),
mode=SelectSelectorMode.DROPDOWN,
)
)
),
}
}

if provinces := all_countries.get(country):
province_schema = {
vol.Optional(CONF_PROVINCE): SelectSelector(
SelectSelectorConfig(
options=provinces,
mode=SelectSelectorMode.DROPDOWN,
translation_key=CONF_PROVINCE,
)
),
}

return vol.Schema({**DATA_SCHEMA_OPT.schema, **add_schema})
return vol.Schema({**DATA_SCHEMA_OPT.schema, **language_schema, **province_schema})


def _is_valid_date_range(check_date: str, error: type[HomeAssistantError]) -> bool:
Expand All @@ -93,12 +109,11 @@ def validate_custom_dates(user_input: dict[str, Any]) -> None:

year: int = dt_util.now().year
if country := user_input.get(CONF_COUNTRY):
cls = country_holidays(country)
obj_holidays = country_holidays(
country=country,
subdiv=user_input.get(CONF_PROVINCE),
years=year,
language=cls.default_language,
language=user_input.get(CONF_LANGUAGE),
)
else:
obj_holidays = HolidayBase(years=year)
Expand Down Expand Up @@ -237,7 +252,9 @@ async def async_step_options(
)

schema = await self.hass.async_add_executor_job(
add_province_to_schema, DATA_SCHEMA_OPT, self.data.get(CONF_COUNTRY)
add_province_and_language_to_schema,
DATA_SCHEMA_OPT,
self.data.get(CONF_COUNTRY),
)
new_schema = self.add_suggested_values_to_schema(schema, user_input)
return self.async_show_form(
Expand Down Expand Up @@ -298,7 +315,9 @@ async def async_step_init(
return self.async_create_entry(data=combined_input)

schema: vol.Schema = await self.hass.async_add_executor_job(
add_province_to_schema, DATA_SCHEMA_OPT, self.options.get(CONF_COUNTRY)
add_province_and_language_to_schema,
DATA_SCHEMA_OPT,
self.options.get(CONF_COUNTRY),
)

new_schema = self.add_suggested_values_to_schema(
Expand Down
12 changes: 8 additions & 4 deletions homeassistant/components/workday/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@
"workdays": "Workdays",
"add_holidays": "Add holidays",
"remove_holidays": "Remove Holidays",
"province": "Subdivision of country"
"province": "Subdivision of country",
"language": "Language for named holidays"
},
"data_description": {
"excludes": "List of workdays to exclude",
"days_offset": "Days offset",
"workdays": "List of workdays",
"add_holidays": "Add custom holidays as YYYY-MM-DD or as range using `,` as separator",
"remove_holidays": "Remove holidays as YYYY-MM-DD, as range using `,` as separator or by using partial of name",
"province": "State, Territory, Province, Region of Country"
"province": "State, Territory, Province, Region of Country",
"language": "Choose the language you want to configure named holidays after"
}
}
},
Expand All @@ -48,15 +50,17 @@
"workdays": "[%key:component::workday::config::step::options::data::workdays%]",
"add_holidays": "[%key:component::workday::config::step::options::data::add_holidays%]",
"remove_holidays": "[%key:component::workday::config::step::options::data::remove_holidays%]",
"province": "[%key:component::workday::config::step::options::data::province%]"
"province": "[%key:component::workday::config::step::options::data::province%]",
"language": "[%key:component::workday::config::step::options::data::language%]"
},
"data_description": {
"excludes": "[%key:component::workday::config::step::options::data_description::excludes%]",
"days_offset": "[%key:component::workday::config::step::options::data_description::days_offset%]",
"workdays": "[%key:component::workday::config::step::options::data_description::workdays%]",
"add_holidays": "[%key:component::workday::config::step::options::data_description::add_holidays%]",
"remove_holidays": "[%key:component::workday::config::step::options::data_description::remove_holidays%]",
"province": "[%key:component::workday::config::step::options::data_description::province%]"
"province": "[%key:component::workday::config::step::options::data_description::province%]",
"language": "[%key:component::workday::config::step::options::data_description::language%]"
}
}
},
Expand Down
30 changes: 30 additions & 0 deletions tests/components/workday/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": [],
"language": "de",
}
TEST_CONFIG_NO_LANGUAGE_CONFIGURED = {
"name": DEFAULT_NAME,
"country": "DE",
"province": "BW",
"excludes": DEFAULT_EXCLUDES,
"days_offset": DEFAULT_OFFSET,
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": [],
}
TEST_CONFIG_INCORRECT_COUNTRY = {
"name": DEFAULT_NAME,
Expand All @@ -74,6 +85,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": [],
"language": "de",
}
TEST_CONFIG_INCORRECT_PROVINCE = {
"name": DEFAULT_NAME,
Expand All @@ -84,6 +96,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": [],
"language": "de",
}
TEST_CONFIG_NO_PROVINCE = {
"name": DEFAULT_NAME,
Expand All @@ -93,6 +106,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": [],
"language": "de",
}
TEST_CONFIG_WITH_STATE = {
"name": DEFAULT_NAME,
Expand All @@ -103,6 +117,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": [],
"language": "en_US",
}
TEST_CONFIG_NO_STATE = {
"name": DEFAULT_NAME,
Expand All @@ -112,6 +127,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": [],
"language": "en_US",
}
TEST_CONFIG_INCLUDE_HOLIDAY = {
"name": DEFAULT_NAME,
Expand All @@ -122,6 +138,7 @@ async def init_integration(
"workdays": ["holiday"],
"add_holidays": [],
"remove_holidays": [],
"language": "de",
}
TEST_CONFIG_EXAMPLE_1 = {
"name": DEFAULT_NAME,
Expand All @@ -131,6 +148,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": [],
"language": "en_US",
}
TEST_CONFIG_EXAMPLE_2 = {
"name": DEFAULT_NAME,
Expand All @@ -141,6 +159,7 @@ async def init_integration(
"workdays": ["mon", "wed", "fri"],
"add_holidays": ["2020-02-24"],
"remove_holidays": [],
"language": "de",
}
TEST_CONFIG_REMOVE_HOLIDAY = {
"name": DEFAULT_NAME,
Expand All @@ -150,6 +169,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": ["2020-12-25", "2020-11-26"],
"language": "en_US",
}
TEST_CONFIG_REMOVE_NAMED = {
"name": DEFAULT_NAME,
Expand All @@ -159,6 +179,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": ["Not a Holiday", "Christmas", "Thanksgiving"],
"language": "en_US",
}
TEST_CONFIG_TOMORROW = {
"name": DEFAULT_NAME,
Expand All @@ -168,6 +189,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": [],
"language": "de",
}
TEST_CONFIG_DAY_AFTER_TOMORROW = {
"name": DEFAULT_NAME,
Expand All @@ -177,6 +199,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": [],
"language": "de",
}
TEST_CONFIG_YESTERDAY = {
"name": DEFAULT_NAME,
Expand All @@ -186,6 +209,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": [],
"language": "de",
}
TEST_CONFIG_INCORRECT_ADD_REMOVE = {
"name": DEFAULT_NAME,
Expand All @@ -196,6 +220,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": ["2023-12-32"],
"remove_holidays": ["2023-12-32"],
"language": "de",
}
TEST_CONFIG_INCORRECT_ADD_DATE_RANGE = {
"name": DEFAULT_NAME,
Expand All @@ -206,6 +231,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": ["2023-12-01", "2023-12-30,2023-12-32"],
"remove_holidays": [],
"language": "de",
}
TEST_CONFIG_INCORRECT_REMOVE_DATE_RANGE = {
"name": DEFAULT_NAME,
Expand All @@ -216,6 +242,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": ["2023-12-25", "2023-12-30,2023-12-32"],
"language": "de",
}
TEST_CONFIG_INCORRECT_ADD_DATE_RANGE_LEN = {
"name": DEFAULT_NAME,
Expand All @@ -226,6 +253,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": ["2023-12-01", "2023-12-29,2023-12-30,2023-12-31"],
"remove_holidays": [],
"language": "de",
}
TEST_CONFIG_INCORRECT_REMOVE_DATE_RANGE_LEN = {
"name": DEFAULT_NAME,
Expand All @@ -236,6 +264,7 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": [],
"remove_holidays": ["2023-12-25", "2023-12-29,2023-12-30,2023-12-31"],
"language": "de",
}
TEST_CONFIG_ADD_REMOVE_DATE_RANGE = {
"name": DEFAULT_NAME,
Expand All @@ -246,4 +275,5 @@ async def init_integration(
"workdays": DEFAULT_WORKDAYS,
"add_holidays": ["2022-12-01", "2022-12-05,2022-12-15"],
"remove_holidays": ["2022-12-04", "2022-12-24,2022-12-26"],
"language": "de",
}
2 changes: 2 additions & 0 deletions tests/components/workday/test_binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
TEST_CONFIG_INCORRECT_REMOVE_DATE_RANGE_LEN,
TEST_CONFIG_NO_COUNTRY,
TEST_CONFIG_NO_COUNTRY_ADD_HOLIDAY,
TEST_CONFIG_NO_LANGUAGE_CONFIGURED,
TEST_CONFIG_NO_PROVINCE,
TEST_CONFIG_NO_STATE,
TEST_CONFIG_REMOVE_HOLIDAY,
Expand All @@ -51,6 +52,7 @@
(TEST_CONFIG_TOMORROW, "off"),
(TEST_CONFIG_DAY_AFTER_TOMORROW, "off"),
(TEST_CONFIG_YESTERDAY, "on"),
(TEST_CONFIG_NO_LANGUAGE_CONFIGURED, "off"),
],
)
async def test_setup(
Expand Down

0 comments on commit 8e71086

Please sign in to comment.