Zum Hauptinhalt springen

OrderResource

Die OrderResource verwaltet alle Dolmetsch-Aufträge der Plattform.

Konfiguration

File: OrderResource.php

EigenschaftWert
ModelApp\Models\Order
Navigation GroupAuftragsverwaltung
Navigation LabelAufträge
Navigation Iconheroicon-o-shopping-bag
Navigation Sort1

State Machine

State-Farben

StateFarbeBeschreibung
DraftgrayEntwurf
OpenwarningOffen, sucht Sprachmittler
AssignedinfoSprachmittler zugewiesen
RunningprimaryTermin läuft
CompletedsuccessAbgeschlossen
CancelleddangerStorniert
NotMatcheddangerKein Sprachmittler gefunden
InvoiceCreatedinfoRechnung erstellt
PaymentInstructedwarningZahlung angewiesen
PaymentReceivedsuccessZahlung erhalten

Form-Struktur

Allgemeine Informationen

FeldTypBeschreibung
order_numberTextInputAutomatisch generiert, readonly
appointment_category_idSelectTerminart (Behörde, Arzt, etc.)

Auftraggeber

Forms\Components\Select::make('requester_id')
->relationship('requester', 'full_name')
->searchable()
->preload()
->createOptionForm([
// Inline-Erstellung eines neuen Auftraggebers
Forms\Components\TextInput::make('first_name')->required(),
Forms\Components\TextInput::make('last_name')->required(),
Forms\Components\TextInput::make('email')->email()->required(),
Forms\Components\TextInput::make('phone'),
Forms\Components\Hidden::make('role')->default('requester'),
])
->createOptionUsing(function (array $data) {
$user = User::create([
...$data,
'password' => bcrypt(Str::random(16)),
'state' => new Active,
]);
return $user->id;
})

Klient-Informationen

FeldTypValidierung
client_salutationSelectnullable
client_first_nameTextInputrequired, max:255
client_last_nameTextInputrequired, max:255
client_phoneTextInputnullable
client_emailTextInputnullable, email
client_country_codeSelect185+ Länder

Termin-Details

FeldTypBeschreibung
scheduled_dateDatePickerTermindatum
scheduled_timeTimePickerTerminzeit
estimated_durationTextInputGeschätzte Dauer (Minuten)
location_streetTextInputStraße
location_house_numberTextInputHausnummer
location_postal_codeTextInputPLZ
location_cityTextInputStadt
location_additional_infoTextareaZusatzinfo (Raum, Etage)

Check-In/Out Zeiten

Nur sichtbar bei entsprechendem State:

Forms\Components\Section::make('Check-In/Out')
->visible(fn (?Order $record) => $record?->state instanceof Assigned
|| $record?->state instanceof Running
|| $record?->state instanceof Completed)
->schema([
Forms\Components\DateTimePicker::make('check_in_time')
->label('Check-In Zeit'),
Forms\Components\DateTimePicker::make('check_out_time')
->label('Check-Out Zeit')
->visible(fn (?Order $record) => $record?->state instanceof Running
|| $record?->state instanceof Completed),
])

Sprachmittler-Präferenzen

FeldTypBeschreibung
desired_interpreter_idSelectWunsch-Sprachmittler
preferred_interpreter_genderSelectGeschlechtspräferenz
interpreter_notesTextareaHinweise für Sprachmittler

Sprach-Informationen

FeldTypBeschreibung
client_languagesSelectMax 3 Sprachen des Klienten
target_language_codesSelectZielsprache (DE/EN)

Kosten

Nur bei abgeschlossenen Aufträgen editierbar:

Forms\Components\Section::make('Kosten')
->visible(fn (?Order $record) => $record?->state instanceof Completed)
->schema([
Forms\Components\TextInput::make('total_amount')
->numeric()
->prefix('€')
->disabled(fn (?Order $record) => !$record?->state instanceof Completed),

Forms\Components\Repeater::make('additional_costs')
->relationship()
->schema([
Forms\Components\Select::make('category')
->options([
'travel' => 'Fahrtkosten',
'waiting' => 'Wartezeit',
'materials' => 'Materialien',
'overtime' => 'Überstunden',
'other' => 'Sonstiges',
])
->required(),
Forms\Components\TextInput::make('amount')
->numeric()
->prefix('€')
->required(),
Forms\Components\TextInput::make('description'),
]),
])

Table-Konfiguration

Spalten

