->schema([
Forms\Components\Repeater::make('items')
->relationship()
->schema([
Forms\Components\Select::make('expense_category_id')
->label('Category')
->options(
ExpenseCategory::query()
->pluck('name', 'id')
)
->required()
->distinct()
->disableOptionsWhenSelectedInSiblingRepeaterItems()
->searchable(),
Forms\Components\TextInput::make('unit_price')
->label('Unit Price')
->mask(RawJs::make('$money($input)'))
->stripCharacters(',')
->numeric()
->inputMode('decimal')
->required()
])
->live(debounce: 500)
->afterStateUpdated(
fn(Forms\Set $set, Forms\Get $get) =>
$set(
'total_amount',
round(collect($get('items'))
->sum(
fn($item)
=> (float) str_replace(',', '', $item['unit_price'] ?? 0)
), 2)
)
)
Forms\Components\TextInput::make('total_amount')
->label('Total')
->mask(RawJs::make('$money($input)'))
->numeric()
->reactive()
->inputMode('decimal')
->readOnly()
->required()
->dehydrateStateUsing(
fn($state) => (float) str_replace(',', '', $state)
)
->schema([
Forms\Components\Repeater::make('items')
->relationship()
->schema([
Forms\Components\Select::make('expense_category_id')
->label('Category')
->options(
ExpenseCategory::query()
->pluck('name', 'id')
)
->required()
->distinct()
->disableOptionsWhenSelectedInSiblingRepeaterItems()
->searchable(),
Forms\Components\TextInput::make('unit_price')
->label('Unit Price')
->mask(RawJs::make('$money($input)'))
->stripCharacters(',')
->numeric()
->inputMode('decimal')
->required()
])
->live(debounce: 500)
->afterStateUpdated(
fn(Forms\Set $set, Forms\Get $get) =>
$set(
'total_amount',
round(collect($get('items'))
->sum(
fn($item)
=> (float) str_replace(',', '', $item['unit_price'] ?? 0)
), 2)
)
)
Forms\Components\TextInput::make('total_amount')
->label('Total')
->mask(RawJs::make('$money($input)'))
->numeric()
->reactive()
->inputMode('decimal')
->readOnly()
->required()
->dehydrateStateUsing(
fn($state) => (float) str_replace(',', '', $state)
)