mirror of
https://github.com/kuhyx/testsAndMisc-archive.git
synced 2026-11-11 13:07:35 +01:00
Last of the four drifted apps. The theme was ColorScheme.fromSeed(teal) plus fifteen ad hoc colour literals that mostly bypassed it -- not one widget outside main.dart read colorScheme at all, so the seed barely affected what you saw. It now uses design_system-v0.1.0's buildLightTheme(), and the literals that have a real theme role read it off the scheme. Light, not dark, deliberately: the receipt screens carry black-on-white helper text, so inverting brightness would make it unreadable. The Colors.black54 sites are exactly those, now onSurfaceVariant. The error family maps cleanly -- Colors.red to error, red.shade50 to errorContainer with onErrorContainer text on it, and the swipe-to-delete background+icon to error/onError so the fill and the glyph drawn on it cannot drift apart. The four category dots (deepOrange/amber/blueGrey/teal) stay literals, with a comment saying why: they encode which category an item is, not a theme role, and a single-accent system has no four distinct hues to lend them. Mapping them onto primary/secondary/tertiary would make the categories stop being distinguishable, which is their only job. They are tracked in nielsen-audit.md as needing a categorical ramp. Note this decouples the default dot from the old seed -- both were Colors.teal, so they used to match by coincidence rather than by design. Verified: 60/60 tests, 100% line coverage across 11 lib files, analyze clean apart from four pre-existing unnecessary_unawaited infos. A temporary assertion pumped the real app and read primary=ffb8862e and surface=fff6f4f3 off a live Scaffold, confirming the palette changed rather than merely compiling. Colour literals: 15 -> 4. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XS1m7b1piBtAL22USLW6jL |
||
|---|---|---|
| .. | ||
| android | ||
| assets/icon | ||
| ios | ||
| lib | ||
| linux | ||
| macos | ||
| test | ||
| windows | ||
| .gitignore | ||
| .metadata | ||
| analysis_options.yaml | ||
| pubspec.lock | ||
| pubspec.yaml | ||
| README.md | ||
BillSplit
Flutter app (mobile + desktop) for splitting shop receipts between people — including the drinkers vs non-drinkers case — with Biedronka e-paragon import and .xlsx export.
Features
- People roster with a per-person drinks alcohol toggle, plus arbitrary groups (tags) like "meat eaters".
- Receipts: import a Polish fiscal e-receipt JSON (
e-paragon, JPK_KASA_PARAGON_v2-0 — the file the Biedronka app exports; the embedded JWS payload is decoded, signature not verified) or build one manually. Multiple receipts persist locally (state.jsonin app documents). - Per-item assignment: each item is split among Everyone / Drinkers / Non-drinkers / a group / hand-picked people. Alcohol is auto-detected on import (wódka/piwo/wino/… keywords) and defaults to drinkers only; deposits (kaucja) become their own line split among everyone. Category and assignment are always editable — the keyword detection is a default, not a decision.
- Grosz-exact math: every item's shares sum to exactly the item total (largest-remainder distribution), so per-person totals reconcile with the receipt to the grosz — no floating point drift.
- Totals view: per person, with alcohol / rest breakdown, unassigned-item warnings, and a reconciliation check against the paid amount.
- Export .xlsx: one row per item with a 1/0 person matrix plus a summary — same layout as the hand-made spreadsheet this app grew out of. Matrix and summary are exported values (the app is the calculator); column totals are live SUM formulas.
Running
The repo ships lib/, test/, and pubspec.yaml without platform runner
folders. Generate them once for the platforms you want:
cd billsplit
flutter create . --platforms=linux,windows,macos,android,ios
flutter pub get
flutter run # picks a connected device / desktop
Tested with Flutter 3.44.8 / Dart 3.10.
Tests
flutter test
Covers: parsing the real sample receipt in test/fixtures/ (49 items +
deposit, totals 590.55 + 7.00 = 597.55 zł), split invariants incl. a 500-case
fuzz of the remainder distribution, assignment-mode resolution, and xlsx
generation (the test writes build/test_export.xlsx for external inspection).
Design notes / edge cases
- Money is
intgrosze end to end; formatting happens only at the UI edge. - An item resolving to zero people (e.g. "non-drinkers" on an all-drinker receipt) is excluded from totals and loudly flagged, never silently dropped into someone's bill.
- Deleting a person prunes them from groups, receipt participants and custom assignments; deleting a group falls back affected items to Everyone.
- Assignment modes are stored symbolically (not as materialized ID sets), so adding a person later automatically includes them in Everyone items. Touching a person checkbox materializes the current set and switches the item to custom.
paidTotalGr(what the card was charged) is kept separately from the item sum; a mismatch shows red in Totals instead of being "fixed" silently.
Quality gates (enforced in CI)
dart format --set-exit-if-changed .— formatting is canonicalflutter analyze --fatal-infos—very_good_analysis+strict-casts,strict-inference,strict-raw-types; any info fails the buildflutter test --coverage+tool/coverage_check.py— 100% line coverage oflib/is mandatory; the gate also fails if a lib file is never executed by any test