From e19372eed16bd3f3991f1f9ce728973ce85a40b0 Mon Sep 17 00:00:00 2001 From: Nurmuhammet Allanov Date: Thu, 23 Oct 2025 16:29:39 +0500 Subject: [PATCH] Card order --- .../Cards/CardOrders/CardOrderResource.php | 85 ++++++ .../CardOrders/Pages/CreateCardOrder.php | 11 + .../Cards/CardOrders/Pages/EditCardOrder.php | 23 ++ .../Cards/CardOrders/Pages/ListCardOrders.php | 19 ++ .../CardOrders/Schemas/CardOrderForm.php | 267 ++++++++++++++++++ .../CardOrders/Tables/CardOrdersTable.php | 98 +++++++ .../Clusters/Cards/Cards/CardResource.php | 2 + lang/tk.json | 1 + 8 files changed, 506 insertions(+) create mode 100644 app/Filament/Clusters/Cards/CardOrders/CardOrderResource.php create mode 100644 app/Filament/Clusters/Cards/CardOrders/Pages/CreateCardOrder.php create mode 100644 app/Filament/Clusters/Cards/CardOrders/Pages/EditCardOrder.php create mode 100644 app/Filament/Clusters/Cards/CardOrders/Pages/ListCardOrders.php create mode 100644 app/Filament/Clusters/Cards/CardOrders/Schemas/CardOrderForm.php create mode 100644 app/Filament/Clusters/Cards/CardOrders/Tables/CardOrdersTable.php diff --git a/app/Filament/Clusters/Cards/CardOrders/CardOrderResource.php b/app/Filament/Clusters/Cards/CardOrders/CardOrderResource.php new file mode 100644 index 0000000..05abf8b --- /dev/null +++ b/app/Filament/Clusters/Cards/CardOrders/CardOrderResource.php @@ -0,0 +1,85 @@ + ListCardOrders::route('/'), + 'create' => CreateCardOrder::route('/create'), + 'edit' => EditCardOrder::route('/{record}/edit'), + ]; + } + + /** + * @return Builder<\App\Modules\CardOrder\Models\CardOrder> + */ + public static function getRecordRouteBindingEloquentQuery(): Builder + { + return parent::getRecordRouteBindingEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } +} diff --git a/app/Filament/Clusters/Cards/CardOrders/Pages/CreateCardOrder.php b/app/Filament/Clusters/Cards/CardOrders/Pages/CreateCardOrder.php new file mode 100644 index 0000000..2b74fae --- /dev/null +++ b/app/Filament/Clusters/Cards/CardOrders/Pages/CreateCardOrder.php @@ -0,0 +1,11 @@ +components([ + Hidden::make('user_id')->default(Auth::id()), + + Section::make(__('New loan order')) + ->columnSpan(4) + ->columns(4) + ->components([ + Select::make('status') + ->label(__('Status')) + ->options(OrderStatusRepository::statusValues()) + ->default(OrderStatusRepository::defaultStatus()) + ->native(false) + ->required() + ->columnSpan(2), + + Toggle::make('paid') + ->label(__('Paid')) + ->inline(false) + ->required(), + + RichEditor::make('notes') + ->label(__('Bellik')) + ->columnSpanFull(), + ]), + + Wizard::make([ + Step::make(__('Loan & Bank')) + ->schema([ + Fieldset::make(__('Loan type and amount')) + ->schema([ + Select::make('card_state_id') + ->relationship('cardState', 'name') + ->label(__('Card state')) + ->native(false) + ->required(), + + Select::make('card_type_id') + ->relationship('cardType', 'name') + ->label(__('Card type')) + ->native(false) + ->required(), + ]), + + Fieldset::make(__('Location')) + ->schema([ + Select::make('region') + ->label(__('Region')) + ->options(RegionRepository::values()) + ->live() + ->afterStateUpdated(fn (callable $set) => $set('branch_id', null)) + ->required(), + + Select::make('branch_id') + ->label(__('Branch')) + ->relationship('branch', 'name', function ($query, callable $get) { + $region = $get('region'); + if ($region) { + $query->where('region', $region); + } + }) + ->required(), + ]), + ]), + Step::make(__('Personal information')) + ->columns(8) + ->schema([ + TextInput::make('customer_name') + ->label(__('Name')) + ->columnSpan(2) + ->default(user()->first_name) + ->required() + ->maxLength(255) + ->autocomplete(Str::random(10)), + + TextInput::make('customer_surname') + ->label(__('Surname')) + ->columnSpan(2) + ->default(user()->last_name) + ->required() + ->maxLength(255), + + TextInput::make('customer_patronic_name') + ->label(__('Patronic name')) + ->columnSpan(2) + ->default(user()->getOption('patronic_name')) + ->maxLength(255), + + DatePicker::make('born_at') + ->displayFormat('d.m.Y') + ->label(__('Birth date')) + ->native(false) + ->columnSpan(2) + ->default(user()->getOption('born_at')) + ->required() + ->beforeOrEqual('today'), + + FusedGroup::make([ + Select::make('passport_serie') + ->label(__('Passport serie')) + ->options(TurkmenPassportRepository::values()) + ->native(false) + ->required() + ->default(user()->getOption('passport_serie')) + ->columnSpan(1), + + TextInput::make('passport_id') + ->label(__('Passport number')) + ->required() + ->columnSpan(1) + ->default(user()->getOption('passport_id')) + ->mask('999999'), + ]) + ->columnSpan(3) + ->label(__('Passport serie and number')) + ->columns(2), + + DatePicker::make('passport_given_at') + ->label(__('Passport given date')) + ->columnSpan(2) + ->displayFormat('d.m.Y') + ->native(false) + ->closeOnDateSelection() + ->default(user()->getOption('passport_given_at')) + ->beforeOrEqual('today') + ->required(), + + TextInput::make('born_place') + ->columnSpan(3) + ->label(__('Born place (passport)')) + ->default(user()->getOption('born_place')) + ->maxLength(255) + ->required(), + + TextInput::make('passport_given_by') + ->label(__('Passport given by')) + ->columnSpan(4) + ->default(user()->getOption('passport_given_by')) + ->maxLength(255) + ->required(), + + TextInput::make('passport_address') + ->columnSpan(4) + ->label(__('Proscription for home')) + ->default(user()->getOption('passport_address')) + ->maxLength(255) + ->required(), + + TextInput::make('real_address') + ->label(__('Current home address')) + ->columnSpan(4) + ->default(user()->getOption('real_address')) + ->maxLength(255) + ->required(), + + TextInput::make('phone') + ->label(__('Phone')) + ->required() + ->mask('99 99 99 99') + ->prefix('+993') + ->default(user()->phone) + ->rules([ + new PhoneNumberVerificationRule, + ]) + ->columnSpan(2), + + TextInput::make('phone_additional') + ->label(__('Additional phone')) + ->mask('99 99 99 99') + ->prefix('+993') + ->default(user()->getOption('phone_additional')) + ->rules([ + new PhoneNumberVerificationRule, + ]) + ->columnSpan(2), + + TextInput::make('job_location') + ->label(__('Work location and your position')) + ->columnSpan(6) + ->required(), + + Select::make('citizenship') + ->label(__('Citizenship')) + ->options(CountryRepository::values()) + ->default('TM') + ->columnSpan(2) + ->required(), + ]), + Step::make(__('Pasport files')) + ->columns(4) + ->schema([ + FileUpload::make('passport_one') + ->label(__('Passport (page 1)')) + ->image() + ->maxSize(4096) + ->required() + ->columnSpan(2), + + FileUpload::make('passport_two') + ->label(__('Passport (page 2-3)')) + ->image() + ->maxSize(4096) + ->required() + ->columnSpan(2), + + FileUpload::make('passport_three') + ->label(__('Passport (page 8-9)')) + ->image() + ->maxSize(4096) + ->required() + ->columnSpan(2), + + FileUpload::make('passport_four') + ->label(__('Passport (page 32)')) + ->image() + ->maxSize(4096) + ->required() + ->columnSpan(2), + ])->columnSpan(4), + ])->columnSpanFull(), + + // Textarea::make('passport_one') + // ->required() + // ->columnSpanFull(), + // Textarea::make('passport_two') + // ->required() + // ->columnSpanFull(), + // Textarea::make('passport_three') + // ->required() + // ->columnSpanFull(), + // Textarea::make('passport_four') + // ->required() + // ->columnSpanFull(), + + ]); + } +} diff --git a/app/Filament/Clusters/Cards/CardOrders/Tables/CardOrdersTable.php b/app/Filament/Clusters/Cards/CardOrders/Tables/CardOrdersTable.php new file mode 100644 index 0000000..fa31f40 --- /dev/null +++ b/app/Filament/Clusters/Cards/CardOrders/Tables/CardOrdersTable.php @@ -0,0 +1,98 @@ +columns([ + TextColumn::make('unique_id') + ->searchable(), + TextColumn::make('cardState.name') + ->searchable(), + TextColumn::make('cardType.name') + ->searchable(), + TextColumn::make('region') + ->searchable(), + TextColumn::make('branch.name') + ->searchable(), + TextColumn::make('customer_name') + ->searchable(), + TextColumn::make('customer_surname') + ->searchable(), + TextColumn::make('customer_patronic_name') + ->searchable(), + TextColumn::make('born_at') + ->date() + ->sortable(), + TextColumn::make('old_surname') + ->searchable(), + TextColumn::make('citizenship') + ->searchable(), + TextColumn::make('passport_serie') + ->searchable(), + TextColumn::make('passport_id') + ->searchable(), + TextColumn::make('passport_given_at') + ->date() + ->sortable(), + TextColumn::make('passport_given_by') + ->searchable(), + TextColumn::make('born_place') + ->searchable(), + TextColumn::make('job_location') + ->searchable(), + TextColumn::make('passport_address') + ->searchable(), + TextColumn::make('real_address') + ->searchable(), + TextColumn::make('phone') + ->searchable(), + TextColumn::make('phone_additional') + ->searchable(), + TextColumn::make('status') + ->searchable(), + TextColumn::make('user.name') + ->searchable(), + IconColumn::make('paid') + ->boolean(), + TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + TextColumn::make('updated_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + TextColumn::make('deleted_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + TrashedFilter::make(), + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ForceDeleteBulkAction::make(), + RestoreBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Clusters/Cards/Cards/CardResource.php b/app/Filament/Clusters/Cards/Cards/CardResource.php index 947b8e1..3279dc2 100644 --- a/app/Filament/Clusters/Cards/Cards/CardResource.php +++ b/app/Filament/Clusters/Cards/Cards/CardResource.php @@ -22,6 +22,8 @@ use Filament\Tables\Table; class CardResource extends Resource { + protected static ?int $navigationSort = 1; + protected static ?string $model = Card::class; protected static ?string $cluster = CardsCluster::class; diff --git a/lang/tk.json b/lang/tk.json index c8c1606..76c7ea7 100644 --- a/lang/tk.json +++ b/lang/tk.json @@ -522,6 +522,7 @@ "Created by": "Sargyt eden", "Updated by": "Üýtgeden", "Passport files": "Pasport faýýlar", + "New card order": "Täze kart sargyt", "Card order": "Kart sargyt", "Card orders": "Kart sargytlary", "Reason for issuing the card": "Kartyň çykarylmagynyň sebäbi",