Skip to content

feat: order history & spending analytics sensors#64

Merged
dvejsada merged 14 commits into
dvejsada:masterfrom
kwaczek:feat/order-history-sensors
Apr 11, 2026
Merged

feat: order history & spending analytics sensors#64
dvejsada merged 14 commits into
dvejsada:masterfrom
kwaczek:feat/order-history-sensors

Conversation

@kwaczek
Copy link
Copy Markdown

@kwaczek kwaczek commented Feb 26, 2026

Summary

  • Order History Storage: Persistent JSON-based OrderStore with paginated API fetch for full order history backfill
  • Spending Analytics Sensors: 10 new sensors for category spending (L0–L3) and per-item spending, each with "this year" and "all time" variants
  • Config Flow: Two-step wizard (login → analytics) with opt-in checkboxes for analytics levels, configurable top N items (default 10), and hide discontinued products toggle
  • Options Flow: All analytics settings reconfigurable on existing entries via the Configure button
  • Background Processing: Full order history download and enrichment runs in the background without blocking the config flow
  • Localized Notifications: Progress notifications during enrichment in EN/CS based on HA language setting

Test plan

  • Production deployment tested with 484 orders
  • Fresh Docker HA instance: full wizard flow (login → analytics → completion) works end-to-end
  • Options flow: changing top N and hide discontinued works on existing entries
  • Sensors correctly display top N items with total_count attribute
  • Discontinued products excluded when hide option is enabled
  • Background history fetch completes without blocking UI
  • Verify on clean install without analytics enabled (base sensors only)

🤖 Generated with Claude Code

mirobotur and others added 10 commits February 26, 2026 12:27
Adds yearly and all-time spending sensors with local JSON storage
for order history. Phase 1 of the order analytics feature.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7 bite-sized tasks: API pagination, OrderStore, sensors, service, translations, tests, deploy.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add opt-in spending analytics with category breakdown sensors (L0-L3)
and per-item spending sensors. Users can configure analytics levels,
top N items to display (default 10), and hide discontinued products
via the config flow wizard and options flow. Full order history is
fetched in the background when analytics is enabled.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kwaczek kwaczek changed the title feat: add yearly and all-time spending sensors with order history storage feat: order history & spending analytics sensors Feb 27, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dvejsada
Copy link
Copy Markdown
Owner

@kwaczek Thank you for this PR. However, please kindly add to make this (i.e. total history fetching and analytics) optional in the config with default being off - I would presume that may people (and I am one of them) do not want this kind of details to be fetched and stored in HA, incl. all history.

@kwaczek
Copy link
Copy Markdown
Author

kwaczek commented Feb 28, 2026

@dvejsada It is optional during the wizard and turned off by default. Spin off a new HA in docker and check the wizard

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces persistent order-history storage and opt-in spending analytics for the Rohlik.cz Home Assistant integration, including a two-step config flow/options flow and background backfill/enrichment with localized progress notifications.

Changes:

  • Added JSON-backed OrderStore with order backfill + item/category enrichment paths and new related services.
  • Added opt-in analytics sensors (yearly/all-time totals, category L0–L3, per-item) gated by config/options.
  • Updated config flow/options flow, translations, and documentation to support analytics settings and usage.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
custom_components/rohlikcz/hub.py Adds OrderStore, enrichment logic, background enrichment scheduling, and localized notifications.
custom_components/rohlikcz/rohlik_api.py Adds pagination + order detail/category fetch + enrichment helper methods.
custom_components/rohlikcz/sensor.py Adds analytics sensors and gates them based on selected options.
custom_components/rohlikcz/config_flow.py Implements 2-step config flow (login → analytics) and OptionsFlow for analytics settings.
custom_components/rohlikcz/__init__.py Passes options into hub, adds migration + reload listener, schedules background history fetch.
custom_components/rohlikcz/const.py Adds icons, analytics option constants, and new service constant(s).
custom_components/rohlikcz/services.py Registers fetch_order_history and enrich_orders services.
custom_components/rohlikcz/services.yaml Documents new services for HA service UI.
custom_components/rohlikcz/translations/en.json Adds analytics step/options UI strings and new entity translation keys.
custom_components/rohlikcz/translations/cs.json Adds analytics step/options UI strings and new entity translation keys (Czech).
custom_components/rohlikcz/manifest.json Bumps integration version to 0.4.0.
tests/test_order_store.py Adds a standalone test script for basic store/dedup/aggregation behavior.
readme.md Documents analytics setup, sensor list, and new backfill action.
docs/plans/2026-02-26-order-history-sensors.md Implementation plan documentation for order history sensors.
docs/plans/2026-02-26-order-history-sensors-design.md Design doc for order history sensors.
docs/plans/2026-02-26-config-flow-analytics-options.md Implementation plan for analytics config/options flow.
docs/plans/2026-02-26-category-item-analytics.md Implementation plan for category/item analytics enrichment + sensors.
Comments suppressed due to low confidence (1)

custom_components/rohlikcz/services.py:176

  • register_services(hass) is called from async_setup_entry, and the integration now reloads entries when options change. Since register_services unconditionally calls hass.services.async_register(...), a reload will attempt to re-register the same services in the same HA runtime (potentially raising and breaking reload). Make service registration idempotent (e.g., check hass.services.has_service(DOMAIN, ...) / store a flag in hass.data) or register/unregister services in a way that is safe across reloads.
    # Register the services
    hass.services.async_register(
        DOMAIN,
        SERVICE_ADD_TO_CART,
        async_add_to_cart_service,
        schema=vol.Schema({
            vol.Required(ATTR_CONFIG_ENTRY_ID): cv.string,
            vol.Required(ATTR_PRODUCT_ID): cv.positive_int,
            vol.Required(ATTR_QUANTITY, default=1): cv.positive_int,
        }),
        supports_response=True
    )


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread custom_components/rohlikcz/hub.py
Comment thread custom_components/rohlikcz/__init__.py
Comment thread custom_components/rohlikcz/hub.py
Comment thread custom_components/rohlikcz/translations/en.json
Comment thread custom_components/rohlikcz/translations/cs.json
Comment thread custom_components/rohlikcz/sensor.py
Comment on lines +844 to +854
year = datetime.now(ZoneInfo("Europe/Prague")).strftime("%Y")
categories = store.category_totals(year=year, level=0, hide_discontinued=self._rohlik_account.hide_discontinued)
if not categories:
return {"year": year, "enriched_orders": store.enriched_count, "total_orders": store.yearly_count(year)}
return {
"year": year,
"total_count": len(categories),
"categories": categories[:self._rohlik_account.top_n],
"enriched_orders": store.enriched_count,
"total_orders": store.yearly_count(year),
}
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the yearly L0 category sensor, total_orders is filtered to the current year (store.yearly_count(year)), but enriched_orders uses store.enriched_count (all-time). This makes the attributes inconsistent/misleading for “this year”. Consider computing an enriched-order count filtered by the same year.

Copilot uses AI. Check for mistakes.
Comment thread custom_components/rohlikcz/sensor.py
Comment thread custom_components/rohlikcz/sensor.py
Comment thread tests/test_order_store.py Outdated
dvejsada and others added 2 commits April 11, 2026 14:55
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@dvejsada dvejsada merged commit 31293ea into dvejsada:master Apr 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants