diff --git a/app/Filament/Exports/OrderExporter.php b/app/Filament/Exports/OrderExporter.php new file mode 100644 index 0000000..457d349 --- /dev/null +++ b/app/Filament/Exports/OrderExporter.php @@ -0,0 +1,41 @@ +label('ID'), + ExportColumn::make('created_at')->label('Erstallungsdatum'), + ExportColumn::make('updated_at')->label('Letzte Veränderung'), + ExportColumn::make('name')->label('Name'), + ExportColumn::make('url')->label('URL'), + ExportColumn::make('count')->label('Anzahl'), + ExportColumn::make('orderstatus.name')->label('Bestellstatus'), + ExportColumn::make('orderdatetime')->label('Bestelldatum'), + ExportColumn::make('user.name')->label('Bestellt von'), + ]; + } + + public static function getCompletedNotificationBody(Export $export): string + { + $body = 'Your order export has completed and ' . Number::format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.'; + + if ($failedRowsCount = $export->getFailedRowsCount()) { + $body .= ' ' . Number::format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to export.'; + } + + return $body; + } +} diff --git a/app/Filament/Resources/Orders/Pages/ListOrders.php b/app/Filament/Resources/Orders/Pages/ListOrders.php index 701628e..1367fa3 100644 --- a/app/Filament/Resources/Orders/Pages/ListOrders.php +++ b/app/Filament/Resources/Orders/Pages/ListOrders.php @@ -2,8 +2,10 @@ namespace App\Filament\Resources\Orders\Pages; +use App\Filament\Exports\OrderExporter; use App\Filament\Resources\Orders\OrderResource; use Filament\Actions\CreateAction; +use Filament\Actions\ExportAction; use Filament\Resources\Pages\ListRecords; class ListOrders extends ListRecords @@ -14,6 +16,7 @@ class ListOrders extends ListRecords { return [ CreateAction::make(), + ExportAction::make()->label('exportieren')->exporter(OrderExporter::class)->enableVisibleTableColumnsByDefault() ]; } } diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 0e579ed..3c5878a 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -31,6 +31,7 @@ class AdminPanelProvider extends PanelProvider ->login() ->spa() ->unsavedChangesAlerts() + ->databaseNotifications() ->profile() ->passwordReset() ->colors([ diff --git a/database/migrations/2026_02_21_220719_create_notifications_table.php b/database/migrations/2026_02_21_220719_create_notifications_table.php new file mode 100644 index 0000000..d738032 --- /dev/null +++ b/database/migrations/2026_02_21_220719_create_notifications_table.php @@ -0,0 +1,31 @@ +uuid('id')->primary(); + $table->string('type'); + $table->morphs('notifiable'); + $table->text('data'); + $table->timestamp('read_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('notifications'); + } +}; diff --git a/database/migrations/2026_02_21_220723_create_imports_table.php b/database/migrations/2026_02_21_220723_create_imports_table.php new file mode 100644 index 0000000..1d9c09d --- /dev/null +++ b/database/migrations/2026_02_21_220723_create_imports_table.php @@ -0,0 +1,35 @@ +id(); + $table->timestamp('completed_at')->nullable(); + $table->string('file_name'); + $table->string('file_path'); + $table->string('importer'); + $table->unsignedInteger('processed_rows')->default(0); + $table->unsignedInteger('total_rows'); + $table->unsignedInteger('successful_rows')->default(0); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('imports'); + } +}; diff --git a/database/migrations/2026_02_21_220724_create_exports_table.php b/database/migrations/2026_02_21_220724_create_exports_table.php new file mode 100644 index 0000000..6a87ac3 --- /dev/null +++ b/database/migrations/2026_02_21_220724_create_exports_table.php @@ -0,0 +1,35 @@ +id(); + $table->timestamp('completed_at')->nullable(); + $table->string('file_disk'); + $table->string('file_name')->nullable(); + $table->string('exporter'); + $table->unsignedInteger('processed_rows')->default(0); + $table->unsignedInteger('total_rows'); + $table->unsignedInteger('successful_rows')->default(0); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('exports'); + } +}; diff --git a/database/migrations/2026_02_21_220725_create_failed_import_rows_table.php b/database/migrations/2026_02_21_220725_create_failed_import_rows_table.php new file mode 100644 index 0000000..2f77805 --- /dev/null +++ b/database/migrations/2026_02_21_220725_create_failed_import_rows_table.php @@ -0,0 +1,30 @@ +id(); + $table->json('data'); + $table->foreignId('import_id')->constrained()->cascadeOnDelete(); + $table->text('validation_error')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('failed_import_rows'); + } +}; diff --git a/run_queue.sh b/run_queue.sh new file mode 100755 index 0000000..1982ee4 --- /dev/null +++ b/run_queue.sh @@ -0,0 +1,2 @@ +#//bin/sh +/usr/bin/php artisan queue:work --stop-when-empty --silent