Skip to content

Publish the Rohlík Group shops; add cart currency and minimum order value (v0.3.0) - #11

Merged
dvejsada merged 3 commits into
mainfrom
claude/ha-integration-open-issues-1hg1fx
Sep 27, 2026
Merged

dvejsada merged 3 commits into
mainfrom
claude/ha-integration-open-issues-1hg1fx

Conversation

@dvejsada

Copy link
Copy Markdown
Owner

Closes #9. Closes #10.

Why

Every Rohlík Group shop runs the same API, and RohlikAPI already accepted a base_url. Even so, each consumer had to know the other shops' URLs itself, and the models described every amount as CZK. The Home Assistant integration just added shop selection (dvejsada/HA-RohlikCZ#92) and keeps its own copy of the shop table; it can use this one once it ships. Separately, the cart response contains the minimum order value, but Cart.from_api dropped it (#9).

Changes

Verified against live responses

I added an item to an anonymous (logged-out) cart on knuspr.de and on rohlik.cz:

  • Cart items report "currency": "EUR" and "CZK" respectively.
  • minimalOrderPrice is present at the top level of data (along with minimalStandardOrderPrice and minimalDeliveryPointOrderPrice), but it is 0 on an anonymous cart.

The value on a logged-in cart is not yet confirmed. The docstring states this.

Testing

  • ruff check ., black --check . and mypy rohlik_api pass.
  • pytest: 152 passed.
  • New tests:
    • tests/test_sites.py: presets are well formed, cz matches BASE_URL, the names are exported, and the client targets the chosen shop.
    • A cart test built from the real Knuspr.de payload shape, covering the currency and minimum order price.

🤖 Generated with Claude Code

https://claude.ai/code/session_0135WLPbnfESWnAJmw4P8uRH


Generated by Claude Code

…alue

Every Rohlík Group shop runs the same API, and RohlikAPI already took a
base_url, but consumers each had to know the other shops' URLs themselves
and the models documented every amount as CZK.

- New rohlik_api.SITES / Site: code, name, base_url, currency and timezone
  for Rohlík.cz, Knuspr.de, Gurkerl.at, Kifli.hu and Sezamo.ro (#10).
- CartItem.currency from each item's ISO currency code, and Cart.currency
  from its items (the cart payload itself has none; None for an empty
  cart) (#10).
- Cart.minimum_order_price from minimalOrderPrice, which Cart.from_api used
  to drop (#9). Cart.can_make_order's docstring no longer claims it tracks
  the minimum: submitConditionPassed also needs checkout details.
- Docstrings and README no longer assume CZK / Rohlik.cz only; README
  gains an "Other shops" section.

Checked against live anonymous carts on knuspr.de (currency "EUR") and
rohlik.cz ("CZK"); minimalOrderPrice is present there but 0, so the value
on a logged-in cart is still to be confirmed.

Closes #9
Closes #10

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0135WLPbnfESWnAJmw4P8uRH
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0135WLPbnfESWnAJmw4P8uRH

Copy link
Copy Markdown
Owner Author

@claude review this PR. Focus on correctness bugs, backwards compatibility of the public models (Cart, CartItem) and exports, and whether the typing and docs are accurate.


Generated by Claude Code

@claude

claude Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Claude finished @dvejsada's task in 1m 54s —— View job


Reviewing PR #11

  • Gather context (PR diff, CLAUDE.md, changed files)
  • Review rohlik_api/sites.py and SITES/Site export
  • Review rohlik_api/models.py changes (Cart, CartItem)
  • Review rohlik_api/client.py and http_client.py changes
  • Check backwards compatibility of public models/exports
  • Check typing and docs accuracy
  • Post final review

Review

Overall this is a clean, well-scoped change. I couldn't find a correctness bug in the new code paths.

Backwards compatibility — looks solid

  • CartItem.currency: str = "" (rohlik_api/models.py:53) and Cart.minimum_order_price / Cart.currency (rohlik_api/models.py:96-97) are appended after all existing fields, each with a default, so positional construction (e.g. by the HA integration) still works.
  • Both CartItem and Cart use @dataclass(slots=True); adding trailing defaulted fields doesn't change slot layout in a way that breaks existing code.
  • SITES["cz"].base_url == BASE_URL (rohlik_api/endpoints.py:7, verified in tests/test_sites.py:12), so the new default-shop preset is consistent with the pre-existing default.
  • New Site/SITES exports are additive to __all__ (rohlik_api/__init__.py:43-44); nothing existing was renamed or removed.

Correctness

  • Cart.currency = next((p.currency for p in products if p.currency), None) (rohlik_api/models.py:111) correctly treats CartItem.currency == "" as "unknown" and skips it, which matches the intent (empty string is the "omitted" sentinel for CartItem, None is the sentinel for Cart).
  • minimum_order_price=data.get("minimalOrderPrice") (rohlik_api/models.py:110) correctly maps absence to None vs. the anonymous-cart 0 value, matching the verified live-response behavior described in the PR body.
  • Site currency/timezone values (rohlik_api/sites.py:37-41) check out: EUR for Knuspr.de/Gurkerl.at, HUF for Kifli.hu, RON for Sezamo.ro, and all five IANA timezone strings are valid.

Minor doc nit (non-blocking)

  • Cart.currency's docstring (rohlik_api/models.py:87-89) says it's None "for an empty cart," but per the implementation it's also None for a non-empty cart whose items all omit currency (e.g. legacy/partial payloads) — the test at tests/test_services.py for the plain get_content case actually exercises exactly this and asserts currency is None with non-empty... actually that test's cart is non-empty with total_items derived from items, so the docstring's "empty cart" framing is slightly narrower than the real behavior. Worth a one-line addition like "...or when no item reports one" for precision. Fix this →

Not verified

  • I was unable to run ruff check ., black --check ., mypy rohlik_api, or pytest in this sandboxed environment — pip install -e ".[dev]" requires approval that isn't available to me here. Based on static reading, the diff's style and typing (str | None, Final[dict[str, Site]], generator default in next(...)) are consistent with the rest of the codebase and the existing mypy strictness, but I'd suggest confirming CI is green before merge.

No blocking issues found. The SITES/Site addition (#10) and Cart.minimum_order_price/currency fields (#9) are implemented and documented as described, and the version bump to 0.3.0 is correctly picked up via dynamic = ["version"] / attr = "rohlik_api.__version__" in pyproject.toml.

@dvejsada
dvejsada merged commit 5291646 into main Sep 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants