@extends('layouts.app', ['title' => 'Auftrag ' . $order->order_nr]) @section('content')
{{-- Header --}}
Zurück @if($order->category) {{ $order->category->nr_prefix }} · {{ $order->category->name }} @endif @if($order->offer) aus Angebot {{ $order->offer->offer_nr }} @endif

{{ $order->title }}

{{ $order->order_nr }}
@if(session('success'))
{{ session('success') }}
@endif {{-- Workflow-Banner --}} @if($order->fk_workflow_id && $wfCurrentStation)
{{-- Zurück --}}
@if($wfPrevStation)
@csrf
@endif
{{-- Phase / Abteilung (Mitte) --}}
Phase {{ $order->current_phase }}: {{ $wfCurrentStation->department->name ?? '—' }}
{{-- Weiter --}}
@if($wfNextStation)
@csrf
@else Workflow abgeschlossen @endif
@if($wfCurrentStation->aufgabe)
{{ $wfCurrentStation->aufgabe }}
@endif
@endif {{-- Status-Leiste --}} @php $allOrderStatuses = \App\Models\PmsStatus::order()->where('is_deleted',0)->orderBy('sort')->get(); $allDeptStatuses = \App\Models\PmsStatus::dept()->where('is_deleted',0)->orderBy('sort')->get(); @endphp
AUFTRAGSSTATUS @foreach($allOrderStatuses as $s)
@csrf
@endforeach
ABT.-STATUS @foreach($allDeptStatuses as $s)
@csrf
@endforeach
{{-- Links: Stammdaten + Positionen --}}
{{-- Stammdaten --}}
Stammdaten Bearbeiten
{{-- Zeile 1: Datum · Standort · Projektart --}}
Auftragsdatum
{{ $order->order_date ? \Carbon\Carbon::parse($order->order_date)->format('d.m.Y') : '—' }}
Standort / Bauvorhaben
{{ $order->project_location?->name ?? '—' }}
Projektart
{{ $order->type?->name ?? '—' }}
{{-- Trennlinie --}}

{{-- Zeile 2: Kunde · Ansprechpartner · Erstellt von --}}
Kunde
{{ $order->customer?->name ?? '—' }}
Ansprechpartner
{{ $order->customer_contact ? $order->customer_contact->first_name . ' ' . $order->customer_contact->last_name : '—' }}
Erstellt von
{{ $order->created_by ? $order->created_by->first_name . ' ' . $order->created_by->last_name : '—' }}
{{-- Workflow + Auftragsbestätigung in einer Zeile --}} @if($order->workflow || $abFile)

@if($order->workflow)
Workflow
{{ $order->workflow->name }} @if($order->current_phase) Phase {{ $order->current_phase }} @endif
@endif @if($abFile)
Auftragsbestätigung
{{ $abFile->original_name }}
@endif @endif {{-- Hinweis (wenn vorhanden) --}} @if($order->notes)

