Neustrukturierung Customer / Lead / Booking Phase 2

This commit is contained in:
Kevin Adametz 2026-05-28 17:10:37 +02:00
parent 313f0dbf4e
commit 6df9c401af
69 changed files with 3809 additions and 374 deletions

View file

@ -1,49 +1,58 @@
<div class="card mb-2 border-primary">
<h6 class="card-header bg-primary text-white py-2" data-toggle="collapse" data-target="#collapseBookingLead" aria-expanded="false" aria-controls="collapseBookingLead">
<h6 class="card-header bg-primary text-white py-2" data-toggle="collapse" data-target="#collapseBookingLead"
aria-expanded="false" aria-controls="collapseBookingLead">
<strong style="line-height: 1.6em">Anfrage</strong>
</h6>
<div class="collapse" id="collapseBookingLead">
<div class="card-body row">
@if($booking->lead->count())
@if ($booking->lead)
<div class="form-group col-sm-6">
<label class="form-label" for="lead_id">{{ __('Anfrage ID') }}</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<a class="text-primary" href="{{route('lead_detail', [$booking->lead->id])}}"><i class="fa fa-edit"></i></a></span>
<a class="text-primary" href="{{ route('lead_detail', [$booking->lead->id]) }}"><i
class="fa fa-edit"></i></a></span>
</div>
{{ Form::text('lead[id]', $booking->lead->id, array('placeholder'=>__('Anfrage ID'), 'class'=>'form-control', 'id'=>'lead_id', 'readonly')) }}
{{ Form::text('lead[id]', $booking->lead->id, ['placeholder' => __('Anfrage ID'), 'class' => 'form-control', 'id' => 'lead_id', 'readonly']) }}
</div>
</div>
<div class="form-group col-sm-6 col-md-6">
<label class="form-label" for="lead_status_id">{{ __('Status ändern') }} </label>
{{ Form::select('lead[status_id]', \App\Models\Lead::getStatusArray() , $booking->lead->status_id, array('class'=>'custom-select')) }}
<label class="form-label" for="lead_status_id">{{ __('Status ändern') }} </label>
{{ Form::select('lead[status_id]', \App\Models\Lead::getStatusArray(), $booking->lead->status_id, ['class' => 'custom-select']) }}
</div>
<div class="form-group col-sm-6">
<label class="custom-control custom-checkbox mt-2">
{!! Form::checkbox('lead[is_rebook]', 1, $booking->lead->is_rebook, ['class'=>'custom-control-input', 'readonly']) !!}
<span class="custom-control-label">{{__('Umbuchung abgeschlossen')}}</span>
{!! Form::checkbox('lead[is_rebook]', 1, $booking->lead->is_rebook, [
'class' => 'custom-control-input',
'readonly',
]) !!}
<span class="custom-control-label">{{ __('Umbuchung abgeschlossen') }}</span>
</label>
</div>
<div class="form-group col-sm-6">
<label class="custom-control custom-checkbox mt-2">
{!! Form::checkbox('lead[is_closed]', 1, $booking->lead->is_closed, ['class'=>'custom-control-input', 'readonly']) !!}
<span class="custom-control-label">{{__('Vorgang abgeschlossen')}}</span>
{!! Form::checkbox('lead[is_closed]', 1, $booking->lead->is_closed, [
'class' => 'custom-control-input',
'readonly',
]) !!}
<span class="custom-control-label">{{ __('Vorgang abgeschlossen') }}</span>
</label>
</div>
<div class="col-sm-12">
<div class="text-left mt-2">
<button type="submit" name="action" value="save_lead_status" class="btn btn-sm btn-secondary">Änderungen speichern</button>&nbsp;
<a href="{{route('leads')}}" class="btn btn-sm btn-default">{{ __('zur Übersicht') }}</a>
<button type="submit" name="action" value="save_lead_status"
class="btn btn-sm btn-secondary">Änderungen speichern</button>&nbsp;
<a href="{{ route('leads') }}" class="btn btn-sm btn-default">{{ __('zur Übersicht') }}</a>
</div>
</div>
@endif
</div>
</div>
</div>
</div>

View file

