This commit is contained in:
salam committed 2025-09-25 14:37:34 +02:00
1 parent 5f95289079
commit 60249dffd9
37 files changed
+411 -457

No files matched your search

+6 -1
View File
@@ -8,5 +8,10 @@ a make:model ModelName -f // also creates a factory
a make:model ModelName -s // also creates a database seeder a make:model ModelName -s // also creates a database seeder
a make:model ModelName -mfcs // creates migration, factory, controller and seeder a make:model ModelName -mfcs // creates migration, factory, controller and seeder
a make:factory GutachterFactory a make:factory GutachterFactory
https://fakerphp.org/
Thomas Schranz
Adamgasse 9a
2.Stock
+32 -86
View File
@@ -7,6 +7,7 @@ use Danielebarbaro\LaravelVatEuValidator\Rules\VatNumber;
use Filament\Auth\Pages\Register as BaseRegister; use Filament\Auth\Pages\Register as BaseRegister;
use Filament\Forms\Components\Checkbox; use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Fieldset; use Filament\Schemas\Components\Fieldset;
use Filament\Schemas\Components\Utilities\Get; use Filament\Schemas\Components\Utilities\Get;
@@ -18,6 +19,8 @@ use Ysfkaya\FilamentPhoneInput\Forms\PhoneInput;
class Register extends BaseRegister class Register extends BaseRegister
{ {
public User $user;
public function form(Schema $schema): Schema public function form(Schema $schema): Schema
{ {
return $schema return $schema
@@ -39,28 +42,35 @@ class Register extends BaseRegister
->description('Mit einem Konto verbinden.') ->description('Mit einem Konto verbinden.')
->schema([ ->schema([
$this->getKontoModusFormComponent(), $this->getKontoModusFormComponent(),
/** OLD */ /** BESTEHENDES KONTO */
$this->getKontoFormComponent(), $this->getKontoFormComponent(),
/** NEU */ /** NEU */
Fieldset::make('Rechnungsdaten') Fieldset::make('Rechnungsdaten')
->visible(fn (Get $get): bool => $get('konto') == 'new') ->visible(fn (Get $get): bool => $get('konto') == 'new')
->schema([ ->schema([
$this->getCompanyFormComponent(), TextInput::make('company')
$this->getUIDFormComponent(), ->label('Firma')
$this->getPLZFormComponent(), ->required(),
$this->getLocationFormComponent(), TextInput::make('uid_number')
$this->getAdresseFormComponent(), ->label('UID Nummer')
$this->getCountryFormComponent(), ->rules([new VatNumber])
->required(),
Textarea::make('address')
->label('Adresse')
->required(),
TextInput::make('country')
->label('Land')
->default('Österreich')
->required(),
])->columnSpan(4), ])->columnSpan(4),
Fieldset::make('Kontaktperson') Fieldset::make('Kontaktperson')
->visible(fn (Get $get): bool => $get('konto') == 'new') ->visible(fn (Get $get): bool => $get('konto') == 'new')
->schema([ ->schema([
$this->getKontoGenderFormComponent(), // $this->getKontoGenderFormComponent(),
$this->getTitleFormComponent(), // $this->getTitleFormComponent(),
$this->getKontoFirstNameFormComponent(), // $this->getNameFormComponent(),
$this->getKontoLastNameFormComponent(), // $this->getKontoEmailFormComponent(),
$this->getKontoEmailFormComponent(), // $this->getPhoneFormComponent(),
$this->getPhoneFormComponent(),
])->columnSpan(4), ])->columnSpan(4),
]), ]),
@@ -72,7 +82,9 @@ class Register extends BaseRegister
Fieldset::make('Bitte lesen und akzeptieren Sie die allgemeinen Geschäftsbedignungen um die Registrierung abzuschließen.') Fieldset::make('Bitte lesen und akzeptieren Sie die allgemeinen Geschäftsbedignungen um die Registrierung abzuschließen.')
->visible(fn (Get $get): bool => $get('konto') == 'new') ->visible(fn (Get $get): bool => $get('konto') == 'new')
->schema([ ->schema([
$this->getABGFormComponent(), Checkbox::make('agb_akzeptiert')
->label('ABG akzeptieren')
->required(),
]), ]),
View::make('pages.agb'), View::make('pages.agb'),
@@ -130,7 +142,7 @@ class Register extends BaseRegister
'Um das erstellte Profil zu aktivieren muß der Kontoinhaber die Anmeldung im Programm freischalten', 'Um das erstellte Profil zu aktivieren muß der Kontoinhaber die Anmeldung im Programm freischalten',
]) ])
->visible(fn (Get $get): bool => $get('konto') == 'old') ->visible(fn (Get $get): bool => $get('konto') == 'old')
->options(Konto::query()->pluck('konto_company', 'id')) ->options(Konto::query()->pluck('company', 'id'))
->searchable() ->searchable()
->required(); ->required();
} }
@@ -138,17 +150,9 @@ class Register extends BaseRegister
/** /**
* KONTO NEU * KONTO NEU
*/ */
protected function getABGFormComponent(): Checkbox
{
return Checkbox::make('konto_agb_akzeptiert')
->label('ABG akzeptieren')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getTitleFormComponent(): TextInput protected function getTitleFormComponent(): TextInput
{ {
return TextInput::make('konto_title') return TextInput::make('title')
->label('Title') ->label('Title')
->visible(fn (Get $get): bool => $get('konto') == 'new') ->visible(fn (Get $get): bool => $get('konto') == 'new')
->required(); ->required();
@@ -156,7 +160,7 @@ class Register extends BaseRegister
protected function getKontoGenderFormComponent(): Select protected function getKontoGenderFormComponent(): Select
{ {
return Select::make('konto_gender') return Select::make('gender')
->columnSpan(2) ->columnSpan(2)
->label('Geschlecht') ->label('Geschlecht')
->visible(fn (Get $get): bool => $get('konto') == 'new') ->visible(fn (Get $get): bool => $get('konto') == 'new')
@@ -168,25 +172,9 @@ class Register extends BaseRegister
->required(); ->required();
} }
protected function getKontoFirstNameFormComponent(): TextInput
{
return TextInput::make('konto_first_name')
->label('Vorname')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getKontoLastNameFormComponent(): TextInput
{
return TextInput::make('konto_last_name')
->label('Nachname')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getCompanyFormComponent(): TextInput protected function getCompanyFormComponent(): TextInput
{ {
return TextInput::make('konto_company') return TextInput::make('konto.company')
->label('Firma') ->label('Firma')
->visible(fn (Get $get): bool => $get('konto') == 'new') ->visible(fn (Get $get): bool => $get('konto') == 'new')
->required(); ->required();
@@ -194,60 +182,18 @@ class Register extends BaseRegister
protected function getKontoEmailFormComponent(): TextInput protected function getKontoEmailFormComponent(): TextInput
{ {
return TextInput::make('konto_email') return TextInput::make('email')
->label('E-Mail') ->label('E-Mail')
->visible(fn (Get $get): bool => $get('konto') == 'new') ->visible(fn (Get $get): bool => $get('konto') == 'new')
->unique(table: Konto::class) ->unique(table: Konto::class)
->required(); ->required();
} }
protected function getAdresseFormComponent(): TextInput
{
return TextInput::make('konto_address')
->label('Adresse')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getLocationFormComponent(): TextInput
{
return TextInput::make('konto_location')
->label('Ort')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getPLZFormComponent(): TextInput
{
return TextInput::make('konto_plz')
->label('Postleitzahl')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getPhoneFormComponent(): PhoneInput protected function getPhoneFormComponent(): PhoneInput
{ {
return PhoneInput::make('konto_phone') return PhoneInput::make('phone')
->label('Telefon') ->label('Telefon')
->visible(fn (Get $get): bool => $get('konto') == 'new') ->visible(fn (Get $get): bool => $get('konto') == 'new')
->defaultCountry('AT'); ->defaultCountry('AT');
} }
protected function getCountryFormComponent(): TextInput
{
return TextInput::make('konto_country')
->label('Land')
->default('Österreich')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->required();
}
protected function getUIDFormComponent(): TextInput
{
return TextInput::make('konto_uid_number')
->label('UID Nummer')
->visible(fn (Get $get): bool => $get('konto') == 'new')
->rules([new VatNumber])
->required();
}
} }
@@ -1,64 +0,0 @@
<?php
namespace App\Filament\Resources\KontoOptions;
use App\Filament\Clusters\Administration\AdministrationCluster;
use App\Filament\Resources\KontoOptions\Pages\CreateKontoOption;
use App\Filament\Resources\KontoOptions\Pages\EditKontoOption;
use App\Filament\Resources\KontoOptions\Pages\ListKontoOptions;
use App\Filament\Resources\KontoOptions\Schemas\KontoOptionForm;
use App\Filament\Resources\KontoOptions\Tables\KontoOptionTable;
use App\Models\KontoOption;
use BackedEnum;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Table;
use UnitEnum;
class KontoOptionResource extends Resource
{
protected static ?string $model = KontoOption::class;
protected static ?string $cluster = AdministrationCluster::class;
protected static string|UnitEnum|null $navigationGroup = 'Kunden';
protected static string|BackedEnum|null $navigationIcon = 'lucide-key-square';
protected static ?string $navigationLabel = 'Konto Optionen';
protected static ?string $modelLabel = 'Konto Option';
protected static ?string $pluralModelLabel = 'Konto Optionen';
public static function form(Schema $schema): Schema
{
return KontoOptionForm::configure($schema);
}
public static function table(Table $table): Table
{
return KontoOptionTable::configure($table);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => ListKontoOptions::route('/'),
'create' => CreateKontoOption::route('/create'),
'edit' => EditKontoOption::route('/{record}/edit'),
];
}
public static function getNavigationBadge(): ?string
{
return parent::getEloquentQuery()->count();
}
}
@@ -1,11 +0,0 @@
<?php
namespace App\Filament\Resources\KontoOptions\Pages;
use App\Filament\Resources\KontoOptions\KontoOptionResource;
use Filament\Resources\Pages\CreateRecord;
class CreateKontoOption extends CreateRecord
{
protected static string $resource = KontoOptionResource::class;
}
@@ -1,19 +0,0 @@
<?php
namespace App\Filament\Resources\KontoOptions\Pages;
use App\Filament\Resources\KontoOptions\KontoOptionResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditKontoOption extends EditRecord
{
protected static string $resource = KontoOptionResource::class;
protected function getHeaderActions(): array
{
return [
DeleteAction::make(),
];
}
}
@@ -1,19 +0,0 @@
<?php
namespace App\Filament\Resources\KontoOptions\Pages;
use App\Filament\Resources\KontoOptions\KontoOptionResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListKontoOptions extends ListRecords
{
protected static string $resource = KontoOptionResource::class;
protected function getHeaderActions(): array
{
return [
// CreateAction::make(),
];
}
}
@@ -15,37 +15,37 @@ class KontoForm
{ {
return $schema return $schema
->components([ ->components([
TextInput::make('konto_company') TextInput::make('company')
->label('Firma') ->label('Firma')
->required(), ->required(),
TextInput::make('konto_email') TextInput::make('email')
->label('E-Mail') ->label('E-Mail')
->unique(table: Konto::class) ->unique(table: Konto::class)
->required(), ->required(),
TextInput::make('konto_address') TextInput::make('address')
->label('Adresse') ->label('Adresse')
->required(), ->required(),
TextInput::make('konto_location') TextInput::make('location')
->label('Ort') ->label('Ort')
->required(), ->required(),
TextInput::make('konto_plz') TextInput::make('plz')
->label('Postleitzahl') ->label('Postleitzahl')
->required(), ->required(),
PhoneInput::make('konto_phone') PhoneInput::make('phone')
->label('Telefon') ->label('Telefon')
->defaultCountry('AT'), ->defaultCountry('AT'),
TextInput::make('konto_country') TextInput::make('country')
->label('Land') ->label('Land')
->default('Österreich') ->default('Österreich')
->required(), ->required(),
TextInput::make('konto_uid_number') TextInput::make('uid_number')
->label('UID Nummer') ->label('UID Nummer')
->rules([new VatNumber]) ->rules([new VatNumber])
->required(), ->required(),
TextInput::make('konto_title') TextInput::make('title')
->label('Title') ->label('Title')
->required(), ->required(),
Select::make('konto_gender') Select::make('gender')
->label('Geschlecht') ->label('Geschlecht')
->options([ ->options([
'Herr' => 'Herr', 'Herr' => 'Herr',
@@ -53,11 +53,8 @@ class KontoForm
'Non-binary' => 'Non-binary', 'Non-binary' => 'Non-binary',
]) ])
->required(), ->required(),
TextInput::make('konto_first_name') TextInput::make('name')
->label('Vorname') ->label('Name')
->required(),
TextInput::make('konto_last_name')
->label('Nachname')
->required(), ->required(),
]); ]);
} }
@@ -23,42 +23,42 @@ class KontosTable
return $table return $table
->columns([ ->columns([
// TextColumn::make('id'), // TextColumn::make('id'),
// TextColumn::make('konto_gender')->label('Geschlecht'), // TextColumn::make('gender')->label('Geschlecht'),
// TextColumn::make('konto_title')->label('Title'), // TextColumn::make('title')->label('Title'),
// TextColumn::make('konto_first_name')->label('Vorname'), // TextColumn::make('first_name')->label('Vorname'),
// IconColumn::make('konto_agb_akzeptiert') // IconColumn::make('agb_akzeptiert')
// ->label('AGB') // ->label('AGB')
// ->boolean() // ->boolean()
// ->trueIcon(Heroicon::OutlinedCheckBadge) // ->trueIcon(Heroicon::OutlinedCheckBadge)
// ->falseIcon(Heroicon::OutlinedXMark), // ->falseIcon(Heroicon::OutlinedXMark),
// PhoneColumn::make('konto_phone') // PhoneColumn::make('phone')
// ->label('Telefon') // ->label('Telefon')
// ->displayFormat(PhoneInputNumberType::INTERNATIONAL), // ->displayFormat(PhoneInputNumberType::INTERNATIONAL),
// TextColumn::make('konto_email') // TextColumn::make('email')
// ->copyable() // ->copyable()
// ->copyMessage('E-Mail wurde kopiert') // ->copyMessage('E-Mail wurde kopiert')
// ->copyMessageDuration(1500) // ->copyMessageDuration(1500)
// ->label('E-mail'), // ->label('E-mail'),
TextColumn::make('konto_company')->label('Firma') TextColumn::make('company')->label('Firma')
->description(fn ($record): string => $record->konto_address.', '.$record->konto_location), ->description(fn ($record): string => $record->address.', '.$record->location),
TextColumn::make('konto_option.name') TextColumn::make('option.name')
->icon(Heroicon::CurrencyEuro) ->icon(Heroicon::CurrencyEuro)
// ->iconColor('success') // ->iconColor('success')
// ->badge() // ->badge()
->label('Plan') ->label('Plan')
->description(fn ($record): string => $record->konto_option->payment_plan->name), ->description(fn ($record): string => $record->option->payment_plan->name),
TextColumn::make('konto_gutachten_abgeschlossen') TextColumn::make('gutachten_abgeschlossen')
->size(TextSize::Large) ->size(TextSize::Large)
->weight(FontWeight::Bold) ->weight(FontWeight::Bold)
->label('Abgeschlossen') ->label('Abgeschlossen')
->color('primary') ->color('primary')
->description('Gutachten') ->description('Gutachten')
->alignCenter(), ->alignCenter(),
TextColumn::make('konto_gutachten_zahl') TextColumn::make('gutachten_zahl')
->size(TextSize::Large) ->size(TextSize::Large)
->weight(FontWeight::Bold) ->weight(FontWeight::Bold)
->label('Freigeschalted') ->label('Freigeschalted')
@@ -27,9 +27,9 @@ class PermissionResource extends Resource
protected static ?string $recordTitleAttribute = 'name'; protected static ?string $recordTitleAttribute = 'name';
protected static ?string $navigationLabel = 'Berechtigungen'; protected static ?string $navigationLabel = 'Berechtigung';
protected static ?string $modelLabel = 'Berechtigungen'; protected static ?string $modelLabel = 'Berechtigung';
protected static ?string $pluralModelLabel = 'Berechtigungen'; protected static ?string $pluralModelLabel = 'Berechtigungen';
@@ -0,0 +1,11 @@
<?php
namespace App\Filament\Resources\Plans\Pages;
use App\Filament\Resources\Plans\PlanResource;
use Filament\Resources\Pages\CreateRecord;
class CreatePlan extends CreateRecord
{
protected static string $resource = PlanResource::class;
}
@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Plans\Pages;
use App\Filament\Resources\Plans\PlanResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditPlan extends EditRecord
{
protected static string $resource = PlanResource::class;
protected function getHeaderActions(): array
{
return [
DeleteAction::make(),
];
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Plans\Pages;
use App\Filament\Resources\Plans\PlanResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListPlans extends ListRecords
{
protected static string $resource = PlanResource::class;
protected function getHeaderActions(): array
{
return [
CreateAction::make(),
];
}
}
@@ -0,0 +1,64 @@
<?php
namespace App\Filament\Resources\Plans;
use App\Filament\Clusters\Administration\AdministrationCluster;
use App\Filament\Resources\Plans\Pages\CreatePlan;
use App\Filament\Resources\Plans\Pages\EditPlan;
use App\Filament\Resources\Plans\Pages\ListPlans;
use App\Filament\Resources\Plans\Schemas\PlanForm;
use App\Filament\Resources\Plans\Tables\PlansTable;
use App\Models\Plan;
use BackedEnum;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Table;
use UnitEnum;
class PlanResource extends Resource
{
protected static ?string $model = Plan::class;
protected static string|BackedEnum|null $navigationIcon = 'lucide-key-square';
protected static ?string $cluster = AdministrationCluster::class;
protected static string|UnitEnum|null $navigationGroup = 'Kunden';
protected static ?string $navigationLabel = 'Zahlungsplan';
protected static ?string $modelLabel = 'Zahlungsplan';
protected static ?string $pluralModelLabel = 'Zahlungspläne';
public static function form(Schema $schema): Schema
{
return PlanForm::configure($schema);
}
public static function table(Table $table): Table
{
return PlansTable::configure($table);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => ListPlans::route('/'),
'create' => CreatePlan::route('/create'),
'edit' => EditPlan::route('/{record}/edit'),
];
}
public static function getNavigationBadge(): ?string
{
return parent::getEloquentQuery()->count();
}
}
@@ -1,10 +1,10 @@
<?php <?php
namespace App\Filament\Resources\KontoOptions\Schemas; namespace App\Filament\Resources\Plans\Schemas;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
class KontoOptionForm class PlanForm
{ {
public static function configure(Schema $schema): Schema public static function configure(Schema $schema): Schema
{ {
@@ -1,26 +1,19 @@
<?php <?php
namespace App\Filament\Resources\KontoOptions\Tables; namespace App\Filament\Resources\Plans\Tables;
use Filament\Actions\BulkActionGroup; use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction; use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction; use Filament\Actions\EditAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table; use Filament\Tables\Table;
class KontoOptionTable class PlansTable
{ {
public static function configure(Table $table): Table public static function configure(Table $table): Table
{ {
return $table return $table
->columns([ ->columns([
TextColumn::make('name') //
->description(fn ($record): string => $record->description)
->wrap(),
TextColumn::make('payment_plan.name')
->label('Zahlung'),
TextColumn::make('number_user')->alignCenter()->badge()->label('Benutzer'),
TextColumn::make('number_gutachter')->alignCenter()->badge()->label('Gutachter'),
]) ])
->filters([ ->filters([
// //
@@ -13,7 +13,12 @@ class ListUsers extends ListRecords
protected function getHeaderActions(): array protected function getHeaderActions(): array
{ {
return [ return [
CreateAction::make(), CreateAction::make()
->mutateDataUsing(function (array $data): array {
$data['konto_id'] = auth()->user()->konto_id;
return $data;
}),
]; ];
} }
} }
@@ -2,22 +2,55 @@
namespace App\Filament\Resources\Users\Schemas; namespace App\Filament\Resources\Users\Schemas;
use App\Models\User;
use Filament\Forms\Components\Select; use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Illuminate\Validation\Rules\Password;
class UserForm class UserForm
{ {
public User $user;
public static function configure(Schema $schema): Schema public static function configure(Schema $schema): Schema
{ {
return $schema return $schema
->components([ ->components([
TextInput::make('name'), Section::make('Benutzerkonto')
->icon('lucide-user')
->schema([
TextInput::make('name')->required(),
TextInput::make('email')->email()
->required()
->label('E-Mail'),
]),
Section::make('Sicherheit')
->icon('lucide-lock')
->schema([
TextInput::make('password')
->label('Passwort')
->password() // Masks the input
->required()
->revealable()
->rule(Password::min(8)->mixedCase()->numbers()->symbols()->uncompromised()) // Enforces strong password policies
->dehydrateStateUsing(fn ($state) => bcrypt($state)) // Hashes the password before saving
->label('Password'),
TextInput::make('password_confirmation')
->password() // Masks the input
->required()
->same('password') // Validates that this matches the 'password' field
->label('Passwort Bestätigen'),
]),
Select::make('roles') Select::make('roles')
->label('Rolle')
->visible(fn () => auth()->user()->hasRole('super_admin'))
->relationship('roles', 'name') ->relationship('roles', 'name')
->multiple() ->multiple()
->preload() ->preload()
->searchable(), ->searchable(),
]); ])->columns(1);
} }
} }
@@ -18,10 +18,12 @@ class UsersTable
return $table return $table
->columns([ ->columns([
TextColumn::make('name'), TextColumn::make('name'),
TextColumn::make('konto.company')->badge(),
TextColumn::make('email')->copyable()->label('E-Mail'),
// //
]) ])
->filters([ ->filters([
TrashedFilter::make(), TrashedFilter::make()->visible(fn () => auth()->user()->hasRole('super_admin')),
]) ])
->recordActions([ ->recordActions([
EditAction::make(), EditAction::make(),
@@ -31,7 +33,7 @@ class UsersTable
DeleteBulkAction::make(), DeleteBulkAction::make(),
ForceDeleteBulkAction::make(), ForceDeleteBulkAction::make(),
RestoreBulkAction::make(), RestoreBulkAction::make(),
]), ])->visible(fn () => auth()->user()->hasRole('super_admin')),
]); ]);
} }
} }
@@ -3,8 +3,6 @@
namespace App\Filament\Resources\Users; namespace App\Filament\Resources\Users;
use App\Filament\Clusters\Verwaltung\VerwaltungCluster; use App\Filament\Clusters\Verwaltung\VerwaltungCluster;
use App\Filament\Resources\Users\Pages\CreateUser;
use App\Filament\Resources\Users\Pages\EditUser;
use App\Filament\Resources\Users\Pages\ListUsers; use App\Filament\Resources\Users\Pages\ListUsers;
use App\Filament\Resources\Users\Schemas\UserForm; use App\Filament\Resources\Users\Schemas\UserForm;
use App\Filament\Resources\Users\Tables\UsersTable; use App\Filament\Resources\Users\Tables\UsersTable;
@@ -57,8 +55,6 @@ class UserResource extends Resource
{ {
return [ return [
'index' => ListUsers::route('/'), 'index' => ListUsers::route('/'),
'create' => CreateUser::route('/create'),
'edit' => EditUser::route('/{record}/edit'),
]; ];
} }
+1 -1
View File
@@ -12,7 +12,7 @@ class KontoSwitch extends Component
public function mount() public function mount()
{ {
$this->kontos = Konto::pluck('konto_company', 'id')->all(); $this->kontos = Konto::pluck('company', 'id')->all();
} }
public function render() public function render()
+2 -2
View File
@@ -40,8 +40,8 @@ class Konto extends Model
return KontoFactory::new(); return KontoFactory::new();
} }
public function konto_option(): HasOne public function plan(): HasOne
{ {
return $this->hasOne(KontoOption::class, 'id', 'konto_option_id'); return $this->hasOne(Plan::class);
} }
} }
-14
View File
@@ -1,14 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
class KontoOption extends Model
{
public function payment_plan(): HasOne
{
return $this->hasOne(PaymentPlan::class, 'id', 'payment_plan_id');
}
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Plan extends Model
{
//
}
+48 -49
View File
@@ -3,13 +3,16 @@
namespace App\Models; namespace App\Models;
use App\Models\Scopes\KontoScope; use App\Models\Scopes\KontoScope;
use Database\Factories\UserFactory;
use Filament\Auth\MultiFactor\App\Contracts\HasAppAuthentication; use Filament\Auth\MultiFactor\App\Contracts\HasAppAuthentication;
use Filament\Auth\MultiFactor\App\Contracts\HasAppAuthenticationRecovery; use Filament\Auth\MultiFactor\App\Contracts\HasAppAuthenticationRecovery;
use Filament\Auth\MultiFactor\Email\Contracts\HasEmailAuthentication; use Filament\Auth\MultiFactor\Email\Contracts\HasEmailAuthentication;
use Filament\Models\Contracts\FilamentUser; use Filament\Models\Contracts\FilamentUser;
use Filament\Panel; use Filament\Panel;
use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
@@ -32,22 +35,13 @@ class User extends Authenticatable implements FilamentUser, HasAppAuthentication
'email', 'email',
'password', 'password',
'app_verified_at', 'app_verified_at',
'konto_title',
'konto_gender',
'konto_first_name',
'konto_last_name',
'konto_company',
'konto_email',
'konto_address',
'konto_location',
'konto_plz',
'konto_country',
'konto_phone',
'konto_uid_number',
'konto_agb_akzeptiert',
]; ];
protected static function newFactory(): Factory
{
return UserFactory::new();
}
/** /**
* The attributes that should be hidden for serialization. * The attributes that should be hidden for serialization.
* *
@@ -81,45 +75,50 @@ class User extends Authenticatable implements FilamentUser, HasAppAuthentication
{ {
static::addGlobalScope(new KontoScope); static::addGlobalScope(new KontoScope);
static::creating(function (User $user) { // static::creating(function (User $user) {
if (isset($user->konto_title)) { // if (isset($user->konto_title)) {
$konto = Konto::create([ // $konto = Konto::create([
'konto_title' => $user->konto_title, // 'konto_title' => $user->konto_title,
'konto_gender' => $user->konto_gender, // 'konto_gender' => $user->konto_gender,
'konto_company' => $user->konto_company, // 'konto_company' => $user->konto_company,
'konto_uid_number' => $user->konto_uid_number, // 'konto_uid_number' => $user->konto_uid_number,
'konto_location' => $user->konto_location, // 'konto_location' => $user->konto_location,
'konto_plz' => $user->konto_plz, // 'konto_plz' => $user->konto_plz,
'konto_agb_akzeptiert' => $user->konto_agb_akzeptiert, // 'konto_agb_akzeptiert' => $user->konto_agb_akzeptiert,
'konto_country' => $user->konto_country, // 'konto_country' => $user->konto_country,
'konto_address' => $user->konto_address, // 'konto_address' => $user->konto_address,
'konto_first_name' => $user->konto_first_name, // 'konto_first_name' => $user->konto_first_name,
'konto_last_name' => $user->konto_last_name, // 'konto_last_name' => $user->konto_last_name,
'konto_email' => $user->konto_email, // 'konto_email' => $user->konto_email,
'konto_phone' => $user->konto_phone, // 'konto_phone' => $user->konto_phone,
]); // ]);
$user->konto_id = $konto->id; // $user->konto_id = $konto->id;
unset($user->konto_title); // unset($user->konto_title);
unset($user->konto_gender); // unset($user->konto_gender);
unset($user->konto_company); // unset($user->konto_company);
unset($user->konto_uid_number); // unset($user->konto_uid_number);
unset($user->konto_location); // unset($user->konto_location);
unset($user->konto_plz); // unset($user->konto_plz);
unset($user->konto_agb_akzeptiert); // unset($user->konto_agb_akzeptiert);
unset($user->konto_country); // unset($user->konto_country);
unset($user->konto_address); // unset($user->konto_address);
unset($user->konto_first_name); // unset($user->konto_first_name);
unset($user->konto_last_name); // unset($user->konto_last_name);
unset($user->konto_email); // unset($user->konto_email);
unset($user->konto_phone); // unset($user->konto_phone);
// }
// $user->app_verified_at = now();
// $user->email_verified_at = now();
// $user->assignRole('gutachter');
// });
} }
$user->app_verified_at = now();
$user->email_verified_at = now(); public function konto(): HasOne
$user->assignRole('gutachter'); {
}); return $this->hasOne(Konto::class, 'id', 'konto_id');
} }
public function getAppAuthenticationSecret(): ?string public function getAppAuthenticationSecret(): ?string
+70
View File
@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
namespace App\Policies;
use Illuminate\Foundation\Auth\User as AuthUser;
use App\Models\Plan;
use Illuminate\Auth\Access\HandlesAuthorization;
class PlanPolicy
{
use HandlesAuthorization;
public function viewAny(AuthUser $authUser): bool
{
return $authUser->can('ViewAny:Plan');
}
public function view(AuthUser $authUser, Plan $plan): bool
{
return $authUser->can('View:Plan');
}
public function create(AuthUser $authUser): bool
{
return $authUser->can('Create:Plan');
}
public function update(AuthUser $authUser, Plan $plan): bool
{
return $authUser->can('Update:Plan');
}
public function delete(AuthUser $authUser, Plan $plan): bool
{
return $authUser->can('Delete:Plan');
}
public function restore(AuthUser $authUser, Plan $plan): bool
{
return $authUser->can('Restore:Plan');
}
public function forceDelete(AuthUser $authUser, Plan $plan): bool
{
return $authUser->can('ForceDelete:Plan');
}
public function forceDeleteAny(AuthUser $authUser): bool
{
return $authUser->can('ForceDeleteAny:Plan');
}
public function restoreAny(AuthUser $authUser): bool
{
return $authUser->can('RestoreAny:Plan');
}
public function replicate(AuthUser $authUser, Plan $plan): bool
{
return $authUser->can('Replicate:Plan');
}
public function reorder(AuthUser $authUser): bool
{
return $authUser->can('Reorder:Plan');
}
}
Generated
+12 -12
View File
@@ -4518,16 +4518,16 @@
}, },
{ {
"name": "paragonie/constant_time_encoding", "name": "paragonie/constant_time_encoding",
"version": "v3.1.2", "version": "v3.1.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/paragonie/constant_time_encoding.git", "url": "https://github.com/paragonie/constant_time_encoding.git",
"reference": "5bd79e0e88e8757f23e757bcedd1e37fa818cf68" "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/5bd79e0e88e8757f23e757bcedd1e37fa818cf68", "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77",
"reference": "5bd79e0e88e8757f23e757bcedd1e37fa818cf68", "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4583,7 +4583,7 @@
"issues": "https://github.com/paragonie/constant_time_encoding/issues", "issues": "https://github.com/paragonie/constant_time_encoding/issues",
"source": "https://github.com/paragonie/constant_time_encoding" "source": "https://github.com/paragonie/constant_time_encoding"
}, },
"time": "2025-09-24T01:22:14+00:00" "time": "2025-09-24T15:06:41+00:00"
}, },
{ {
"name": "phiki/phiki", "name": "phiki/phiki",
@@ -10834,16 +10834,16 @@
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
"version": "12.3.8", "version": "12.4.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "99e692c6a84708211f7536ba322bbbaef57ac7fc" "reference": "67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/99e692c6a84708211f7536ba322bbbaef57ac7fc", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c",
"reference": "99e692c6a84708211f7536ba322bbbaef57ac7fc", "reference": "67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -10870,7 +10870,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "12.3.x-dev" "dev-main": "12.4.x-dev"
} }
}, },
"autoload": { "autoload": {
@@ -10899,7 +10899,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.3.8" "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.4.0"
}, },
"funding": [ "funding": [
{ {
@@ -10919,7 +10919,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-09-17T11:31:43+00:00" "time": "2025-09-24T13:44:41+00:00"
}, },
{ {
"name": "phpunit/php-file-iterator", "name": "phpunit/php-file-iterator",
+1 -2
View File
@@ -19,8 +19,7 @@ class KontoFactory extends Factory
return [ return [
'title' => fake()->randomElement(['Architekt:in', 'Ziviltechniker:in']), 'title' => fake()->randomElement(['Architekt:in', 'Ziviltechniker:in']),
'gender' => fake()->randomElement(['Frau', 'Herr']), 'gender' => fake()->randomElement(['Frau', 'Herr']),
'first_name' => fake()->firstName(), 'name' => fake()->name(),
'last_name' => fake()->lastName(),
'company' => fake()->Company(), 'company' => fake()->Company(),
'email' => fake()->email(), 'email' => fake()->email(),
'address' => fake()->Address(), 'address' => fake()->Address(),
+3
View File
@@ -2,6 +2,7 @@
namespace Database\Factories; namespace Database\Factories;
use App\Models\Konto;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str; use Illuminate\Support\Str;
@@ -24,7 +25,9 @@ class UserFactory extends Factory
public function definition(): array public function definition(): array
{ {
return [ return [
'gender' => fake()->randomElement(['Frau', 'Herr']),
'name' => fake()->name(), 'name' => fake()->name(),
'konto_id' => Konto::all()->random()->id,
'email' => fake()->unique()->safeEmail(), 'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(), 'email_verified_at' => now(),
'password' => static::$password ??= Hash::make('password'), 'password' => static::$password ??= Hash::make('password'),
@@ -15,8 +15,7 @@ return new class extends Migration
$table->id(); $table->id();
$table->string('title')->nullable(); $table->string('title')->nullable();
$table->string('gender')->nullable(); $table->string('gender')->nullable();
$table->string('first_name'); $table->string('name');
$table->string('last_name');
$table->string('company'); $table->string('company');
$table->string('email')->nullable(); $table->string('email')->nullable();
$table->string('address')->nullable(); $table->string('address')->nullable();
@@ -14,6 +14,7 @@ return new class extends Migration
Schema::create('plans', function (Blueprint $table) { Schema::create('plans', function (Blueprint $table) {
$table->id(); $table->id();
$table->string('name')->nullable(); $table->string('name')->nullable();
$table->string('payment')->nullable();
$table->string('description')->nullable(); $table->string('description')->nullable();
$table->integer('number_user')->default(1); $table->integer('number_user')->default(1);
$table->integer('number_gutachter')->default(1); $table->integer('number_gutachter')->default(1);
@@ -27,6 +28,6 @@ return new class extends Migration
*/ */
public function down(): void public function down(): void
{ {
Schema::dropIfExists('konto_options'); Schema::dropIfExists('plans');
} }
}; };
@@ -1,29 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('payments', function (Blueprint $table) {
$table->id();
$table->string('name')->nullable();
$table->string('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('payments');
}
};
@@ -1,28 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('titels', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('titels');
}
};
@@ -1,28 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('genders', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('genders');
}
};
+8 -5
View File
@@ -4,6 +4,7 @@ namespace Database\Seeders;
use App\Models\Gutachter; use App\Models\Gutachter;
use App\Models\Konto; use App\Models\Konto;
use App\Models\User;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder class DatabaseSeeder extends Seeder
@@ -17,11 +18,13 @@ class DatabaseSeeder extends Seeder
// Gutachter::factory()->create(30); // Gutachter::factory()->create(30);
// $this->call([ $this->call([
// OrientierungenSeeder::class, OrientierungenSeeder::class,
// KontoOptionSeeder::class, PlansSeeder::class,
// RolesAndPermissionsSeeder::class, RolesAndPermissionsSeeder::class,
// ]); ]);
User::factory()->count(100)->create();
} }
} }
-31
View File
@@ -1,31 +0,0 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class KontoOptionSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$sql = "INSERT INTO `payments` (`id`, `name`)
VALUES
('1', 'Pro Gutachten'),
('2', 'Monatlich'),
('3', 'Jährlich');
";
DB::unprepared($sql);
$sql = "INSERT INTO `plans` (`id`, `name`, `description`, `number_user`, `number_gutachter`, `payment_id`, `created_at`, `updated_at`)
VALUES
('1', 'Basic', 'Basis Version für einen Benutzer und einem Gutacher.', '1', '1', '1', NULL, NULL),
('2', 'Erweitert', 'Premium Version für 3 Benutzer und 3 Gutacher.', '3', '3', '2', NULL, NULL),
('3', 'Premium', 'Premium Version für fünf Benutzer und fünf Gutacher. \nUnbegrenzte Anzahl der Gutachten.', '5', '5', '3', NULL, NULL);
";
DB::unprepared($sql);
}
}
+3 -3
View File
@@ -12,10 +12,10 @@ class KontoSeeder extends Seeder
*/ */
public function run(): void public function run(): void
{ {
$sql = "INSERT INTO `kontos` (`id`, `konto_title`, `konto_gender`, `konto_first_name`, `konto_last_name`, `konto_company`, `konto_email`, `konto_address`, `konto_location`, `konto_plz`, `konto_country`, `konto_phone`, `konto_uid_number`, `konto_agb_akzeptiert`, `konto_option_id`, `konto_gutachten_zahl`, `konto_gutachten_zeit`, `konto_gutachten_abgeschlossen`, `created_at`, `updated_at`) $sql = "INSERT INTO `kontos` (`id`, `title`, `gender`, `name`, `company`, `email`, `address`, `location`, `plz`, `country`, `phone`, `uid_number`, `agb_akzeptiert`, `option_id`, `gutachten_zahl`, `gutachten_zeit`, `gutachten_abgeschlossen`, `created_at`, `updated_at`)
VALUES VALUES
('1', 'Architekt', 'Herr', 'Hanno', 'Vogl-Fernheim', 'Architekt Vogl-Fernheim', 'office@vogl-fernheim.eu', 'Richardsweg 1', 'Innsbruck', '6020', 'Österreich', '+43 0512 560303', 'ATU 61718733', '1', '1', '1', NULL, '1', NULL, NULL), ('1', 'Architekt', 'Herr', 'Hanno Vogl-Fernheim', 'Architekt Vogl-Fernheim', 'office@vogl-fernheim.eu', 'Richardsweg 1', 'Innsbruck', '6020', 'Österreich', '+43 0512 560303', 'ATU 61718733', '1', '1', '1', NULL, '1', NULL, NULL),
('2', 'Staatl. bef. u. beeideter Ziviltechniker', 'Herr', 'Christoph', 'Falkner', 'Christoph Falkner', 'christophfalkner@me.com', 'Adele-Obermayr-Straße 2', 'Innsbruck', '6020', 'Österreich', '+43 650 92210248', 'ATU56874500', '1', '1', '1', NULL, '1', NULL, NULL); ('2', 'Staatl. bef. u. beeideter Ziviltechniker', 'Herr', 'Christoph Falkner', 'Ziviltechniker Christoph Falkner', 'christophfalkner@me.com', 'Adele-Obermayr-Straße 2', 'Innsbruck', '6020', 'Österreich', '+43 650 92210248', 'ATU56874500', '1', '1', '1', NULL, '1', NULL, NULL);
"; ";
DB::unprepared($sql); DB::unprepared($sql);
} }
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class PlansSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$sql = "INSERT INTO `plans` (`id`, `name`, `payment`, `description`, `number_user`, `number_gutachter`, `payment_id`, `created_at`, `updated_at`)
VALUES
('1', 'Basic', 'Pro Gutachten', 'Basis Version für einen Benutzer und einem Gutacher.', '1', '1', '1', NULL, NULL),
('2', 'Erweitert', 'Monatlich', 'Premium Version für 3 Benutzer und 3 Gutacher.', '3', '3', '2', NULL, NULL),
('3', 'Premium', 'Jährlich', 'Premium Version für fünf Benutzer und fünf Gutacher. \nUnbegrenzte Anzahl der Gutachten.', '5', '5', '3', NULL, NULL);
";
DB::unprepared($sql);
}
}