Hinweis
{{ $order->notes }}
@endif
{{-- Positionen + PDF-Tab --}}
{{-- Aktions-Buttons --}}
Noch keine Positionen angelegt.
@foreach($order->positions as $i => $pos) @include('pms.orders._position_row', ['pos' => $pos, 'depth' => 0, 'nr' => ($i+1), 'readonly' => false]) @endforeach {{-- Inline-Eingabezeile --}}
@if($order->positions->count()) @php $netto = $order->positions->where('is_optional', 0)->sum('calculated_total'); $vatRate = (float)($order->vat_rate ?? 19); $vatFactor = $vatRate / 100; $mwst = $netto * $vatFactor; $brutto = $netto + $mwst; $rowStyle = 'd-flex align-items-center gap-2 px-4'; @endphp
{{-- Nettosumme --}}
NETTOSUMME {{ number_format($netto, 2, ',', '.') }} €
{{-- MwSt --}}
@if($order->vat_hinweis){{ $order->vat_hinweis }} · @endif UMSATZSTEUER {{ number_format($vatRate, 0) }} % {{ number_format($mwst, 2, ',', '.') }} €
{{-- Gesamtsumme --}}
GESAMTSUMME {{ number_format($brutto, 2, ',', '.') }} €
@endif
{{-- end tab-pane positionen --}} {{-- Tab: Dateien / Anhänge --}}
{{ $attachments->count() }} Datei(en) angehängt
@if($attachments->isEmpty())
Noch keine Dateien angehängt.
@else @foreach($attachments as $att) @php $ext = strtolower(pathinfo($att->filename, PATHINFO_EXTENSION)); $icon = match(true) { in_array($ext, ['pdf']) => ['bi-file-earmark-pdf', 'text-danger'], in_array($ext, ['jpg','jpeg','png','gif','webp','svg']) => ['bi-file-earmark-image', 'text-success'], in_array($ext, ['doc','docx']) => ['bi-file-earmark-word', 'text-primary'], in_array($ext, ['xls','xlsx','csv']) => ['bi-file-earmark-excel', 'text-success'], in_array($ext, ['zip','rar','7z']) => ['bi-file-earmark-zip', 'text-warning'], default => ['bi-file-earmark', 'text-muted'], }; @endphp @endforeach
Dateiname Größe Hochgeladen Aktionen
{{ $att->original_name ?? $att->filename }}
@if($att->filesize) {{ $att->filesize >= 1048576 ? number_format($att->filesize / 1048576, 1) . ' MB' : number_format($att->filesize / 1024, 0) . ' KB' }} @else — @endif {{ $att->created_at ? \Carbon\Carbon::parse($att->created_at)->format('d.m.Y H:i') : '—' }} Download @if(Auth::user()->get_employee->is_dms || Auth::user()->get_employee->is_mgt)
@csrf
@endif
@endif
{{-- end tab-pane dateien --}} {{-- Tab: Rechnungen --}}
{{ $invoices->count() }} Rechnung(en) für diesen Auftrag @php $hasOpenSchluss = $invoices->where('type','schluss')->where('status','!=','storniert')->count() > 0; @endphp
@if($invoices->isEmpty())
Noch keine Rechnungen vorhanden.
@else
@foreach($invoices as $inv) @endforeach
Nr. Kundennr. Typ Status Datum Netto Gesamt
{{ $inv->invoice_nr ?? '(Entwurf)' }} {{ $order->customer?->customer_code ?? '—' }} {{ $inv->type_labal }} {{ $inv->status_label }} {{ $inv->invoice_date ? \Carbon\Carbon::parse($inv->invoice_date)->format('d.m.Y') : '—' }} {{ number_format($inv->subtotal, 2, ',', '.') }} € {{ number_format($inv->total, 2, ',', '.') }} € @if($inv->status === 'entwurf') Bearbeiten @else Anzeigen @endif
@php $gestelltNetto = $invoices->where('status', '!=', 'storniert')->sum('subtotal'); $gestelltBrutto = $invoices->where('status', '!=', 'storniert')->sum('total'); $orderNetto = (float) \DB::table('pms_order_positions') ->where('fk_order_id', $order->id) ->where('is_deleted', 0) ->selectRaw('COALESCE(SUM(quantity * unit_price), 0) as t') ->value('t'); $orderBrutto = round($orderNetto * (1 + ($order->vat_rate ?? 19) / 100), 2); $offenNetto = max(0, $orderNetto - $gestelltNetto); $offenBrutto = max(0, $orderBrutto - $gestelltBrutto); $progressPct = $orderBrutto > 0 ? min(100, round($gestelltBrutto / $orderBrutto * 100)) : 0; @endphp
Gestellt Auftragssumme
Gestellt
{{ number_format($gestelltBrutto, 2, ',', '.') }} €
{{ number_format($gestelltNetto, 2, ',', '.') }} € netto
Auftragssumme
{{ number_format($orderBrutto, 2, ',', '.') }} €
{{ number_format($orderNetto, 2, ',', '.') }} € netto
Noch offen
{{ number_format($offenBrutto, 2, ',', '.') }} €
{{ number_format($offenNetto, 2, ',', '.') }} € netto
@endif
{{-- end tab-pane rechnungen --}}
{{-- end tab-content --}}
{{-- Rechts: Termine + Timeline --}}
{{-- Termine --}}
Termine @php $now = now(); $upcoming = $appointments->where('is_done', 0)->filter(fn($a) => $a->starts_at->gte($now))->sortBy('starts_at'); $missed = $appointments->where('is_done', 0)->filter(fn($a) => $a->starts_at->lt($now))->sortByDesc('starts_at'); $done = $appointments->where('is_done', 1)->sortByDesc('starts_at'); @endphp @if($upcoming->count()) {{ $upcoming->count() }} @endif @if($missed->count()) {{ $missed->count() }} verpasst @endif
@if($appointments->isEmpty())
Noch keine Termine vereinbart.
@else {{-- Bevorstehende --}} @foreach($upcoming as $apt)
{{ $apt->type_label }}
{{ $apt->title }}
{{ $apt->starts_at->format('d.m.Y H:i') }} @if($apt->ends_at) – {{ $apt->ends_at->format('H:i') }} @endif
@if($apt->notes)
{{ $apt->notes }}
@endif
@csrf
@csrf
@endforeach {{-- Verpasst --}} @if($missed->count())
VERPASST
@foreach($missed as $apt)
{{ $apt->type_label }}
{{ $apt->title }}
{{ $apt->starts_at->format('d.m.Y H:i') }} @if($apt->ends_at) – {{ $apt->ends_at->format('H:i') }} @endif
@if($apt->notes)
{{ $apt->notes }}
@endif
@csrf
@csrf
@endforeach
@endif {{-- Erledigte (eingeklappt) --}} @if($done->count())
@foreach($done as $apt)
{{ $apt->title }}
{{ $apt->starts_at->format('d.m.Y H:i') }}
@csrf
@csrf
@endforeach
@endif @endif
Verlauf / Hinweise
{{-- Neuer Eintrag --}}
@csrf
@foreach([ ['4','notes','bi-info-square-fill','Info','text-info'], ['0','call','bi-telephone-fill','Anruf','text-success'], ['1','mail','bi-envelope-fill','E-Mail','text-primary'], ['2','poste','bi-mailbox2','Post','text-secondary'], ['3','personally','bi-people-fill','Persönlich','text-warning'], ] as [$val,$rid,$ico,$lbl,$col]) @endforeach

