Page - Bill Splitter

Screen: AppRoute.billSplit File: Utiliship/Features/BillSplit/BillSplitView.swift ViewModel: Utiliship/Features/BillSplit/BillSplitViewModel.swift Use Case: Utiliship/Features/BillSplit/DefaultBillSplitUseCase.swift

Purpose

Three-step wizard for splitting a restaurant bill among any number of participants. Step 1 (Setup): add participants and configure service charge / VAT. Step 2 (Items): add line items and assign each to one or more people. Step 3 (Result): view per-person totals with configurable rounding, and share as text. Completed bills are auto-saved to history.

Component Tree

BillSplitView
└── switch state.currentStep
    ├── .setup  → BillSetupView
    │   ├── participantsList   — ForEach state.participants → ParticipantRow
    │   ├── addParticipantRow  — shown when state.isAddingParticipant
    │   ├── chargesSection     — service charge + VAT fields (BillCharges)
    │   └── nextButton         — enabled when state.canProceedToItems
    │
    ├── .items  → BillItemsView
    │   ├── itemsList          — ForEach state.items → BillItemRow
    │   │   └── participantToggleRow per participant
    │   ├── subtotalSummary    — state.itemsSubtotal
    │   └── calculateButton    — enabled when state.canCalculate
    │
    └── .result → BillResultView
        ├── perPersonSection   — ForEach calculation.perPersonAmounts
        ├── roundingPicker     — state.roundingRule
        ├── shareButton        — useCase.generateShareableText
        └── resetButton        — viewModel.reset()

ViewModel State

FieldTypeDescription
currencySymbolStringSymbol from SettingsStore.preferredCurrency (default "฿")
currentStepWizardStep.setup, .items, or .result
participants[BillParticipant]People in the bill; always starts with .defaultMe
chargesBillChargesService charge percentage + VAT
items[BillItem]Line items, each with participantIds: Set<UUID>
calculationBillSplitCalculation?Result from DefaultBillSplitUseCase.calculateSplit
roundingRuleRoundingRule.nearest1 default; changing it triggers recalculate
isAddingParticipantBoolShows inline add-participant form
isAddingItemBoolShows inline add-item form
editingParticipantBillParticipant?Currently editing participant
editingItemBillItem?Currently editing item
errorMessageString?Displayed on calculation failure
successMessageString?Shown after loading from history

Data Flow