@ -64,7 +64,7 @@
@endif
@if (Auth::user()->isPermission('crm-bo'))
<li
class="sidenav-item{{ Request::is(['requests', 'bookings', 'booking/*', 'leads', 'lead/*', 'customers', 'customer/*', 'contacts', 'contact/*', 'customer_mails', 'customer_mail/*']) ? ' open' : '' }}">
class="sidenav-item{{ Request::is(['requests', 'bookings', 'booking/*', 'leads', 'lead/*', 'offers', 'offer/*', 'offer-templates', 'offer-template/*', 'customers', 'customer/*', 'contacts', 'contact/*', 'customer_mails', 'customer_mail/*']) ? ' open' : '' }}">
<a href="javascript:void(0)" class="sidenav-link sidenav-toggle">
<i class="sidenav-icon ion ion-md-bed"></i>
<div>Buchungen</div>
@ -93,6 +93,14 @@
</a>
</li>
@endif
@if (Auth::user()->isPermission('offers-r') || Auth::user()->isPermission('offers-w'))
<li class="sidenav-item{{ Request::is(['offers', 'offer/*']) ? ' active' : '' }}">
<a href="{{ route('offers') }}" class="sidenav-link"><i
class="sidenav-icon ion ion-md-document"></i>
<div>Angebote</div>
</a>
</li>
@endif
@if (Auth::user()->isPermission('crm-bo-cu'))
<li
class="sidenav-item{{ Request::is(['customers', 'customer/*']) ? ' active' : '' }}">

View file

@ -0,0 +1,13 @@
@extends('layouts.layout-2')
@section('content')
<h4 class="font-weight-bold py-3 mb-4">
{{ __('Angebot') }} {{ $offer->offer_number }} <small
class="text-muted">#{{ $offer->id }}</small>
</h4>
<div class="card p-3">
<p class="mb-0">Status: <span class="badge badge-secondary">{{ $offer->status }}</span></p>
<p class="text-muted small mb-0 mt-2">Detail-Editor, Tabs und Aktionen folgen in B3. Aktuelle
Version: V{{ $offer->currentVersion ? $offer->currentVersion->version_no : '—' }}.</p>
</div>
@endsection

View file

@ -0,0 +1,57 @@
@extends('layouts.layout-2')
@section('content')
<h4 class="font-weight-bold py-3 mb-4">
{{ __('Angebote') }}
</h4>
<p class="text-muted">Filter &amp; Aktionen erweitert Ticket B1. Die Tabelle nutzt die Route <code>data_table_offers</code>.</p>
<div class="card">
<div class="table-responsive-track" id="datatables-offers-scroll">
<div class="table-responsive-thumb" id="datatables-offers-thumb"></div>
</div>
<div class="card-datatable table-responsive" id="datatables-offers-table">
<table class="datatables-offers table table-striped table-bordered" id="datatables-offers">
<thead>
<tr>
<th style="max-width: 60px;">&nbsp;</th>
<th>ID</th>
<th>Nr.</th>
<th>Kontakt</th>
<th>Status</th>
<th>Erstellt von</th>
<th>Erstellt am</th>
</tr>
</thead>
</table>
</div>
</div>
<script>
$(function () {
var table = $('#datatables-offers').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('data_table_offers') !!}',
order: [[1, 'desc']],
columns: [
{data: 'action_edit', name: 'action_edit', orderable: false, searchable: false},
{data: 'id', name: 'offers.id'},
{data: 'offer_number', name: 'offers.offer_number'},
{data: 'contact_name', name: 'contact_name', orderable: false, searchable: false},
{data: 'status_badge', name: 'offers.status', orderable: true, searchable: false},
{data: 'created_name', name: 'created_name', orderable: false, searchable: false},
{data: 'created_at_fmt', name: 'offers.created_at', searchable: false}
],
bLengthChange: false,
iDisplayLength: 100,
language: {url: '/js/German.json'},
drawCallback: function () {
if (typeof dataTableScrollTrack === 'function') {
dataTableScrollTrack('#datatables-offers');
}
}
});
});
</script>
@endsection

View file

@ -0,0 +1,5 @@
{{-- Stub für A6 ersetzt durch B2 (modal-new-offer) --}}
<div class="p-2">
<p class="mb-0">Neues Angebot-Modal: Implementierung in Ticket B2
(<code>OfferService::createBlank / createFromInquiry</code>).</p>
</div>

View file

@ -0,0 +1,14 @@
@extends('layouts.layout-2')
@section('content')
<h4 class="font-weight-bold py-3 mb-4">
@if($id === 'new')
{{ __('Neue Vorlage') }}
@else
{{ __('Vorlage') }}: {{ $template->name }}
@endif
</h4>
<div class="card p-3">
<p class="text-muted mb-0">Vorlagen-Editor folgt in C1.</p>
</div>
@endsection

View file

@ -0,0 +1,14 @@
@extends('layouts.layout-2')
@section('content')
<h4 class="font-weight-bold py-3 mb-4">{{ __('Angebotsvorlagen') }}</h4>
<div class="list-group">
@forelse($templates as $t)
<a class="list-group-item list-group-item-action"
href="{{ route('offer_template_detail', ['id' => $t->id]) }}">{{ $t->name }}</a>
@empty
<p class="text-muted p-2 mb-0">Noch keine Vorlagen anlegen in C1.</p>
@endforelse
</div>
<a class="btn btn-primary mt-3" href="{{ route('offer_template_detail', ['id' => 'new']) }}">Neue Vorlage</a>
@endsection