{{-- Filter --}}
Filter: @foreach([ ['0','all','bi-list-ul','Alle'], ['1','fnotes','bi-info-square-fill','Info'], ['2','fcall','bi-telephone-fill','Anruf'], ['3','fmail','bi-envelope-fill','E-Mail'], ['4','fposte','bi-mailbox2','Post'], ['5','fpersonally','bi-people-fill','Person'], ] as [$val,$fid,$ico,$lbl]) @endforeach
{{-- Einträge --}}
@forelse($order->timeline->sortByDesc('created_at') as $entry) @php $ct = (int) $entry->contact_type; $isNote = $ct === 4; $isCall = $ct === 0; $isEmail = $ct === 1; $isPost = $ct === 2; $isPersonally = $ct === 3; if ($isNote) { $tlIcon = 'bi-info-square-fill'; $tlColor = '#0dcaf0'; } elseif ($isCall) { $tlIcon = 'bi-telephone-fill'; $tlColor = '#198754'; } elseif ($isEmail) { $tlIcon = 'bi-envelope-fill'; $tlColor = '#0d6efd'; } elseif ($isPost) { $tlIcon = 'bi-mailbox2'; $tlColor = '#6c757d'; } else { $tlIcon = 'bi-people-fill'; $tlColor = '#ffc107'; } @endphp
@if(!$isNote && $entry->contact_dst) {{ $entry->contact_dst }} @endif {{ $entry->created_at ? \Carbon\Carbon::parse($entry->created_at)->format('d.m.Y - H:i') : '—' }}
{!! $entry->message !!}
{{ $entry->employee?->first_name }} {{ $entry->employee?->last_name }}
@empty
Noch keine Einträge.
@endforelse
{{-- end scroll-wrapper --}}
{{-- Modal: Neue Rechnung erstellen --}} {{-- Formular für Inline-Position (außerhalb Tabelle, via form="inline-pos-form") --}}
@csrf
{{-- Modal: Leistungsbibliothek --}} {{-- Modal: Materialkatalog --}} {{-- Modals: Lohn / Geräte / Fremdleistung / Sonstiges --}} {{-- Modal: Dateien hochladen --}} {{-- Flatpickr --}} {{-- Modal: Neuer Termin --}} @endsection