schema([ Section::make([ Grid::make(2) ->schema([ Select::make('customer_id') ->required() ->label('Customer') ->options(Customer::all()->pluck('company_name', 'id')) ->reactive() ->searchable() ->disabledOn('edit') ->columnSpan(2), Split::make([ DatePicker::make('date') ->required() ->default(today()), DatePicker::make('due_date'), ]) ->columnSpan(2), Select::make('status') ->options(InvoiceStatus::class) ->searchable() ->required() ->default(InvoiceStatus::UNPAID), ])->columnSpan(2), Grid::make(1) ->schema([ ToggleButtons::make('gst') ->boolean() ->default(true) ->inline() ->colors([ 'true' => 'info', 'false' => 'info', ]), ToggleButtons::make('pst') ->boolean() ->default(false) ->inline() ->colors([ 'true' => 'info', 'false' => 'info', ]), ])->columnSpan(1), ]) ->columns(3) ->columnSpan(3), ])->columns(3); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('internal_id') ->label('ID') ->fontFamily('mono') ->color('primary') ->sortable() ->searchable(), Tables\Columns\TextColumn::make('customer.company_name') ->sortable() ->extraHeaderAttributes(['class' => 'w-full']) ->searchable(), Tables\Columns\TextColumn::make('status') ->badge(InvoiceStatus::class) ->sortable(), Tables\Columns\TextColumn::make('created_at') ->label('Created') ->date() ->sortable(), Tables\Columns\TextColumn::make('subtotal') ->money('USD') ->alignRight(), Tables\Columns\TextColumn::make('gst_amount') ->label('GST') ->money('USD') ->alignRight(), Tables\Columns\TextColumn::make('pst_amount') ->label('PST') ->formatStateUsing(function ($state) { return $state == 0.00 ? '-' : '$'.$state; }) ->alignRight(), Tables\Columns\TextColumn::make('total') ->money('USD') ->weight('bold') ->alignRight(), ]) ->filters([ Tables\Filters\Filter::make('created_at') ->form([ Split::make([ DatePicker::make('created_from') ->label('From date'), DatePicker::make('created_until') ->label('Until date'), ]), ]) ->query(function (Builder $query, array $data): Builder { return $query ->when( $data['created_from'], fn (Builder $query, $date): Builder => $query->whereDate('date', '>=', $date), ) ->when( $data['created_until'], fn (Builder $query, $date): Builder => $query->whereDate('date', '<=', $date), ); }), Tables\Filters\SelectFilter::make('status') ->options(InvoiceStatus::class) ->columnSpan(1), ], layout: Tables\Enums\FiltersLayout::AboveContentCollapsible) ->filtersFormColumns(3) ->groups([ 'status', ]) ->defaultSort('created_at', 'desc') ->actions([ Tables\Actions\EditAction::make(), //todo: generate report pdf ]) ->bulkActions([ Tables\Actions\BulkAction::make('Mark as paid') ->action(function (Collection $records) { $records->each->setStatus(InvoiceStatus::PAID); Notification::make() ->title(count($records).' item(s) saved successfully') ->success() ->send(); }) ->icon('lucide-circle-check') ->deselectRecordsAfterCompletion(), Tables\Actions\BulkActionGroup::make([ Tables\Actions\BulkAction::make('Mark as unpaid') ->action(function (Collection $records) { $records->each->setStatus(InvoiceStatus::UNPAID); Notification::make() ->title(count($records).' item(s) saved successfully') ->success() ->send(); }) ->icon('lucide-circle-x') ->deselectRecordsAfterCompletion(), Tables\Actions\DeleteBulkAction::make(), ]) ->label('Other actions'), ]) ->selectCurrentPageOnly(); } public static function getRelations(): array { return [ OrdersRelationManager::class, ProductServicesRelationManager::class, ]; } public static function getPages(): array { return [ 'index' => Pages\ListInvoices::route('/'), 'create' => Pages\CreateInvoice::route('/create'), 'edit' => Pages\EditInvoice::route('/{record}/edit'), ]; } }