improve WO form: inline client/vehicle create, mechanic filter, category translation, PDF emoji fix
- client_id field: switched to relationship() with createOptionForm so new clients
can be created inline (name, phone, email); search also matches by phone
- vehicle_id field: added createOptionForm (make, model, plate, year, VIN); newly
created vehicle is automatically linked to the currently selected client
- master_id field: now shows only active users with role mechanic/master
- WorksRelationManager: labor catalog select marked optional; added createOptionForm
so new catalog entries can be added without leaving the WO form
- SubcontractJobsRelationManager: category table column now translates value via __()
and shows explicit label(__('Categorie'))
- PDF work-order: replaced 📞 / ✉ / ⚠ emojis with plain-text equivalents so
DomPDF/DejaVu Sans renders them correctly instead of showing "????"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -84,16 +84,39 @@ class WorkOrderResource extends Resource
|
|||||||
Forms\Components\Select::make('urgency')->label(__('Urgență'))
|
Forms\Components\Select::make('urgency')->label(__('Urgență'))
|
||||||
->options(\App\Support\I18n::opts(\App\Models\Tenant\PricingCoefficient::URGENCY))->default('normal')->required(),
|
->options(\App\Support\I18n::opts(\App\Models\Tenant\PricingCoefficient::URGENCY))->default('normal')->required(),
|
||||||
Forms\Components\Select::make('client_id')->label(__('Client'))
|
Forms\Components\Select::make('client_id')->label(__('Client'))
|
||||||
->options(fn () => Client::pluck('name', 'id'))
|
->relationship('client', 'name')
|
||||||
->searchable()->live()->required()->columnSpan(2),
|
->getSearchResultsUsing(fn (string $query) =>
|
||||||
|
Client::where(fn ($q) => $q
|
||||||
|
->where('name', 'like', "%{$query}%")
|
||||||
|
->orWhere('phone', 'like', "%{$query}%"))
|
||||||
|
->limit(30)->pluck('name', 'id'))
|
||||||
|
->searchable()->live()->required()->columnSpan(2)
|
||||||
|
->createOptionForm([
|
||||||
|
Forms\Components\TextInput::make('name')->label(__('Nume'))->required(),
|
||||||
|
Forms\Components\TextInput::make('phone')->label(__('Telefon')),
|
||||||
|
Forms\Components\TextInput::make('email')->label(__('Email'))->email(),
|
||||||
|
]),
|
||||||
Forms\Components\Select::make('vehicle_id')->label(__('Auto'))
|
Forms\Components\Select::make('vehicle_id')->label(__('Auto'))
|
||||||
->options(fn (Get $get) => $get('client_id')
|
->options(fn (Get $get) => $get('client_id')
|
||||||
? Vehicle::where('client_id', $get('client_id'))->get()
|
? Vehicle::where('client_id', $get('client_id'))->get()
|
||||||
->mapWithKeys(fn ($v) => [$v->id => "{$v->make} {$v->model} {$v->plate}"])->toArray()
|
->mapWithKeys(fn ($v) => [$v->id => "{$v->make} {$v->model} {$v->plate}"])->toArray()
|
||||||
: [])
|
: [])
|
||||||
->searchable()->columnSpan(2),
|
->searchable()->columnSpan(2)
|
||||||
|
->createOptionForm([
|
||||||
|
Forms\Components\TextInput::make('make')->label(__('Marcă'))->required(),
|
||||||
|
Forms\Components\TextInput::make('model')->label(__('Model'))->required(),
|
||||||
|
Forms\Components\TextInput::make('plate')->label(__('Nr. înmatriculare'))->required(),
|
||||||
|
Forms\Components\TextInput::make('year')->label(__('An'))->numeric(),
|
||||||
|
Forms\Components\TextInput::make('vin')->label(__('VIN')),
|
||||||
|
])
|
||||||
|
->createOptionUsing(function (array $data, \Livewire\Component $livewire) {
|
||||||
|
$data['client_id'] = data_get((array) $livewire->data, 'client_id');
|
||||||
|
return Vehicle::create($data)->id;
|
||||||
|
}),
|
||||||
Forms\Components\Select::make('master_id')->label(__('Maistru'))
|
Forms\Components\Select::make('master_id')->label(__('Maistru'))
|
||||||
->options(fn () => User::where('status', 'active')->pluck('name', 'id'))
|
->options(fn () => User::where('status', 'active')
|
||||||
|
->whereIn('role', ['mechanic', 'master'])
|
||||||
|
->pluck('name', 'id'))
|
||||||
->searchable()->columnSpan(2),
|
->searchable()->columnSpan(2),
|
||||||
Forms\Components\TextInput::make('mileage_in')->label(__('Km intrare'))->numeric(),
|
Forms\Components\TextInput::make('mileage_in')->label(__('Km intrare'))->numeric(),
|
||||||
Forms\Components\TextInput::make('mileage_out')->label(__('Km ieșire'))->numeric(),
|
Forms\Components\TextInput::make('mileage_out')->label(__('Km ieșire'))->numeric(),
|
||||||
|
|||||||
+3
-1
@@ -51,7 +51,9 @@ class SubcontractJobsRelationManager extends RelationManager
|
|||||||
->columns([
|
->columns([
|
||||||
Tables\Columns\TextColumn::make('number')->label(__('Nr.')),
|
Tables\Columns\TextColumn::make('number')->label(__('Nr.')),
|
||||||
Tables\Columns\TextColumn::make('subcontractor.name')->label(__('Terț'))->placeholder('—'),
|
Tables\Columns\TextColumn::make('subcontractor.name')->label(__('Terț'))->placeholder('—'),
|
||||||
Tables\Columns\TextColumn::make('category')->badge()->placeholder('—'),
|
Tables\Columns\TextColumn::make('category')->label(__('Categorie'))
|
||||||
|
->formatStateUsing(fn ($s) => $s ? __($s) : '—')
|
||||||
|
->badge()->placeholder('—'),
|
||||||
Tables\Columns\TextColumn::make('cost')->money('MDL')->alignRight(),
|
Tables\Columns\TextColumn::make('cost')->money('MDL')->alignRight(),
|
||||||
Tables\Columns\TextColumn::make('client_price')->label(__('Preț client'))->money('MDL')->alignRight(),
|
Tables\Columns\TextColumn::make('client_price')->label(__('Preț client'))->money('MDL')->alignRight(),
|
||||||
Tables\Columns\TextColumn::make('margin')
|
Tables\Columns\TextColumn::make('margin')
|
||||||
|
|||||||
+13
-1
@@ -28,7 +28,7 @@ class WorksRelationManager extends RelationManager
|
|||||||
{
|
{
|
||||||
return $schema->components([
|
return $schema->components([
|
||||||
Forms\Components\Select::make('labor_id')
|
Forms\Components\Select::make('labor_id')
|
||||||
->label(__('Catalog manoperă'))
|
->label(__('Catalog manoperă') . ' (' . __('opțional') . ')')
|
||||||
->options(fn () => Labor::where('is_active', true)
|
->options(fn () => Labor::where('is_active', true)
|
||||||
->get()
|
->get()
|
||||||
->mapWithKeys(fn ($l) => [$l->id => '[' . __($l->category) . '] ' . $l->label() . ' (' . $l->hours . __('h') . ')'])
|
->mapWithKeys(fn ($l) => [$l->id => '[' . __($l->category) . '] ' . $l->label() . ' (' . $l->hours . __('h') . ')'])
|
||||||
@@ -42,6 +42,18 @@ class WorksRelationManager extends RelationManager
|
|||||||
$set('price_per_hour', $labor->hours > 0 ? round($labor->price / max((float) $labor->hours, 1), 2) : 0);
|
$set('price_per_hour', $labor->hours > 0 ? round($labor->price / max((float) $labor->hours, 1), 2) : 0);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
->createOptionForm([
|
||||||
|
Forms\Components\Select::make('category')->label(__('Categorie'))
|
||||||
|
->options(\App\Support\I18n::opts(array_combine(Labor::CATEGORIES, Labor::CATEGORIES)))
|
||||||
|
->required(),
|
||||||
|
Forms\Components\TextInput::make('name_ro')->label(__('Denumire'))->required(),
|
||||||
|
Forms\Components\TextInput::make('hours')->label(__('Ore normate'))->numeric()->default(1)->required(),
|
||||||
|
Forms\Components\TextInput::make('price')->label(__('Preț total (MDL)'))->numeric()->default(0)->required(),
|
||||||
|
])
|
||||||
|
->createOptionUsing(function (array $data) {
|
||||||
|
$data['is_active'] = true;
|
||||||
|
return Labor::create($data)->id;
|
||||||
|
})
|
||||||
->columnSpanFull(),
|
->columnSpanFull(),
|
||||||
Forms\Components\TextInput::make('name')->label(__('Nume'))->required()->columnSpanFull(),
|
Forms\Components\TextInput::make('name')->label(__('Nume'))->required()->columnSpanFull(),
|
||||||
Forms\Components\TextInput::make('hours')->label(__('Ore'))->numeric()->default(1)->required(),
|
Forms\Components\TextInput::make('hours')->label(__('Ore'))->numeric()->default(1)->required(),
|
||||||
|
|||||||
@@ -126,10 +126,10 @@
|
|||||||
<div class="brand-sub">{{ $company->city }}</div>
|
<div class="brand-sub">{{ $company->city }}</div>
|
||||||
@endif
|
@endif
|
||||||
@if ($company->phone)
|
@if ($company->phone)
|
||||||
<div class="brand-sub">📞 {{ $company->phone }}</div>
|
<div class="brand-sub">Tel.: {{ $company->phone }}</div>
|
||||||
@endif
|
@endif
|
||||||
@if ($company->email)
|
@if ($company->email)
|
||||||
<div class="brand-sub">✉ {{ $company->email }}</div>
|
<div class="brand-sub">Email: {{ $company->email }}</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-half">
|
<div class="col col-half">
|
||||||
@@ -268,7 +268,7 @@
|
|||||||
|
|
||||||
@if ($wo->recommendations)
|
@if ($wo->recommendations)
|
||||||
<div class="recommendations">
|
<div class="recommendations">
|
||||||
<h3>{{ __('⚠ Recomandări') }}</h3>
|
<h3>{{ __('Recomandări') }}</h3>
|
||||||
<div>{{ $wo->recommendations }}</div>
|
<div>{{ $wo->recommendations }}</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
Reference in New Issue
Block a user