SpalteTypBeschreibung
order_numberTextColumnSortierbar
requester.full_nameTextColumnAuftraggeber
scheduled_atTextColumnFormatiert als Datum+Zeit
stateBadgeColumnFarbcodiert
appointment_category.nameTextColumnTerminart
full_addressTextColumnZusammengesetzte Adresse
client_languagesBadgeColumnKlient-Sprachen
target_languagesBadgeColumnZielsprachen
total_amountTextColumnMit € Suffix
current_interpreter.full_nameTextColumnAktueller Sprachmittler
is_over_30kmIconColumnIndikator für weite Anfahrt

Filter

FilterTypBeschreibung
scheduled_dateDateRangeFilterTerminzeitraum
requester_idSelectFilterAuftraggeber
appointment_category_idSelectFilterTerminart
is_overdueTernaryFilterÜberfällige Aufträge
is_todayTernaryFilterHeutige Aufträge
is_this_weekTernaryFilterDiese Woche
stateSelectFilterStatus

Actions

State-Transition Actions

Action::make('assign')
->label('Sprachmittler zuweisen')
->icon('heroicon-o-user-plus')
->visible(fn (Order $record) => $record->state instanceof Open)
->form([
Forms\Components\Select::make('interpreter_id')
->label('Sprachmittler')
->options(function (Order $record) {
return User::interpreters()
->available()
->withDistanceFrom($record->location_latitude, $record->location_longitude)
->get()
->mapWithKeys(fn ($user) => [
$user->id => "{$user->full_name} ({$user->distance} km)"
]);
})
->required(),
])
->action(function (Order $record, array $data) {
$record->assignInterpreter($data['interpreter_id']);
})

Invoice Actions

ActionIconBeschreibungSichtbarkeit
create_invoicedocument-plusRechnung erstellenCompleted
download_invoicearrow-down-trayRechnung herunterladenInvoiceCreated+
calculate_costscalculatorKosten berechnenCompleted
Action::make('create_invoice')
->label('Rechnung erstellen')
->icon('heroicon-o-document-plus')
->visible(fn (Order $record) => $record->state instanceof Completed)
->requiresConfirmation()
->action(function (Order $record) {
$invoice = $record->createInvoice();
$record->transitionTo(InvoiceCreated::class);

Notification::make()
->success()
->title('Rechnung erstellt')
->body("Rechnungsnummer: {$invoice->invoice_number}")
->send();
})

Activity Timeline

ActivityTimelineAction::make('activity_timeline')
->label('Aktivitäten')
->icon('heroicon-o-clock')
->slideOver()

Relation Managers

Angezeigt als Tabs auf der ViewOrder-Seite:

OrderRequestsRelationManager

Zeigt alle Sprachmittler-Anfragen für diesen Auftrag.

SpalteBeschreibung
interpreter.full_nameSprachmittler
stateStatus (Badge)
scoreMatching-Score
created_atErstellt am
responded_atBeantwortet am

InvoicesRelationManager

Zeigt alle Rechnungen für diesen Auftrag.

SpalteBeschreibung
invoice_numberRechnungsnummer
versionVersion
total_amountBetrag
stateStatus
created_atErstellt am

Actions:

  • download: Rechnung herunterladen
  • regenerate: Rechnung neu generieren

AdditionalCostsRelationManager

Verwaltet Zusatzkosten.

SpalteBeschreibung
categoryKategorie (Badge)
amountBetrag
descriptionBeschreibung

ActivityLogRelationManager

Zeigt das Aktivitätsprotokoll.

Bulk Actions

ActionIconBeschreibung
deletetrashAufträge löschen
exportarrow-down-trayAls Excel exportieren
assign_bulkuser-plusMehrere zuweisen

Pages

PageKlasseBeschreibung
indexListOrdersÜbersichtstabelle
createCreateOrderAuftrag erstellen
viewViewOrderDetailansicht mit Tabs
editEditOrderAuftrag bearbeiten

ViewOrder mit Relation Managers

class ViewOrder extends ViewRecord
{
protected static string $resource = OrderResource::class;

use ViewRecord\Concerns\HasRelationManagers;

public function getRelationManagers(): array
{
return [
'order_requests' => OrderRequestsRelationManager::class,
'invoices' => InvoicesRelationManager::class,
'additional_costs' => AdditionalCostsRelationManager::class,
'activity_log' => ActivityLogRelationManager::class,
];
}
}