DHL Modul v0.5 Shipping Label ok
This commit is contained in:
parent
480fdc65ed
commit
8fdaa0ba1d
122 changed files with 17938 additions and 2239 deletions
578
resources/views/admin/dhl/cockpit.blade.php
Normal file
578
resources/views/admin/dhl/cockpit.blade.php
Normal file
|
|
@ -0,0 +1,578 @@
|
|||
@extends('layouts.layout-2')
|
||||
|
||||
@section('content')
|
||||
|
||||
<h4 class="font-weight-bold py-2 mb-2">
|
||||
<i class="fas fa-shipping-fast text-primary"></i>
|
||||
DHL Cockpit
|
||||
</h4>
|
||||
|
||||
<!-- Statistics Cards -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-xl-3 col-md-6 mb-3">
|
||||
<div class="card bg-primary text-white">
|
||||
<div class="card-body">
|
||||
<div class="media align-items-center">
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0 mb-1">{{ number_format($stats['total_shipments']) }}</h5>
|
||||
<small class="mb-0">Sendungen gesamt</small>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<i class="fas fa-boxes fa-2x opacity-75"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-3 col-md-6 mb-3">
|
||||
<div class="card bg-warning text-white">
|
||||
<div class="card-body">
|
||||
<div class="media align-items-center">
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0 mb-1">{{ number_format($stats['pending_shipments']) }}</h5>
|
||||
<small class="mb-0">In Bearbeitung</small>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<i class="fas fa-clock fa-2x opacity-75"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-3 col-md-6 mb-3">
|
||||
<div class="card bg-success text-white">
|
||||
<div class="card-body">
|
||||
<div class="media align-items-center">
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0 mb-1">{{ number_format($stats['shipped_today']) }}</h5>
|
||||
<small class="mb-0">Heute versandt</small>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<i class="fas fa-truck fa-2x opacity-75"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-3 col-md-6 mb-3">
|
||||
<div class="card bg-info text-white">
|
||||
<div class="card-body">
|
||||
<div class="media align-items-center">
|
||||
<div class="media-body">
|
||||
<h5 class="mt-0 mb-1">{{ number_format($stats['returns_count']) }}</h5>
|
||||
<small class="mb-0">Retouren</small>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<i class="fas fa-undo fa-2x opacity-75"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filters Card -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-filter text-primary"></i>
|
||||
Filter & Suche
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="GET" action="{{ route('admin.dhl.cockpit') }}" id="dhl-filter-form">
|
||||
<div class="form-row">
|
||||
<div class="col-md-3 mb-3">
|
||||
<label for="type">Sendungstyp</label>
|
||||
<select class="form-control custom-select" name="type" id="type">
|
||||
<option value="">Alle Typen</option>
|
||||
<option value="outbound" {{ request('type') == 'outbound' ? 'selected' : '' }}>Ausgehend</option>
|
||||
<option value="return" {{ request('type') == 'return' ? 'selected' : '' }}>Retoure</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3 mb-3">
|
||||
<label for="status">Status</label>
|
||||
<select class="form-control custom-select" name="status" id="status">
|
||||
<option value="">Alle Status</option>
|
||||
<option value="pending" {{ request('status') == 'pending' ? 'selected' : '' }}>Wartend</option>
|
||||
<option value="created" {{ request('status') == 'created' ? 'selected' : '' }}>Erstellt</option>
|
||||
<option value="shipped" {{ request('status') == 'shipped' ? 'selected' : '' }}>Versendet</option>
|
||||
<option value="delivered" {{ request('status') == 'delivered' ? 'selected' : '' }}>Zugestellt</option>
|
||||
<option value="cancelled" {{ request('status') == 'cancelled' ? 'selected' : '' }}>Storniert</option>
|
||||
<option value="failed" {{ request('status') == 'failed' ? 'selected' : '' }}>Fehler</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3 mb-3">
|
||||
<label for="date_from">Von Datum</label>
|
||||
<input type="date" class="form-control" name="date_from" id="date_from" value="{{ request('date_from') }}">
|
||||
</div>
|
||||
|
||||
<div class="col-md-3 mb-3">
|
||||
<label for="date_to">Bis Datum</label>
|
||||
<input type="date" class="form-control" name="date_to" id="date_to" value="{{ request('date_to') }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col-md-8 mb-3">
|
||||
<label for="search">Suche (Sendungsnummer, Tracking-Nummer, Bestellungs-ID)</label>
|
||||
<input type="text" class="form-control" name="search" id="search" value="{{ request('search') }}" placeholder="Suchen...">
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 mb-3 d-flex align-items-end">
|
||||
<button type="submit" class="btn btn-primary mr-2">
|
||||
<i class="fas fa-search"></i> Filtern
|
||||
</button>
|
||||
<a href="{{ route('admin.dhl.cockpit') }}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-sync"></i> Zurücksetzen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick Actions -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-bolt text-warning"></i>
|
||||
Schnellaktionen
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="card bg-light border-primary h-100">
|
||||
<div class="card-body text-center">
|
||||
<i class="fas fa-plus-circle fa-3x text-primary mb-3"></i>
|
||||
<h5 class="card-title">Neue Sendung erstellen</h5>
|
||||
<p class="card-text text-muted">
|
||||
Erstellen Sie eine neue DHL-Sendung basierend auf einer bestehenden Bestellung.
|
||||
</p>
|
||||
<button type="button" class="btn btn-primary"
|
||||
data-toggle="modal"
|
||||
data-id="new"
|
||||
data-target="#modals-load-content"
|
||||
data-action="create-dhl-shipment"
|
||||
data-route="{{ route('modal_load') }}">
|
||||
<i class="fas fa-shipping-fast"></i> Sendung erstellen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="card bg-light border-info h-100">
|
||||
<div class="card-body text-center">
|
||||
<i class="fas fa-search fa-3x text-info mb-3"></i>
|
||||
<h5 class="card-title">Sendung anzeigen</h5>
|
||||
<p class="card-text text-muted">
|
||||
Suchen und anzeigen einer bestimmten Sendung nach ID oder Tracking-Nummer.
|
||||
</p>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-info dropdown-toggle" type="button" id="showDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fas fa-eye"></i> Sendung anzeigen
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="showDropdown">
|
||||
<h6 class="dropdown-header">Sendung finden:</h6>
|
||||
<a class="dropdown-item" href="#" onclick="promptShipmentId()">
|
||||
<i class="fas fa-hashtag"></i> Sendungs-ID eingeben
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" onclick="promptTrackingNumber()">
|
||||
<i class="fas fa-barcode"></i> Tracking-Nummer eingeben
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" onclick="$('#search').focus();">
|
||||
<i class="fas fa-filter"></i> Filter verwenden
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="card bg-light border-secondary h-100">
|
||||
<div class="card-body text-center">
|
||||
<i class="fas fa-plug fa-3x text-secondary mb-3"></i>
|
||||
<h5 class="card-title">API Login Test</h5>
|
||||
<p class="card-text text-muted">
|
||||
Überprüfen Sie, ob die in der <code>.env</code>-Datei hinterlegten DHL-Zugangsdaten korrekt sind.
|
||||
</p>
|
||||
<button type="button" class="btn btn-secondary" id="test-dhl-login-btn">
|
||||
<span class="spinner-border spinner-border-sm" role="status" style="display: none;"></span>
|
||||
<i class="fas fa-key"></i> Login testen
|
||||
</button>
|
||||
<div id="dhl-test-result" class="mt-3 text-left"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Batch Actions -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-list text-primary"></i>
|
||||
Sendungsübersicht
|
||||
</h5>
|
||||
|
||||
<div class="batch-actions" style="display: none;">
|
||||
<button type="button" class="btn btn-sm btn-warning batch-action-btn" data-action="cancel">
|
||||
<i class="fas fa-ban"></i> Ausgewählte stornieren
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-info batch-action-btn" data-action="update_tracking">
|
||||
<i class="fas fa-sync"></i> Tracking aktualisieren
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary batch-action-btn" data-action="download_labels">
|
||||
<i class="fas fa-download"></i> Labels herunterladen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-datatable table-responsive">
|
||||
<table class="table table-striped table-bordered" id="dhl-shipments-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 40px;">
|
||||
<label class="custom-control custom-checkbox mb-0">
|
||||
<input type="checkbox" class="custom-control-input" id="select-all">
|
||||
<span class="custom-control-label"></span>
|
||||
</label>
|
||||
</th>
|
||||
<th>#</th>
|
||||
<th>Typ</th>
|
||||
<th>Bestellung</th>
|
||||
<th>Kunde</th>
|
||||
<th>Sendungsnummer</th>
|
||||
<th>Status</th>
|
||||
<th>Tracking-Status</th>
|
||||
<th>Gewicht</th>
|
||||
<th>Erstellt</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{-- Data will be loaded by DataTables --}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- Pagination will be handled by DataTables --}}
|
||||
</div>
|
||||
|
||||
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// DataTable initialization
|
||||
var dhlTable = $('#dhl-shipments-table').DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
ajax: {
|
||||
url: "{{ route('admin.dhl.datatable') }}",
|
||||
type: "POST",
|
||||
data: function (d) {
|
||||
d._token = '{{ csrf_token() }}';
|
||||
d.type = $('#type').val();
|
||||
d.status = $('#status').val();
|
||||
d.date_from = $('#date_from').val();
|
||||
d.date_to = $('#date_to').val();
|
||||
d.search = $('#search').val();
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
{ data: 'checkbox', name: 'checkbox', orderable: false, searchable: false },
|
||||
{ data: 'id', name: 'id' },
|
||||
{ data: 'type', name: 'type' },
|
||||
{ data: 'order', name: 'order_id' },
|
||||
{ data: 'customer', name: 'shoppingOrder.shopping_user.billing_firstname' },
|
||||
{ data: 'dhl_shipment_no', name: 'dhl_shipment_no' },
|
||||
{ data: 'status', name: 'status' },
|
||||
{ data: 'tracking_status', name: 'tracking_status', orderable: false, searchable: false },
|
||||
{ data: 'weight_kg', name: 'weight_kg' },
|
||||
{ data: 'created_at', name: 'created_at' },
|
||||
{ data: 'actions', name: 'actions', orderable: false, searchable: false }
|
||||
],
|
||||
order: [[1, 'desc']],
|
||||
language: {
|
||||
url: "//cdn.datatables.net/plug-ins/1.10.25/i18n/German.json"
|
||||
},
|
||||
// Re-initialize tooltips on each table draw
|
||||
drawCallback: function () {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
}
|
||||
});
|
||||
|
||||
// Handle filter form submission
|
||||
$('#dhl-filter-form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
dhlTable.draw();
|
||||
});
|
||||
|
||||
// Auto-reload on specific filter changes
|
||||
$('#type, #status').change(function() {
|
||||
dhlTable.draw();
|
||||
});
|
||||
|
||||
// Tooltip initialization for static elements
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
|
||||
// --- DHL LOGIN TEST ---
|
||||
$('#test-dhl-login-btn').click(function() {
|
||||
var btn = $(this);
|
||||
var spinner = btn.find('.spinner-border');
|
||||
var resultContainer = $('#dhl-test-result');
|
||||
|
||||
btn.prop('disabled', true);
|
||||
spinner.show();
|
||||
resultContainer.html('');
|
||||
|
||||
$.ajax({
|
||||
url: '{{ route("admin.dhl.test_login") }}',
|
||||
method: 'POST',
|
||||
data: {
|
||||
_token: '{{ csrf_token() }}'
|
||||
},
|
||||
success: function(response) {
|
||||
var alertClass = response.success ? 'alert-success' : 'alert-danger';
|
||||
var icon = response.success ? 'fas fa-check-circle' : 'fas fa-times-circle';
|
||||
var resultHtml = `
|
||||
<div class="alert ${alertClass} d-flex align-items-center" role="alert">
|
||||
<i class="${icon} mr-2"></i>
|
||||
<div>
|
||||
${response.message}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
resultContainer.html(resultHtml);
|
||||
},
|
||||
error: function(xhr) {
|
||||
var errorHtml = `
|
||||
<div class="alert alert-danger d-flex align-items-center" role="alert">
|
||||
<i class="fas fa-server mr-2"></i>
|
||||
<div>
|
||||
Ein Serverfehler ist aufgetreten. Prüfen Sie die Browser-Konsole und die Laravel-Logs.
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
resultContainer.html(errorHtml);
|
||||
},
|
||||
complete: function() {
|
||||
btn.prop('disabled', false);
|
||||
spinner.hide();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// --- BATCH & ROW ACTIONS ---
|
||||
|
||||
// Select All functionality
|
||||
$('#dhl-shipments-table').on('change', '#select-all', function() {
|
||||
var checked = $(this).is(':checked');
|
||||
$('.shipment-checkbox').prop('checked', checked);
|
||||
toggleBatchActions();
|
||||
});
|
||||
|
||||
// Individual checkbox change
|
||||
$('#dhl-shipments-table').on('change', '.shipment-checkbox', function() {
|
||||
var totalCheckboxes = $('.shipment-checkbox').length;
|
||||
var checkedCheckboxes = $('.shipment-checkbox:checked').length;
|
||||
|
||||
$('#select-all').prop('checked', totalCheckboxes > 0 && totalCheckboxes === checkedCheckboxes);
|
||||
toggleBatchActions();
|
||||
});
|
||||
|
||||
// Toggle batch actions visibility
|
||||
function toggleBatchActions() {
|
||||
var checkedCount = $('.shipment-checkbox:checked').length;
|
||||
if (checkedCount > 0) {
|
||||
$('.batch-actions').show();
|
||||
} else {
|
||||
$('.batch-actions').hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Batch actions
|
||||
$('.batch-action-btn').click(function() {
|
||||
var action = $(this).data('action');
|
||||
var selectedIds = $('.shipment-checkbox:checked').map(function() {
|
||||
return $(this).val();
|
||||
}).get();
|
||||
|
||||
if (selectedIds.length === 0) {
|
||||
alert('Bitte wählen Sie mindestens eine Sendung aus.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm('Möchten Sie diese Aktion für ' + selectedIds.length + ' Sendung(en) ausführen?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Perform batch action
|
||||
$.ajax({
|
||||
url: '{{ route("admin.dhl.batch-action") }}',
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: action,
|
||||
shipment_ids: selectedIds,
|
||||
_token: '{{ csrf_token() }}'
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
showAlert('success', response.message);
|
||||
location.reload();
|
||||
} else {
|
||||
showAlert('error', response.message);
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
showAlert('error', 'Fehler bei der Stapelverarbeitung.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Individual action buttons (delegated events)
|
||||
$('#dhl-shipments-table').on('click', '.cancel-shipment-btn', function() {
|
||||
var shipmentId = $(this).data('shipment-id');
|
||||
|
||||
if (!confirm('Möchten Sie diese Sendung wirklich stornieren?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: `/admin/dhl/shipment/${shipmentId}/cancel`,
|
||||
method: 'DELETE',
|
||||
data: {
|
||||
_token: '{{ csrf_token() }}'
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
showAlert('success', response.message);
|
||||
location.reload();
|
||||
} else {
|
||||
showAlert('error', response.message);
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
showAlert('error', 'Fehler beim Stornieren der Sendung.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#dhl-shipments-table').on('click', '.create-return-btn', function() {
|
||||
var shipmentId = $(this).data('shipment-id');
|
||||
|
||||
if (!confirm('Möchten Sie ein Retourenlabel für diese Sendung erstellen?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: `/admin/dhl/shipment/${shipmentId}/return-label`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
_token: '{{ csrf_token() }}'
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
showAlert('success', response.message);
|
||||
location.reload();
|
||||
} else {
|
||||
showAlert('error', response.message);
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
showAlert('error', 'Fehler beim Erstellen des Retourenlabels.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#dhl-shipments-table').on('click', '.update-tracking-btn', function() {
|
||||
var shipmentId = $(this).data('shipment-id');
|
||||
|
||||
$.ajax({
|
||||
url: `/admin/dhl/shipment/${shipmentId}/update-tracking`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
_token: '{{ csrf_token() }}'
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
showAlert('success', response.message);
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 2000);
|
||||
} else {
|
||||
showAlert('error', response.message);
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
showAlert('error', 'Fehler beim Aktualisieren der Tracking-Informationen.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Remove old auto-submit logic
|
||||
/*
|
||||
$('#type, #status').change(function() {
|
||||
$('#dhl-filter-form').submit();
|
||||
});
|
||||
*/
|
||||
|
||||
function promptShipmentId() {
|
||||
var shipmentId = prompt('Bitte geben Sie die Sendungs-ID ein:');
|
||||
if (shipmentId && shipmentId.trim()) {
|
||||
shipmentId = shipmentId.trim();
|
||||
if (!isNaN(shipmentId) && shipmentId > 0) {
|
||||
window.location.href = '{{ route("admin.dhl.show", ":shipmentId") }}'.replace(':shipmentId', shipmentId);
|
||||
} else {
|
||||
alert('Bitte geben Sie eine gültige Sendungs-ID (Zahl) ein.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function promptTrackingNumber() {
|
||||
var trackingNumber = prompt('Bitte geben Sie die Tracking-Nummer ein:');
|
||||
if (trackingNumber && trackingNumber.trim()) {
|
||||
trackingNumber = trackingNumber.trim();
|
||||
if (trackingNumber.length >= 10) {
|
||||
// Use search functionality to find by tracking number
|
||||
$('#search').val(trackingNumber);
|
||||
$('#dhl-filter-form').submit();
|
||||
} else {
|
||||
alert('Bitte geben Sie eine gültige Tracking-Nummer ein (mindestens 10 Zeichen).');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Alert helper function
|
||||
function showAlert(type, message) {
|
||||
var alertClass = type === 'success' ? 'alert-success' : 'alert-danger';
|
||||
var alertHtml = `
|
||||
<div class="alert ${alertClass} alert-dismissible fade show" role="alert">
|
||||
${message}
|
||||
<button type="button" class="close" data-dismiss="alert">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
$('h4.font-weight-bold').after(alertHtml);
|
||||
|
||||
// Auto-hide after 5 seconds
|
||||
setTimeout(function() {
|
||||
$('.alert').alert('close');
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
428
resources/views/admin/dhl/create.blade.php
Normal file
428
resources/views/admin/dhl/create.blade.php
Normal file
|
|
@ -0,0 +1,428 @@
|
|||
@extends('layouts.layout-2')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center py-2 mb-4">
|
||||
<h4 class="font-weight-bold mb-0">
|
||||
<i class="fas fa-shipping-fast text-primary"></i>
|
||||
DHL Sendung erstellen
|
||||
</h4>
|
||||
<a href="{{ route('admin.dhl.cockpit') }}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Zurück zum Cockpit
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Order Information Card -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-shopping-cart text-info"></i>
|
||||
Bestellinformationen
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<table class="table table-sm">
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Bestellungs-ID:</td>
|
||||
<td>#{{ $order->id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Kunde:</td>
|
||||
<td>
|
||||
{{ $order->user->first_name ?? '' }} {{ $order->user->last_name ?? '' }}
|
||||
<br>
|
||||
<small class="text-muted">{{ $order->user->email ?? '' }}</small>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Bestelldatum:</td>
|
||||
<td>{{ $order->created_at->format('d.m.Y H:i') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Bestellwert:</td>
|
||||
<td><strong>{{ number_format($order->order_total, 2) }} €</strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<table class="table table-sm">
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Lieferadresse:</td>
|
||||
<td>
|
||||
{{ $order->shipping_first_name ?? $order->user->first_name }} {{ $order->shipping_last_name ?? $order->user->last_name }}<br>
|
||||
{{ $order->shipping_street ?? $order->user->street }} {{ $order->shipping_house_number ?? $order->user->house_number }}<br>
|
||||
{{ $order->shipping_postcode ?? $order->user->postcode }} {{ $order->shipping_city ?? $order->user->city }}<br>
|
||||
{{ $order->shippingCountry->name ?? 'Deutschland' }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Status:</td>
|
||||
<td>
|
||||
<span class="badge badge-{{ $order->status == 'completed' ? 'success' : 'warning' }}">
|
||||
{{ $order->status }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Artikel:</td>
|
||||
<td>{{ $order->items->count() }} Artikel</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Order Items Card -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-list text-success"></i>
|
||||
Artikel in der Bestellung
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Artikel</th>
|
||||
<th>Menge</th>
|
||||
<th>Einzelpreis</th>
|
||||
<th>Gesamtpreis</th>
|
||||
<th>Gewicht (kg)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@php $totalWeight = 0; @endphp
|
||||
@foreach($order->items as $item)
|
||||
@php
|
||||
$itemWeight = ($item->product->weight ?? 0) * $item->qty;
|
||||
$totalWeight += $itemWeight;
|
||||
@endphp
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{{ $item->product->name ?? 'Unbekanntes Produkt' }}</strong>
|
||||
@if($item->product->number)
|
||||
<br>
|
||||
<small class="text-muted">Art.-Nr: {{ $item->product->number }}</small>
|
||||
@endif
|
||||
</td>
|
||||
<td>{{ $item->qty }}</td>
|
||||
<td>{{ number_format($item->price, 2) }} €</td>
|
||||
<td>{{ number_format($item->price * $item->qty, 2) }} €</td>
|
||||
<td>{{ number_format($itemWeight, 3) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="table-info font-weight-semibold">
|
||||
<td colspan="4">Geschätztes Gesamtgewicht:</td>
|
||||
<td>{{ number_format($totalWeight, 3) }} kg</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Shipment Creation Form -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-plus-circle text-primary"></i>
|
||||
Sendung konfigurieren
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="create-shipment-form">
|
||||
@csrf
|
||||
<input type="hidden" name="order_id" value="{{ $order->id }}">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="weight" class="font-weight-semibold">
|
||||
<i class="fas fa-weight"></i>
|
||||
Versandgewicht (kg) <span class="text-danger">*</span>
|
||||
</label>
|
||||
<input type="number"
|
||||
class="form-control"
|
||||
id="weight"
|
||||
name="weight"
|
||||
min="0.1"
|
||||
max="31.5"
|
||||
step="0.1"
|
||||
value="{{ max(0.5, $totalWeight) }}"
|
||||
required>
|
||||
<small class="form-text text-muted">
|
||||
Mindestens 0.1 kg, maximal 31.5 kg (DHL Paket Limit)
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="product_code" class="font-weight-semibold">
|
||||
<i class="fas fa-cube"></i>
|
||||
DHL Produktcode
|
||||
</label>
|
||||
<select class="form-control" id="product_code" name="product_code">
|
||||
<option value="V01PAK">V01PAK - DHL Paket</option>
|
||||
<option value="V53WPAK">V53WPAK - DHL Paket International</option>
|
||||
<option value="V54EPAK">V54EPAK - DHL Express</option>
|
||||
</select>
|
||||
<small class="form-text text-muted">
|
||||
Standardmäßig DHL Paket für nationale Sendungen
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="priority" class="font-weight-semibold">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
Priorität
|
||||
</label>
|
||||
<select class="form-control" id="priority" name="priority">
|
||||
<option value="normal">Normal</option>
|
||||
<option value="high">Hoch (Express-Queue)</option>
|
||||
</select>
|
||||
<small class="form-text text-muted">
|
||||
Hohe Priorität für dringende Sendungen
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label class="font-weight-semibold">
|
||||
<i class="fas fa-cog"></i>
|
||||
Zusätzliche Optionen
|
||||
</label>
|
||||
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox"
|
||||
class="custom-control-input"
|
||||
id="auto_track"
|
||||
name="auto_track"
|
||||
checked>
|
||||
<label class="custom-control-label" for="auto_track">
|
||||
Automatisches Tracking aktivieren
|
||||
</label>
|
||||
<small class="form-text text-muted">
|
||||
Startet automatische Sendungsverfolgung nach Erstellung
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card bg-light">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">
|
||||
<i class="fas fa-info-circle text-info"></i>
|
||||
Versandhinweise
|
||||
</h6>
|
||||
<ul class="mb-0 small">
|
||||
<li>Die Sendung wird asynchron erstellt</li>
|
||||
<li>Sie erhalten eine Benachrichtigung nach Fertigstellung</li>
|
||||
<li>Das Versandlabel wird automatisch generiert</li>
|
||||
<li>Bei aktiviertem Auto-Tracking wird die Sendung überwacht</li>
|
||||
@if($totalWeight > 10)
|
||||
<li class="text-warning">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
Hohes Gewicht - prüfen Sie die Verpackung
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="form-group mb-0">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<small class="text-muted">
|
||||
* Pflichtfelder | Geschätzte Verarbeitungszeit: 2-5 Minuten
|
||||
</small>
|
||||
</div>
|
||||
<div>
|
||||
<button type="button"
|
||||
class="btn btn-secondary mr-2"
|
||||
onclick="window.location.href='{{ route('admin.dhl.cockpit') }}'">
|
||||
<i class="fas fa-times"></i>
|
||||
Abbrechen
|
||||
</button>
|
||||
<button type="submit"
|
||||
class="btn btn-primary"
|
||||
id="submit-btn">
|
||||
<i class="fas fa-shipping-fast"></i>
|
||||
Sendung erstellen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Progress Modal -->
|
||||
<div class="modal fade" id="progress-modal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">
|
||||
<i class="fas fa-cog fa-spin text-primary"></i>
|
||||
Sendung wird erstellt
|
||||
</h5>
|
||||
</div>
|
||||
<div class="modal-body text-center">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
<p class="mt-3 mb-0">
|
||||
Bitte warten Sie, während die DHL-Sendung erstellt wird...<br>
|
||||
<small class="text-muted">Dies kann einige Minuten dauern.</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Form submission
|
||||
$('#create-shipment-form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var formData = $(this).serialize();
|
||||
var submitBtn = $('#submit-btn');
|
||||
|
||||
// Disable submit button and show loading
|
||||
submitBtn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Wird erstellt...');
|
||||
|
||||
// Show progress modal
|
||||
$('#progress-modal').modal('show');
|
||||
|
||||
$.ajax({
|
||||
url: '{{ route("admin.dhl.store") }}',
|
||||
method: 'POST',
|
||||
data: formData,
|
||||
success: function(response) {
|
||||
$('#progress-modal').modal('hide');
|
||||
|
||||
if (response.success) {
|
||||
// Show success alert
|
||||
showAlert('success', response.message);
|
||||
|
||||
// Redirect to cockpit after 3 seconds
|
||||
setTimeout(function() {
|
||||
window.location.href = '{{ route("admin.dhl.cockpit") }}';
|
||||
}, 3000);
|
||||
} else {
|
||||
showAlert('error', response.message);
|
||||
resetForm();
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
$('#progress-modal').modal('hide');
|
||||
|
||||
var errorMessage = 'Fehler beim Erstellen der Sendung.';
|
||||
if (xhr.responseJSON && xhr.responseJSON.message) {
|
||||
errorMessage = xhr.responseJSON.message;
|
||||
} else if (xhr.responseJSON && xhr.responseJSON.errors) {
|
||||
var errors = xhr.responseJSON.errors;
|
||||
errorMessage = Object.values(errors).flat().join('<br>');
|
||||
}
|
||||
|
||||
showAlert('error', errorMessage);
|
||||
resetForm();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Reset form function
|
||||
function resetForm() {
|
||||
var submitBtn = $('#submit-btn');
|
||||
submitBtn.prop('disabled', false).html('<i class="fas fa-shipping-fast"></i> Sendung erstellen');
|
||||
}
|
||||
|
||||
// Weight input validation
|
||||
$('#weight').on('input', function() {
|
||||
var weight = parseFloat($(this).val());
|
||||
var weightInput = $(this);
|
||||
var feedback = weightInput.siblings('.invalid-feedback');
|
||||
|
||||
// Remove existing feedback
|
||||
feedback.remove();
|
||||
weightInput.removeClass('is-invalid');
|
||||
|
||||
if (weight < 0.1) {
|
||||
weightInput.addClass('is-invalid');
|
||||
weightInput.after('<div class="invalid-feedback">Mindestgewicht: 0.1 kg</div>');
|
||||
} else if (weight > 31.5) {
|
||||
weightInput.addClass('is-invalid');
|
||||
weightInput.after('<div class="invalid-feedback">Maximalgewicht: 31.5 kg (DHL Paket Limit)</div>');
|
||||
} else if (weight > 10) {
|
||||
weightInput.after('<div class="text-warning small"><i class="fas fa-exclamation-triangle"></i> Hohes Gewicht - prüfen Sie die Verpackung</div>');
|
||||
}
|
||||
});
|
||||
|
||||
// Product code change handler
|
||||
$('#product_code').change(function() {
|
||||
var productCode = $(this).val();
|
||||
var weightInput = $('#weight');
|
||||
var maxWeight = 31.5;
|
||||
|
||||
// Adjust weight limits based on product
|
||||
if (productCode === 'V54EPAK') {
|
||||
maxWeight = 31.5;
|
||||
} else if (productCode === 'V53WPAK') {
|
||||
maxWeight = 20;
|
||||
}
|
||||
|
||||
weightInput.attr('max', maxWeight);
|
||||
|
||||
// Validate current weight
|
||||
$('#weight').trigger('input');
|
||||
});
|
||||
|
||||
// Alert helper function
|
||||
function showAlert(type, message) {
|
||||
var alertClass = type === 'success' ? 'alert-success' : 'alert-danger';
|
||||
var iconClass = type === 'success' ? 'fas fa-check-circle' : 'fas fa-exclamation-circle';
|
||||
|
||||
var alertHtml = `
|
||||
<div class="alert ${alertClass} alert-dismissible fade show" role="alert">
|
||||
<i class="${iconClass}"></i>
|
||||
${message}
|
||||
<button type="button" class="close" data-dismiss="alert">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
$('.py-2.mb-4').after(alertHtml);
|
||||
|
||||
// Scroll to top
|
||||
$('html, body').animate({ scrollTop: 0 }, 500);
|
||||
|
||||
// Auto-hide success alerts after 5 seconds
|
||||
if (type === 'success') {
|
||||
setTimeout(function() {
|
||||
$('.alert-success').alert('close');
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent modal from closing on backdrop click
|
||||
$('#progress-modal').modal({
|
||||
backdrop: 'static',
|
||||
keyboard: false
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
498
resources/views/admin/dhl/modal_create_shipment.blade.php
Normal file
498
resources/views/admin/dhl/modal_create_shipment.blade.php
Normal file
|
|
@ -0,0 +1,498 @@
|
|||
{{--
|
||||
DHL Shipment Creation Modal
|
||||
|
||||
This view is optimized to work with data prepared by DhlModalService.
|
||||
The service handles address parsing, validation, and data preparation.
|
||||
--}}
|
||||
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">
|
||||
<i class="fas fa-shipping-fast text-primary"></i>
|
||||
DHL Sendung erstellen
|
||||
</h5>
|
||||
<button type="button" class="close" data-dismiss="modal">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{{-- Display any errors at the top --}}
|
||||
@if(!empty($errors))
|
||||
<div class="alert alert-danger mx-3 mt-3">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<strong>Fehler:</strong>
|
||||
<ul class="mb-0 mt-1">
|
||||
@foreach($errors as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Display warnings --}}
|
||||
@if(!empty($warnings))
|
||||
<div class="alert alert-warning mx-3 mt-3">
|
||||
<i class="fas fa-exclamation-circle"></i>
|
||||
<strong>Achtung:</strong>
|
||||
<ul class="mb-0 mt-1">
|
||||
@foreach($warnings as $warning)
|
||||
<li>{{ $warning }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($order)
|
||||
<form id="modal-create-shipment-form" method="POST" action="{{ route('admin.dhl.store') }}">
|
||||
@csrf
|
||||
<input type="hidden" name="order_id" value="{{ $order->id }}">
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
{{-- Left Column: Order Info --}}
|
||||
<div class="col-md-6">
|
||||
<h6 class="text-primary mb-3">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
Bestellinformationen
|
||||
</h6>
|
||||
|
||||
<div class="card bg-light">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">Bestellung #{{ $order->id }}</h6>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<small class="text-muted d-block">Kunde:</small>
|
||||
<strong>{{ $order->shopping_user->billing_firstname ?? '' }} {{ $order->shopping_user->billing_lastname ?? '' }}</strong>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<small class="text-muted d-block">Datum:</small>
|
||||
<strong>{{ $order->created_at->format('d.m.Y') }}</strong>
|
||||
</div>
|
||||
<div class="col-6 mt-2">
|
||||
<small class="text-muted d-block">Wert:</small>
|
||||
<strong>{{ number_format($order->total, 2) }} €</strong>
|
||||
</div>
|
||||
<div class="col-6 mt-2">
|
||||
<small class="text-muted d-block">Artikel:</small>
|
||||
<strong>{{ $order->shopping_order_items->count() }} Stück</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Right Column: Shipment Config --}}
|
||||
<div class="col-md-6">
|
||||
<h6 class="text-primary mb-3">
|
||||
<i class="fas fa-cog"></i>
|
||||
Sendungskonfiguration
|
||||
</h6>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="modal-weight" class="font-weight-semibold">
|
||||
<i class="fas fa-weight"></i>
|
||||
Gewicht (kg) <span class="text-danger">*</span>
|
||||
</label>
|
||||
<input type="number"
|
||||
class="form-control"
|
||||
id="modal-weight"
|
||||
name="weight"
|
||||
min="0.1"
|
||||
max="31.5"
|
||||
step="0.1"
|
||||
value="{{ number_format($orderWeight, 1) }}"
|
||||
required>
|
||||
<small class="form-text text-muted">
|
||||
Berechnet: {{ number_format($orderWeight, 1) }} kg
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="modal-product-code" class="font-weight-semibold">
|
||||
<i class="fas fa-cube"></i>
|
||||
Produktcode
|
||||
</label>
|
||||
<select class="form-control custom-select" id="modal-product-code" name="product_code">
|
||||
@foreach($productCodes as $code => $name)
|
||||
<option value="{{ $code }}">{{ $code }} - {{ $name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="modal-priority" class="font-weight-semibold">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
Priorität
|
||||
</label>
|
||||
<select class="form-control custom-select" id="modal-priority" name="priority">
|
||||
<option value="normal">Normal</option>
|
||||
<option value="high">Hoch</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox"
|
||||
class="custom-control-input"
|
||||
id="modal-auto-track"
|
||||
name="auto_track"
|
||||
value="1"
|
||||
checked>
|
||||
<label class="custom-control-label" for="modal-auto-track">
|
||||
Automatisches Tracking
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{{-- Shipping Address Section --}}
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h6 class="text-primary mb-3">
|
||||
<i class="fas fa-map-marker-alt"></i>
|
||||
Lieferadresse
|
||||
@if(!empty($warnings))
|
||||
<small class="text-warning">(Bitte Adresse prüfen)</small>
|
||||
@else
|
||||
<small class="text-muted">(zur Not anpassbar)</small>
|
||||
@endif
|
||||
</h6>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="shipping_firstname">Vorname <span class="text-danger">*</span></label>
|
||||
<input type="text"
|
||||
class="form-control {{ empty($shippingAddress['firstname']) ? 'is-invalid' : '' }}"
|
||||
name="shipping_firstname"
|
||||
id="shipping_firstname"
|
||||
value="{{ $shippingAddress['firstname'] ?? '' }}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="shipping_lastname">Nachname <span class="text-danger">*</span></label>
|
||||
<input type="text"
|
||||
class="form-control {{ empty($shippingAddress['lastname']) ? 'is-invalid' : '' }}"
|
||||
name="shipping_lastname"
|
||||
id="shipping_lastname"
|
||||
value="{{ $shippingAddress['lastname'] ?? '' }}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<label for="shipping_company">Firma <small class="text-muted">(optional)</small></label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
name="shipping_company"
|
||||
id="shipping_company"
|
||||
value="{{ $shippingAddress['company'] ?? '' }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="form-group">
|
||||
<label for="shipping_address">Straße <span class="text-danger">*</span></label>
|
||||
<input type="text"
|
||||
class="form-control {{ empty($shippingAddress['address']) ? 'is-invalid' : '' }}"
|
||||
name="shipping_address"
|
||||
id="shipping_address"
|
||||
value="{{ $shippingAddress['address'] ?? '' }}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="shipping_houseNumber">Nr./Zusatz <span class="text-danger">*</span></label>
|
||||
<input type="text"
|
||||
class="form-control {{ empty($shippingAddress['houseNumber']) ? 'border-warning' : '' }}"
|
||||
name="shipping_houseNumber"
|
||||
id="shipping_houseNumber"
|
||||
value="{{ $shippingAddress['houseNumber'] ?? '' }}"
|
||||
required>
|
||||
@if(empty($shippingAddress['houseNumber']))
|
||||
<small class="text-warning">Hausnummer benötigt</small>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="shipping_zipcode">PLZ <span class="text-danger">*</span></label>
|
||||
<input type="text"
|
||||
class="form-control {{ empty($shippingAddress['zipcode']) ? 'is-invalid' : '' }}"
|
||||
name="shipping_zipcode"
|
||||
id="shipping_zipcode"
|
||||
value="{{ $shippingAddress['zipcode'] ?? '' }}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="form-group">
|
||||
<label for="shipping_city">Ort <span class="text-danger">*</span></label>
|
||||
<input type="text"
|
||||
class="form-control {{ empty($shippingAddress['city']) ? 'is-invalid' : '' }}"
|
||||
name="shipping_city"
|
||||
id="shipping_city"
|
||||
value="{{ $shippingAddress['city'] ?? '' }}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="shipping_country">Land <span class="text-danger">*</span></label>
|
||||
<select class="form-control custom-select" name="shipping_country_id" id="shipping_country" required>
|
||||
@foreach($availableCountries as $countryOption)
|
||||
<option value="{{ $countryOption->id }}"
|
||||
{{ $shippingAddress['country'] && $shippingAddress['country']->id == $countryOption->id ? 'selected' : '' }}>
|
||||
{{ $countryOption->getLocated() }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="shipping_phone">Telefon <small class="text-muted">(empfohlen)</small></label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
name="shipping_phone"
|
||||
id="shipping_phone"
|
||||
value="{{ $shippingAddress['phone'] ?? '' }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fas fa-times"></i> Abbrechen
|
||||
</button>
|
||||
<button type="submit" class="btn btn-primary" id="create-shipment-btn" {{ !empty($errors) ? 'disabled' : '' }}>
|
||||
<i class="fas fa-shipping-fast"></i> Sendung erstellen
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@else
|
||||
{{-- Order Selection when no order ID provided --}}
|
||||
<div class="modal-body">
|
||||
<div class="text-center">
|
||||
<i class="fas fa-search fa-3x text-primary mb-4"></i>
|
||||
<h4>Bestellung auswählen</h4>
|
||||
<p class="text-muted mb-4">Geben Sie eine Bestellungs-ID ein, um eine DHL-Sendung zu erstellen.</p>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 mx-auto">
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">#</span>
|
||||
</div>
|
||||
<input type="number"
|
||||
class="form-control form-control-lg"
|
||||
id="order-id-input"
|
||||
placeholder="z.B. 12345"
|
||||
min="1">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-primary" type="button" id="load-order-btn">
|
||||
<i class="fas fa-search"></i> Laden
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-3">
|
||||
<div class="mb-3">oder</div>
|
||||
<a href="{{ route('admin_sales_customers') }}"
|
||||
target="_blank"
|
||||
class="btn btn-outline-secondary">
|
||||
<i class="fas fa-external-link-alt"></i>
|
||||
In Bestellverwaltung suchen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<i class="fas fa-times"></i> Abbrechen
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
@if(!$order)
|
||||
// Load order functionality
|
||||
$('#load-order-btn').click(function() {
|
||||
var orderId = $('#order-id-input').val();
|
||||
|
||||
if (!orderId || orderId < 1) {
|
||||
alert('Bitte geben Sie eine gültige Bestellungs-ID ein.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Reload modal with order ID
|
||||
var btn = $(this);
|
||||
btn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Laden...');
|
||||
|
||||
$.post('{{ route('modal_load') }}', {
|
||||
action: 'create-dhl-shipment',
|
||||
id: orderId,
|
||||
_token: '{{ csrf_token() }}'
|
||||
}).done(function(response) {
|
||||
console.log(response);
|
||||
$('#modals-load-content .modal-dialog').html(response.html);
|
||||
}).fail(function() {
|
||||
alert('Bestellung konnte nicht geladen werden.');
|
||||
btn.prop('disabled', false).html('<i class="fas fa-search"></i> Laden');
|
||||
});
|
||||
});
|
||||
|
||||
// Enter key handling
|
||||
$('#order-id-input').keypress(function(e) {
|
||||
if (e.which === 13) {
|
||||
$('#load-order-btn').click();
|
||||
}
|
||||
});
|
||||
@endif
|
||||
|
||||
@if($order)
|
||||
// Form submission with improved validation
|
||||
$('#modal-create-shipment-form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var form = $(this);
|
||||
var formData = form.serialize();
|
||||
var submitBtn = $('#create-shipment-btn');
|
||||
|
||||
// Client-side validation
|
||||
var isValid = validateForm();
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable submit button
|
||||
submitBtn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Wird erstellt...');
|
||||
|
||||
$.ajax({
|
||||
url: form.attr('action'),
|
||||
method: 'POST',
|
||||
data: formData,
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
// Close modal
|
||||
$('#modals-load-content').modal('hide');
|
||||
|
||||
// Show success message and reload
|
||||
if (typeof showAlert === 'function') {
|
||||
showAlert('success', response.message);
|
||||
} else {
|
||||
alert(response.message);
|
||||
}
|
||||
|
||||
// Reload page after 2 seconds
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 2000);
|
||||
} else {
|
||||
alert(response.message || 'Fehler beim Erstellen der Sendung.');
|
||||
submitBtn.prop('disabled', false).html('<i class="fas fa-shipping-fast"></i> Sendung erstellen');
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
var errorMessage = 'Fehler beim Erstellen der Sendung.';
|
||||
if (xhr.responseJSON && xhr.responseJSON.message) {
|
||||
errorMessage = xhr.responseJSON.message;
|
||||
} else if (xhr.responseText) {
|
||||
try {
|
||||
var errorData = JSON.parse(xhr.responseText);
|
||||
if (errorData.errors) {
|
||||
errorMessage = Object.values(errorData.errors).flat().join(', ');
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore JSON parse errors
|
||||
}
|
||||
}
|
||||
|
||||
alert(errorMessage);
|
||||
submitBtn.prop('disabled', false).html('<i class="fas fa-shipping-fast"></i> Sendung erstellen');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Enhanced form validation
|
||||
function validateForm() {
|
||||
var isValid = true;
|
||||
|
||||
// Clear previous validation states
|
||||
$('.form-control').removeClass('is-invalid');
|
||||
$('.invalid-feedback').remove();
|
||||
|
||||
// Weight validation
|
||||
var weight = parseFloat($('#modal-weight').val());
|
||||
if (!weight || weight < 0.1 || weight > 31.5) {
|
||||
$('#modal-weight').addClass('is-invalid').after('<div class="invalid-feedback">Gewicht muss zwischen 0.1 und 31.5 kg liegen.</div>');
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
// Required fields validation
|
||||
var requiredFields = [
|
||||
'#shipping_firstname',
|
||||
'#shipping_lastname',
|
||||
'#shipping_address',
|
||||
'#shipping_zipcode',
|
||||
'#shipping_city'
|
||||
];
|
||||
|
||||
requiredFields.forEach(function(fieldId) {
|
||||
var field = $(fieldId);
|
||||
if (!field.val().trim()) {
|
||||
field.addClass('is-invalid').after('<div class="invalid-feedback">Dieses Feld ist erforderlich.</div>');
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
// Real-time weight validation
|
||||
$('#modal-weight').on('input', function() {
|
||||
var weight = parseFloat($(this).val());
|
||||
var input = $(this);
|
||||
|
||||
input.removeClass('is-invalid');
|
||||
input.siblings('.invalid-feedback').remove();
|
||||
|
||||
if (weight && (weight < 0.1 || weight > 31.5)) {
|
||||
input.addClass('is-invalid');
|
||||
if (weight < 0.1) {
|
||||
input.after('<div class="invalid-feedback">Mindestgewicht: 0.1 kg</div>');
|
||||
} else {
|
||||
input.after('<div class="invalid-feedback">Maximalgewicht: 31.5 kg</div>');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Real-time required field validation
|
||||
$('input[required], select[required]').on('blur', function() {
|
||||
var field = $(this);
|
||||
if (!field.val().trim()) {
|
||||
field.addClass('is-invalid');
|
||||
if (!field.siblings('.invalid-feedback').length) {
|
||||
field.after('<div class="invalid-feedback">Dieses Feld ist erforderlich.</div>');
|
||||
}
|
||||
} else {
|
||||
field.removeClass('is-invalid');
|
||||
field.siblings('.invalid-feedback').remove();
|
||||
}
|
||||
});
|
||||
@endif
|
||||
});
|
||||
</script>
|
||||
600
resources/views/admin/dhl/show.blade.php
Normal file
600
resources/views/admin/dhl/show.blade.php
Normal file
|
|
@ -0,0 +1,600 @@
|
|||
@extends('layouts.layout-2')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center py-2 mb-4">
|
||||
<h4 class="font-weight-bold mb-0">
|
||||
<i class="fas fa-box text-primary"></i>
|
||||
DHL Sendung #{{ $shipment->id }}
|
||||
@if($shipment->type == 'return')
|
||||
<span class="badge badge-info ml-2">
|
||||
<i class="fas fa-undo"></i> Retoure
|
||||
</span>
|
||||
@endif
|
||||
</h4>
|
||||
<div>
|
||||
<a href="{{ route('admin.dhl.cockpit') }}" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Zurück zum Cockpit
|
||||
</a>
|
||||
@if($shipment->shoppingOrder)
|
||||
<a href="{{ route('admin_sales_customers_detail', $shipment->shoppingOrder->id) }}"
|
||||
class="btn btn-outline-primary ml-2">
|
||||
<i class="fas fa-shopping-cart"></i> Bestellung anzeigen
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Status & Key Info Row -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-xl-3 col-md-6 mb-3">
|
||||
<div class="card border-left-primary">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">Status</div>
|
||||
@switch($shipment->status)
|
||||
@case('pending')
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800">
|
||||
<span class="badge badge-warning">Wartend</span>
|
||||
</div>
|
||||
@break
|
||||
@case('created')
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800">
|
||||
<span class="badge badge-success">Erstellt</span>
|
||||
</div>
|
||||
@break
|
||||
@case('shipped')
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800">
|
||||
<span class="badge badge-primary">Versendet</span>
|
||||
</div>
|
||||
@break
|
||||
@case('delivered')
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800">
|
||||
<span class="badge badge-info">Zugestellt</span>
|
||||
</div>
|
||||
@break
|
||||
@case('cancelled')
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800">
|
||||
<span class="badge badge-secondary">Storniert</span>
|
||||
</div>
|
||||
@break
|
||||
@case('failed')
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800">
|
||||
<span class="badge badge-danger">Fehler</span>
|
||||
</div>
|
||||
@break
|
||||
@default
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800">
|
||||
<span class="badge badge-light">{{ $shipment->status }}</span>
|
||||
</div>
|
||||
@endswitch
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<i class="fas fa-flag fa-2x text-gray-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-3 col-md-6 mb-3">
|
||||
<div class="card border-left-success">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Sendungsnummer</div>
|
||||
<div class="h6 mb-0 font-weight-bold text-gray-800">
|
||||
@if($shipment->shipment_number)
|
||||
<code class="text-success">{{ $shipment->shipment_number }}</code>
|
||||
@else
|
||||
<span class="text-muted">Nicht verfügbar</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<i class="fas fa-hashtag fa-2x text-gray-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-3 col-md-6 mb-3">
|
||||
<div class="card border-left-info">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-xs font-weight-bold text-info text-uppercase mb-1">Tracking-Nummer</div>
|
||||
<div class="h6 mb-0 font-weight-bold text-gray-800">
|
||||
@if($shipment->tracking_number)
|
||||
<code class="text-info">{{ $shipment->tracking_number }}</code>
|
||||
<br>
|
||||
<a href="{{ route('public.tracking') }}?tracking_number={{ $shipment->tracking_number }}"
|
||||
target="_blank" class="text-muted small">
|
||||
<i class="fas fa-external-link-alt"></i> Verfolgen
|
||||
</a>
|
||||
@else
|
||||
<span class="text-muted">Nicht verfügbar</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<i class="fas fa-search fa-2x text-gray-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-3 col-md-6 mb-3">
|
||||
<div class="card border-left-warning">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">Gewicht</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-800">
|
||||
{{ number_format($shipment->weight, 2) }} kg
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<i class="fas fa-weight fa-2x text-gray-300"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
@if($shipment->status != 'cancelled')
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
@if($shipment->label_path)
|
||||
<a href="{{ route('admin.dhl.download-label', $shipment) }}"
|
||||
class="btn btn-success mr-2">
|
||||
<i class="fas fa-download"></i> Label herunterladen
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@if($shipment->canCancel())
|
||||
<button type="button"
|
||||
class="btn btn-warning mr-2"
|
||||
id="cancel-shipment-btn"
|
||||
data-shipment-id="{{ $shipment->id }}">
|
||||
<i class="fas fa-ban"></i> Sendung stornieren
|
||||
</button>
|
||||
@endif
|
||||
|
||||
@if($shipment->type == 'outbound' && !$shipment->relatedShipment)
|
||||
<button type="button"
|
||||
class="btn btn-info mr-2"
|
||||
id="create-return-btn"
|
||||
data-shipment-id="{{ $shipment->id }}">
|
||||
<i class="fas fa-undo"></i> Retourenlabel erstellen
|
||||
</button>
|
||||
@endif
|
||||
|
||||
@if($shipment->tracking_number)
|
||||
<button type="button"
|
||||
class="btn btn-secondary mr-2"
|
||||
id="update-tracking-btn"
|
||||
data-shipment-id="{{ $shipment->id }}">
|
||||
<i class="fas fa-sync"></i> Tracking aktualisieren
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Shipment Details -->
|
||||
<div class="row">
|
||||
<!-- Left Column -->
|
||||
<div class="col-lg-8">
|
||||
<!-- Shipment Information -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-info-circle text-primary"></i>
|
||||
Sendungsinformationen
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<table class="table table-sm">
|
||||
<tr>
|
||||
<td class="font-weight-semibold">ID:</td>
|
||||
<td>#{{ $shipment->id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Typ:</td>
|
||||
<td>
|
||||
@if($shipment->type == 'outbound')
|
||||
<span class="badge badge-primary">
|
||||
<i class="fas fa-arrow-right"></i> Ausgehend
|
||||
</span>
|
||||
@else
|
||||
<span class="badge badge-info">
|
||||
<i class="fas fa-undo"></i> Retoure
|
||||
</span>
|
||||
@if($shipment->relatedShipment)
|
||||
<br>
|
||||
<small class="text-muted">
|
||||
Bezieht sich auf Sendung
|
||||
<a href="{{ route('admin.dhl.show', $shipment->relatedShipment) }}">
|
||||
#{{ $shipment->relatedShipment->id }}
|
||||
</a>
|
||||
</small>
|
||||
@endif
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Produktcode:</td>
|
||||
<td><code>{{ $shipment->product_code }}</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Label-Format:</td>
|
||||
<td>{{ strtoupper($shipment->label_format) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Label gedruckt:</td>
|
||||
<td>
|
||||
@if($shipment->label_printed)
|
||||
<span class="badge badge-success">Ja</span>
|
||||
@else
|
||||
<span class="badge badge-secondary">Nein</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<table class="table table-sm">
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Erstellt:</td>
|
||||
<td>{{ $shipment->created_at->format('d.m.Y H:i:s') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Letzte Änderung:</td>
|
||||
<td>{{ $shipment->updated_at->format('d.m.Y H:i:s') }}</td>
|
||||
</tr>
|
||||
@if($shipment->last_tracked_at)
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Letztes Tracking:</td>
|
||||
<td>{{ $shipment->last_tracked_at->format('d.m.Y H:i:s') }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@if($shipment->length || $shipment->width || $shipment->height)
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Abmessungen:</td>
|
||||
<td>
|
||||
{{ $shipment->length }}×{{ $shipment->width }}×{{ $shipment->height }} cm
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Order Information -->
|
||||
@if($shipment->shoppingOrder)
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-shopping-cart text-success"></i>
|
||||
Bestellinformationen
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<table class="table table-sm">
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Bestellungs-ID:</td>
|
||||
<td>
|
||||
<a href="{{ route('admin_sales_customers_detail', $shipment->shoppingOrder->id) }}" class="text-primary">
|
||||
#{{ $shipment->shoppingOrder->id }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Kunde:</td>
|
||||
<td>
|
||||
@if($shipment->shoppingOrder->shopping_user)
|
||||
{{ $shipment->shoppingOrder->shopping_user->billing_firstname }} {{ $shipment->shoppingOrder->shopping_user->billing_lastname }}
|
||||
<br>
|
||||
<small class="text-muted">{{ $shipment->shoppingOrder->shopping_user->billing_email }}</small>
|
||||
@else
|
||||
<span class="text-muted">Unbekannt</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Bestelldatum:</td>
|
||||
<td>{{ $shipment->shoppingOrder->created_at->format('d.m.Y H:i') }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<table class="table table-sm">
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Bestellwert:</td>
|
||||
<td><strong>{{ number_format($shipment->shoppingOrder->total, 2) }} €</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Status:</td>
|
||||
<td>
|
||||
<span class="badge badge-{{ $shipment->shoppingOrder->status == 'completed' ? 'success' : 'warning' }}">
|
||||
{{ $shipment->shoppingOrder->status }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-weight-semibold">Artikel:</td>
|
||||
<td>{{ $shipment->shoppingOrder->shopping_order_items->count() ?? 0 }} Artikel</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Tracking Information -->
|
||||
@if($shipment->tracking_status || $shipment->tracking_number)
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-route text-info"></i>
|
||||
Tracking-Informationen
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@if($shipment->tracking_status)
|
||||
<div class="alert alert-info">
|
||||
<h6 class="alert-heading">
|
||||
<i class="fas fa-map-marker-alt"></i>
|
||||
Aktueller Status: {{ $shipment->tracking_status }}
|
||||
</h6>
|
||||
@if($shipment->last_tracked_at)
|
||||
<small class="text-muted">
|
||||
Zuletzt aktualisiert: {{ $shipment->last_tracked_at->format('d.m.Y H:i') }}
|
||||
</small>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($shipment->tracking_number)
|
||||
<div class="text-center">
|
||||
<p>Verfolgen Sie diese Sendung direkt bei DHL:</p>
|
||||
<a href="https://www.dhl.de/de/privatkunden/pakete-empfangen/verfolgen.html?lang=de&idc={{ $shipment->tracking_number }}"
|
||||
target="_blank"
|
||||
class="btn btn-outline-warning">
|
||||
<i class="fas fa-external-link-alt"></i>
|
||||
Bei DHL verfolgen
|
||||
</a>
|
||||
<a href="{{ route('public.tracking') }}?tracking_number={{ $shipment->tracking_number }}"
|
||||
target="_blank"
|
||||
class="btn btn-outline-info ml-2">
|
||||
<i class="fas fa-search"></i>
|
||||
Lokales Tracking
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Right Column -->
|
||||
<div class="col-lg-4">
|
||||
<!-- Related Shipments -->
|
||||
@if($shipment->type == 'outbound' && $shipment->relatedShipments && $shipment->relatedShipments->count() > 0)
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-link text-warning"></i>
|
||||
Verknüpfte Retouren
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@foreach($shipment->relatedShipments as $relatedShipment)
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<div>
|
||||
<a href="{{ route('admin.dhl.show', $relatedShipment) }}" class="text-primary">
|
||||
Retoure #{{ $relatedShipment->id }}
|
||||
</a>
|
||||
<br>
|
||||
<small class="text-muted">{{ $relatedShipment->created_at->format('d.m.Y H:i') }}</small>
|
||||
</div>
|
||||
<span class="badge badge-{{ $relatedShipment->status == 'created' ? 'success' : 'warning' }}">
|
||||
{{ $relatedShipment->status }}
|
||||
</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Additional Services -->
|
||||
@if($shipment->services)
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-plus-circle text-success"></i>
|
||||
Zusatzleistungen
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@foreach($shipment->services as $service => $enabled)
|
||||
@if($enabled)
|
||||
<div class="badge badge-success mr-1 mb-1">{{ $service }}</div>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- API Response Data -->
|
||||
@if($shipment->api_response_data && auth()->user()->isSuperAdmin())
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<i class="fas fa-code text-muted"></i>
|
||||
API Response (Debug)
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<pre class="small text-muted" style="max-height: 300px; overflow-y: auto;">{{ json_encode($shipment->api_response_data, JSON_PRETTY_PRINT) }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Cancel shipment
|
||||
$('#cancel-shipment-btn').click(function() {
|
||||
var shipmentId = $(this).data('shipment-id');
|
||||
|
||||
if (!confirm('Möchten Sie diese Sendung wirklich stornieren?\n\nDieser Vorgang kann nicht rückgängig gemacht werden.')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var btn = $(this);
|
||||
btn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Wird storniert...');
|
||||
|
||||
$.ajax({
|
||||
url: `/admin/dhl/shipment/${shipmentId}/cancel`,
|
||||
method: 'DELETE',
|
||||
data: {
|
||||
_token: '{{ csrf_token() }}'
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
showAlert('success', response.message);
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 2000);
|
||||
} else {
|
||||
showAlert('error', response.message);
|
||||
resetButton(btn, '<i class="fas fa-ban"></i> Sendung stornieren');
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
showAlert('error', 'Fehler beim Stornieren der Sendung.');
|
||||
resetButton(btn, '<i class="fas fa-ban"></i> Sendung stornieren');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Create return label
|
||||
$('#create-return-btn').click(function() {
|
||||
var shipmentId = $(this).data('shipment-id');
|
||||
|
||||
if (!confirm('Möchten Sie ein Retourenlabel für diese Sendung erstellen?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var btn = $(this);
|
||||
btn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Wird erstellt...');
|
||||
|
||||
$.ajax({
|
||||
url: `/admin/dhl/shipment/${shipmentId}/return-label`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
_token: '{{ csrf_token() }}'
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
showAlert('success', response.message);
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 2000);
|
||||
} else {
|
||||
showAlert('error', response.message);
|
||||
resetButton(btn, '<i class="fas fa-undo"></i> Retourenlabel erstellen');
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
showAlert('error', 'Fehler beim Erstellen des Retourenlabels.');
|
||||
resetButton(btn, '<i class="fas fa-undo"></i> Retourenlabel erstellen');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Update tracking
|
||||
$('#update-tracking-btn').click(function() {
|
||||
var shipmentId = $(this).data('shipment-id');
|
||||
var btn = $(this);
|
||||
|
||||
btn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Wird aktualisiert...');
|
||||
|
||||
$.ajax({
|
||||
url: `/admin/dhl/shipment/${shipmentId}/update-tracking`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
_token: '{{ csrf_token() }}'
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
showAlert('success', response.message);
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 3000);
|
||||
} else {
|
||||
showAlert('error', response.message);
|
||||
resetButton(btn, '<i class="fas fa-sync"></i> Tracking aktualisieren');
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
showAlert('error', 'Fehler beim Aktualisieren der Tracking-Informationen.');
|
||||
resetButton(btn, '<i class="fas fa-sync"></i> Tracking aktualisieren');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Helper functions
|
||||
function resetButton(btn, originalText) {
|
||||
btn.prop('disabled', false).html(originalText);
|
||||
}
|
||||
|
||||
function showAlert(type, message) {
|
||||
var alertClass = type === 'success' ? 'alert-success' : 'alert-danger';
|
||||
var iconClass = type === 'success' ? 'fas fa-check-circle' : 'fas fa-exclamation-circle';
|
||||
|
||||
var alertHtml = `
|
||||
<div class="alert ${alertClass} alert-dismissible fade show" role="alert">
|
||||
<i class="${iconClass}"></i>
|
||||
${message}
|
||||
<button type="button" class="close" data-dismiss="alert">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
$('.py-2.mb-4').after(alertHtml);
|
||||
|
||||
// Scroll to top
|
||||
$('html, body').animate({ scrollTop: 0 }, 500);
|
||||
|
||||
// Auto-hide success alerts after 5 seconds
|
||||
if (type === 'success') {
|
||||
setTimeout(function() {
|
||||
$('.alert-success').alert('close');
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
|
@ -107,6 +107,220 @@
|
|||
<button type="submit" name="action" value="save_prepayment" class="btn btn-primary btn-sm mb-2"><i class="ion ion-ios-save"></i> speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- DHL Configuration Section -->
|
||||
<div class="card mb-2">
|
||||
<div class="card-body">
|
||||
<h4><i class="fas fa-truck"></i> DHL Versandeinstellungen</h4>
|
||||
|
||||
@if(Session::has('alert-save-dhl'))
|
||||
<div class="alert alert-success" role="alert">
|
||||
<i class="fas fa-check-circle"></i> {{ Session::get('alert-save-dhl') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- DHL Standard-Einstellungen -->
|
||||
<div class="form-row">
|
||||
<div class="col-sm-12">
|
||||
<h5>Standard-Einstellungen</h5>
|
||||
</div>
|
||||
<div class="form-group col-sm-4">
|
||||
<label class="form-label">{{ __('API Basis URL') }}*</label>
|
||||
{{ Form::text('settings[dhl_base_url][val]', \App\Models\Setting::getContentBySlug('dhl_base_url') ?: 'https://api-eu.dhl.com', array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_base_url][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-4">
|
||||
<label class="form-label">{{ __('API Schlüssel') }}*</label>
|
||||
{{ Form::text('settings[dhl_api_key][val]', \App\Models\Setting::getContentBySlug('dhl_api_key'), array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_api_key][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-4">
|
||||
<label class="form-label">{{ __('Benutzername') }}*</label>
|
||||
{{ Form::text('settings[dhl_username][val]', \App\Models\Setting::getContentBySlug('dhl_username'), array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_username][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-4">
|
||||
<label class="form-label">{{ __('Passwort') }}*</label>
|
||||
{{ Form::password('settings[dhl_password][val]', array('class'=>'form-control', 'value' => \App\Models\Setting::getContentBySlug('dhl_password'))) }}
|
||||
{{ Form::hidden('settings[dhl_password][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-4">
|
||||
<label class="form-label">{{ __('Standard Abrechnungsnummer') }}*</label>
|
||||
{{ Form::text('settings[dhl_billing_number][val]', \App\Models\Setting::getContentBySlug('dhl_billing_number'), array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_billing_number][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-4">
|
||||
<label class="form-label">{{ __('Standard Produktcode') }}*</label>
|
||||
{{ Form::select('settings[dhl_product][val]', [
|
||||
'V01PAK' => 'V01PAK - DHL Paket National',
|
||||
'V53PAK' => 'V53PAK - DHL Paket International',
|
||||
'V62WP' => 'V62WP - Warenpost National'
|
||||
], \App\Models\Setting::getContentBySlug('dhl_product') ?: 'V01PAK', array('class'=>'form-control custom-select')) }}
|
||||
{{ Form::hidden('settings[dhl_product][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('Label Format') }}*</label>
|
||||
{{ Form::select('settings[dhl_label_format][val]', [
|
||||
'PDF' => 'PDF',
|
||||
'ZPL' => 'ZPL'
|
||||
], \App\Models\Setting::getContentBySlug('dhl_label_format') ?: 'PDF', array('class'=>'form-control custom-select')) }}
|
||||
{{ Form::hidden('settings[dhl_label_format][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="custom-control custom-checkbox mt-4">
|
||||
{!! Form::checkbox('settings[dhl_use_queue][val]', 1, \App\Models\Setting::getContentBySlug('dhl_use_queue'), ['class'=>'custom-control-input']) !!}
|
||||
<span class="custom-control-label">Queue für asynchrone Verarbeitung verwenden</span>
|
||||
</label>
|
||||
{{ Form::hidden('settings[dhl_use_queue][type]', 'bool') }}
|
||||
<small class="form-text text-muted">
|
||||
<strong>Aktiviert:</strong> Versandlabel werden im Hintergrund erstellt (erfordert Queue Worker)<br>
|
||||
<strong>Deaktiviert:</strong> Versandlabel werden sofort erstellt (synchron)
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- DHL Account Numbers -->
|
||||
<div class="form-row">
|
||||
<div class="col-sm-12">
|
||||
<h5>Account Nummern für verschiedene Produkte</h5>
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('V01PAK - DHL Paket National') }}*</label>
|
||||
{{ Form::text('settings[dhl_account_v01pak][val]', \App\Models\Setting::getContentBySlug('dhl_account_v01pak'), array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_account_v01pak][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('V07PAK - DHL Retoure Online') }}</label>
|
||||
{{ Form::text('settings[dhl_account_v07pak][val]', \App\Models\Setting::getContentBySlug('dhl_account_v07pak'), array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_account_v07pak][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('V53PAK - DHL Paket International') }}</label>
|
||||
{{ Form::text('settings[dhl_account_v53pak][val]', \App\Models\Setting::getContentBySlug('dhl_account_v53pak'), array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_account_v53pak][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('V62WP - Warenpost National') }}</label>
|
||||
{{ Form::text('settings[dhl_account_v62wp][val]', \App\Models\Setting::getContentBySlug('dhl_account_v62wp'), array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_account_v62wp][type]', 'text') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<!-- DHL Absenderadresse -->
|
||||
<div class="form-row">
|
||||
<div class="col-sm-12">
|
||||
<h5>Absenderadresse</h5>
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('Firmenname') }}*</label>
|
||||
{{ Form::text('settings[dhl_sender_company][val]', \App\Models\Setting::getContentBySlug('dhl_sender_company') ?: 'mivita care gmbh', array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_sender_company][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('Name (optional)') }}</label>
|
||||
{{ Form::text('settings[dhl_sender_name][val]', \App\Models\Setting::getContentBySlug('dhl_sender_name'), array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_sender_name][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('Straße') }}*</label>
|
||||
{{ Form::text('settings[dhl_sender_street][val]', \App\Models\Setting::getContentBySlug('dhl_sender_street') ?: 'Leinfeld', array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_sender_street][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('Hausnummer') }}*</label>
|
||||
{{ Form::text('settings[dhl_sender_house_number][val]', \App\Models\Setting::getContentBySlug('dhl_sender_house_number') ?: '2', array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_sender_house_number][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-4">
|
||||
<label class="form-label">{{ __('PLZ') }}*</label>
|
||||
{{ Form::text('settings[dhl_sender_postal_code][val]', \App\Models\Setting::getContentBySlug('dhl_sender_postal_code') ?: '87755', array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_sender_postal_code][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-4">
|
||||
<label class="form-label">{{ __('Stadt') }}*</label>
|
||||
{{ Form::text('settings[dhl_sender_city][val]', \App\Models\Setting::getContentBySlug('dhl_sender_city') ?: 'Kirchhaslach', array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_sender_city][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-4">
|
||||
<label class="form-label">{{ __('Land') }}*</label>
|
||||
{{ Form::select('settings[dhl_sender_country][val]', [
|
||||
'DE' => 'Deutschland',
|
||||
'AT' => 'Österreich',
|
||||
'CH' => 'Schweiz'
|
||||
], \App\Models\Setting::getContentBySlug('dhl_sender_country') ?: 'DE', array('class'=>'form-control custom-select')) }}
|
||||
{{ Form::hidden('settings[dhl_sender_country][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('E-Mail') }}*</label>
|
||||
{{ Form::email('settings[dhl_sender_email][val]', \App\Models\Setting::getContentBySlug('dhl_sender_email') ?: 'versand@mivita.care', array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_sender_email][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('Telefon') }}</label>
|
||||
{{ Form::text('settings[dhl_sender_phone][val]', \App\Models\Setting::getContentBySlug('dhl_sender_phone') ?: '+49 123 456789', array('class'=>'form-control')) }}
|
||||
{{ Form::hidden('settings[dhl_sender_phone][type]', 'text') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- DHL Absenderadresse -->
|
||||
<div class="form-row">
|
||||
<div class="col-sm-12">
|
||||
<h5>Papierformat</h5>
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('Versandlabel') }}*</label>
|
||||
{{ Form::select('settings[dhl_print_format][val]', [
|
||||
'A4' => 'Common Label Laserdruck A4 Normalpapier',
|
||||
'910-300-600' => 'Common Label Thermodruck 103 x 199 mm (910-300-600)',
|
||||
'910-300-610' => 'Common Label Thermodruck 103 x 199 mm (910-300-610)',
|
||||
'910-300-700' => 'Common Label Laserdruck 105 x 205 mm (DIN A5 Normalpapier, 910-300-700)',
|
||||
'910-300-700-oz' => 'Common Label Laserdruck 105 x 205 mm (DIN A5 Normalpapier, 910-300-700) ohne Zusatzetiketten',
|
||||
'910-300-710' => 'Common Label Laserdruck 105 x 208 mm (910-300-710)',
|
||||
'910-300-300' => 'Common Label Laserdruck 105 x 148 mm (DIN A5 Normalpapier, 910-300-300)',
|
||||
'910-300-300-oz' => 'Common Label Laserdruck 105 x 148 mm (DIN A5 Normalpapier, 910-300-300) ohne Zusatzetiketten',
|
||||
'910-300-400' => 'Common Label Thermodruck 103 x 150 mm (910-300-400)',
|
||||
'910-300-410' => 'Common Label Thermodruck 103 x 150 mm (910-300-410)',
|
||||
'100x70mm' => '100x70mm',
|
||||
], \App\Models\Setting::getContentBySlug('dhl_print_format') ?: 'A4', array('class'=>'form-control custom-select')) }}
|
||||
{{ Form::hidden('settings[dhl_print_format][type]', 'text') }}
|
||||
</div>
|
||||
<div class="form-group col-sm-6">
|
||||
<label class="form-label">{{ __('Retoure Label') }}*</label>
|
||||
{{ Form::select('settings[dhl_retoure_print_format][val]', [
|
||||
'A4' => 'Common Label Laserdruck A4 Normalpapier',
|
||||
'910-300-600' => 'Common Label Thermodruck 103 x 199 mm (910-300-600)',
|
||||
'910-300-610' => 'Common Label Thermodruck 103 x 199 mm (910-300-610)',
|
||||
'910-300-700' => 'Common Label Laserdruck 105 x 205 mm (DIN A5 Normalpapier, 910-300-700)',
|
||||
'910-300-700-oz' => 'Common Label Laserdruck 105 x 205 mm (DIN A5 Normalpapier, 910-300-700) ohne Zusatzetiketten',
|
||||
'910-300-710' => 'Common Label Laserdruck 105 x 208 mm (910-300-710)',
|
||||
'910-300-300' => 'Common Label Laserdruck 105 x 148 mm (DIN A5 Normalpapier, 910-300-300)',
|
||||
'910-300-300-oz' => 'Common Label Laserdruck 105 x 148 mm (DIN A5 Normalpapier, 910-300-300) ohne Zusatzetiketten',
|
||||
'910-300-400' => 'Common Label Thermodruck 103 x 150 mm (910-300-400)',
|
||||
'910-300-410' => 'Common Label Thermodruck 103 x 150 mm (910-300-410)',
|
||||
'100x70mm' => '100x70mm',
|
||||
], \App\Models\Setting::getContentBySlug('dhl_retoure_print_format') ?: 'A4', array('class'=>'form-control custom-select')) }}
|
||||
{{ Form::hidden('settings[dhl_retoure_print_format][type]', 'text') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<button type="submit" name="action" value="save_dhl" class="btn btn-primary btn-sm mb-2">
|
||||
<i class="fas fa-truck"></i> DHL Einstellungen speichern
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!! Form::close() !!}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@
|
|||
</form>
|
||||
|
||||
<div class="mt-1 text-center justify-content-center">
|
||||
<button type="button" class="btn btn-outline-primary mt-2 btn-sm update_modal_data_load" data-url="{{ route('portal.loading_modal') }}" data-data="data_protection" data-target="#modal-loading">{{__('register.data_protection')}}</button>
|
||||
<button type="button" class="btn btn-outline-primary mt-2 btn-sm update_modal_data_load" data-url="{{ route('portal.loading_modal') }}" data-data="imprint" data-target="#modal-loading">{{__('imprint')}}</button>
|
||||
<button type="button" class="btn btn-outline-primary mt-2 btn-sm update_modal_data_load" data-url="{{ route('loading_modal') }}" data-data="data_protection" data-target="#modal-loading">{{__('register.data_protection')}}</button>
|
||||
<button type="button" class="btn btn-outline-primary mt-2 btn-sm update_modal_data_load" data-url="{{ route('loading_modal') }}" data-data="imprint" data-target="#modal-loading">{{__('imprint')}}</button>
|
||||
</div>
|
||||
<div class="mt-1 text-center justify-content-center">
|
||||
<a href="{{ Util::getMyMivitaShopUrl() }}" class="btn btn-secondary mt-2 btn-sm">{{__('portal.back_to_shop')}}</a>
|
||||
|
|
|
|||
|
|
@ -212,6 +212,11 @@
|
|||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="sidenav-item{{ Request::is('admin/dhl/*') ? ' active' : '' }}">
|
||||
<a href="{{ route('admin.dhl.cockpit') }}" class="sidenav-link"><i class="sidenav-icon ion ion-md-send"></i><div>{{ __('navigation.dhl_cockpit') }}</div></a>
|
||||
</li>
|
||||
|
||||
|
||||
<li class="sidenav-item @if(Request::is('admin/payments/*')) open @endif">
|
||||
<a href="javascript:void(0)" class="sidenav-link sidenav-toggle">
|
||||
<i class="sidenav-icon ion ion-md-cash"></i>
|
||||
|
|
@ -302,6 +307,7 @@
|
|||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
<li class="sidenav-item @if(Request::is('admin/sites/*')) open @endif">
|
||||
<a href="javascript:void(0)" class="sidenav-link sidenav-toggle">
|
||||
<i class="sidenav-icon ion ion-md-albums"></i>
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
<a href="{{route('login')}}" class="btn btn-primary btn-block">{{ __('go to login') }}</a>
|
||||
<a href="{{route('password.request')}}" class="btn btn-secondary btn-block">{{ __('create new password') }}</a>
|
||||
<hr>
|
||||
<a href="{{route('/')}}" class="btn btn-default btn-block">{{ __('back to the homepage') }}</a>
|
||||
<a href="{{url('/')}}" class="btn btn-default btn-block">{{ __('back to the homepage') }}</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
<p class="text-center text-big mb-4"><strong>{{ __('Page not available') }}</strong></p>
|
||||
|
||||
<a href="{{route('/')}}" class="btn btn-primary btn-block">{{ __('back to the homepage') }}</a>
|
||||
<a href="{{url('/')}}" class="btn btn-primary btn-block">{{ __('back to the homepage') }}</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
<p class="text-center text-big mb-4"><strong>{{ __('Thank you for your registration!') }}</strong></p>
|
||||
<p class="text-center text-big mb-4">{{ __('We have sent you an e-mail with a link to activate your data.') }}</p>
|
||||
|
||||
<a href="{{route('/')}}" class="btn btn-primary btn-block">{{ __('back to the homepage') }}</a>
|
||||
<a href="{{url('/')}}" class="btn btn-primary btn-block">{{ __('back to the homepage') }}</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
<hr>
|
||||
<p class="text-center text-big mb-4">{{ __('Now assign a password.') }}<br><br><a href="{{route('user_update_password_first')}}" class="btn btn btn-primary">{{ __('create new password') }}</a></p>
|
||||
<hr>
|
||||
<a href="{{route('/')}}" class="btn btn-primary btn-block">{{ __('back to the homepage') }}</a>
|
||||
<a href="{{url('/')}}" class="btn btn-primary btn-block">{{ __('back to the homepage') }}</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -70,6 +70,17 @@
|
|||
</div>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div class="text-muted">{{ __('Status') }}</div>
|
||||
<div class="text-right">
|
||||
@if($user->shop->getSubdomainAvailable())
|
||||
<span class="badge badge-pill badge-success"><i class="fa fa-check"> {{ __('shop.available') }} </i> </span>
|
||||
@else
|
||||
<span class="badge badge-pill badge-danger"><i class="fa fa-times"> {{ __('shop.not_available') }} </i> </span>
|
||||
@endif
|
||||
</div>
|
||||
</li>
|
||||
|
||||
{{-- <li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div class="text-muted">{{ __('Status') }}</div>
|
||||
<div class="text-right">
|
||||
@if($user->shop->getSubdomainStatus())
|
||||
|
|
@ -94,17 +105,13 @@
|
|||
@endif
|
||||
|
||||
</div>
|
||||
</li> --}}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div class="text-muted">{{ __('shop.active_since') }}</div>
|
||||
<div>
|
||||
<a href="{{ route('user_shop_name_edit') }}" class="btn btn-xs btn-outline-primary"><i class="fa fa-edit"></i> Shop Name anpassen</a>
|
||||
</div>
|
||||
</li>
|
||||
@if(!$user->shop->getSubdomainStatus() || !$user->shop->getSubdomainAvailable() || !$user->shop->getSubdomainSslSinActive())
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<p class="text-danger">{{ __('shop.not_available_copy') }}
|
||||
<a href="" class="btn icon-btn btn-xs btn-outline-primary">
|
||||
<span class="lnr lnr-redo"></span>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
</li>
|
||||
@endif
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div class="text-muted">{{ __('shop.active_since') }}</div>
|
||||
<div>
|
||||
|
|
|
|||
174
resources/views/user/components/user_shop_edit_name.blade.php
Normal file
174
resources/views/user/components/user_shop_edit_name.blade.php
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
<div class="card-body" style="background: #fff; border: 1px solid rgba(24, 28, 33, 0.06);">
|
||||
<h4>{{ __('shop.edit_your_shop') }}</h4>
|
||||
|
||||
{!! Form::open(['action' => route('user_shop_register_form'), 'class' => 'form-horizontal' , 'id'=>'data-shop-form-validations']) !!}
|
||||
{{ Form::hidden('user_shop_id', $user_shop_id) }}
|
||||
|
||||
@php
|
||||
$shop_name_btn_color = 'btn-secondary';
|
||||
$shop_name_fa = '';
|
||||
$shop_name_form_control = '';
|
||||
@endphp
|
||||
@if(Session::has('shop-name-error'))
|
||||
@if(Session::get('shop-name-error') == 'check')
|
||||
@php
|
||||
$shop_name_btn_color = 'btn-success';
|
||||
$shop_name_fa = 'fa-check';
|
||||
$shop_name_form_control = ' is-valid';
|
||||
@endphp
|
||||
|
||||
@endif
|
||||
@if(Session::get('shop-name-error') == 'error')
|
||||
@php
|
||||
$shop_name_btn_color = 'btn-danger';
|
||||
$shop_name_fa = 'fa-times';
|
||||
$shop_name_form_control = ' is-invalid';
|
||||
@endphp
|
||||
@endif
|
||||
@endif
|
||||
|
||||
|
||||
<p class="mt-2">
|
||||
{!! __('shop.open_copy_1') !!}
|
||||
<br><br>
|
||||
{!! __('shop.open_copy_2') !!}
|
||||
<br><br>
|
||||
<strong>{{ __('shop.open_note_hl') }}</strong><br>
|
||||
{!! __('shop.open_note_1') !!}
|
||||
<hr>
|
||||
<span class="badge badge-pill badge-primary">{{ __('shop.your_current_shop_name') }}</span> <strong><a href="{{ $user_shop_domain }}" target="_blank">{{ $user_shop_domain }}</a></strong>
|
||||
</p>
|
||||
<div class="form-group">
|
||||
<div class="input-group mt-2 mb-2 ">
|
||||
{{ Form::text('user_shop_name', old('user_shop_name'), array('placeholder'=>__('shop.your_shop_name'), 'class'=>'form-control'.$shop_name_form_control.($errors->has('user_shop_name') ? ' is-invalid' : ''), 'id'=>'user_shop_name', 'tabindex' => 2)) }}
|
||||
<span class="input-group-append">
|
||||
<button class="btn {{ $shop_name_btn_color }}" type="submit" name="shop_submit" value="check"><i class="fa {{ $shop_name_fa }}"></i> {{ __('shop.check') }}!</button>
|
||||
</span>
|
||||
</div>
|
||||
@if ($errors->has('user_shop_name'))
|
||||
<span class="invalid-feedback" style="display: inline-block;">
|
||||
<strong>{{ $errors->first('user_shop_name') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
<div class="from-group mt-2 mb-2 ">
|
||||
{{ Form::text('preview_user_shop_name', '', array('placeholder'=>__('shop.preview_shop_internet_address'), 'class'=>'form-control', 'id'=>'preview_user_shop_name', 'readonly')) }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="custom-control custom-checkbox m-0">
|
||||
<input type="checkbox" class="custom-control-input {{ $errors->has('user_shop_active') ? 'is-invalid' : '' }}" name="user_shop_active" id="user_shop_active" tabindex = "1">
|
||||
<span class="custom-control-label">{!! __('shop.declaration_of_shop') !!}</span>
|
||||
|
||||
</label>
|
||||
@if ($errors->has('user_shop_active'))
|
||||
<span class="invalid-feedback" style="display: inline-block;">
|
||||
<strong>{{ $errors->first('user_shop_active') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
<hr>
|
||||
<div class="text-left mt-3">
|
||||
<button type="submit" class="btn btn-secondary" name="shop_submit" value="action">{{__('shop.accept_and_change') }}</button>
|
||||
|
||||
</div>
|
||||
|
||||
{!! Form::close() !!}
|
||||
|
||||
</div>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
$( document ).ready(function() {
|
||||
|
||||
$.extend( $.validator.messages, {
|
||||
required: "{{__('account.validator_required')}}",
|
||||
maxlength: $.validator.format( "{{__('account.validator_maxlength')}}" ),
|
||||
minlength: $.validator.format( "{{__('account.validator_minlength')}}" ),
|
||||
rangelength: $.validator.format( "{{__('account.validator_rangelength')}}" ),
|
||||
email: "{{__('account.validator_email')}}",
|
||||
url: "{{__('account.validator_url')}}",
|
||||
date: "{{__('account.validator_date')}}",
|
||||
number: "{{__('account.validator_number')}}",
|
||||
digits: "{{__('account.validator_digits')}}",
|
||||
equalTo: "{{__('account.validator_equalTo')}}",
|
||||
range: $.validator.format( "{{__('account.validator_range')}}" ),
|
||||
max: $.validator.format( "{{__('account.validator_max')}}" ),
|
||||
min: $.validator.format( "{{__('account.validator_min')}}" ),
|
||||
creditcard: "{{__('account.validator_creditcard')}}"
|
||||
});
|
||||
|
||||
|
||||
// Set up validator
|
||||
var message = 'Default error message';
|
||||
$('#data-shop-form-validations').validate({
|
||||
rules: {
|
||||
'user_shop_name': {
|
||||
required: true,
|
||||
remote:
|
||||
{
|
||||
url: "{{ route('user_shop_name_check') }}",
|
||||
type: "post",
|
||||
data:
|
||||
{
|
||||
user_shop_name: function()
|
||||
{
|
||||
return $('#data-shop-form-validations :input[name="user_shop_name"]').val();
|
||||
}
|
||||
},
|
||||
encode: true,
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
},
|
||||
dataFilter: function(response) {
|
||||
response = $.parseJSON(response);
|
||||
console.log(response);
|
||||
if (response.success === true){
|
||||
$('#preview_user_shop_name').val(response.preview_user_shop_name);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
message = response.errors.user_shop_name;
|
||||
$('#preview_user_shop_name').val('');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
errorPlacement: function errorPlacement(error, element) {
|
||||
$(element).parents('.form-group').find('.input-group').after(
|
||||
error.addClass('invalid-feedback d-block font-weight-bold')
|
||||
)
|
||||
},
|
||||
highlight: function (element) {
|
||||
|
||||
$(element).parent().find('button').removeClass('btn-success');
|
||||
$(element).parent().find('button').addClass('btn-danger');
|
||||
$(element).parent().find('button i').removeClass('fa-check');
|
||||
$(element).parent().find('button i').addClass('fa-times');
|
||||
|
||||
$(element).removeClass('is-valid');
|
||||
$(element).addClass('is-invalid');
|
||||
},
|
||||
unhighlight: function (element) {
|
||||
$(element).removeClass('is-invalid');
|
||||
$(element).addClass('is-valid');
|
||||
|
||||
$(element).parent().find('button').removeClass('btn-danger');
|
||||
$(element).parent().find('button').addClass('btn-success');
|
||||
$(element).parent().find('button i').removeClass('fa-times');
|
||||
$(element).parent().find('button i').addClass('fa-check');
|
||||
|
||||
$(element).parents('.form-group').find('.is-invalid').removeClass('is-invalid');
|
||||
},
|
||||
messages : {
|
||||
required: "{{__('This field is required.')}}",
|
||||
user_shop_name: {
|
||||
email: "{{ __('Please enter a valid email address.') }}",
|
||||
remote : function(){ return message; }
|
||||
},
|
||||
},
|
||||
onkeyup: function(element) {$(element).valid()},
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
@ -27,9 +27,9 @@
|
|||
|
||||
|
||||
<p class="mt-2">
|
||||
{{ __('shop.open_copy_1') }}
|
||||
{!! __('shop.open_copy_1') !!}
|
||||
<br><br>
|
||||
{{ __('shop.open_copy_2') }}
|
||||
{!! __('shop.open_copy_2') !!}
|
||||
<br><br>
|
||||
<strong>{{ __('shop.open_note_hl') }}</strong><br>
|
||||
{{ __('shop.open_note_1') }}
|
||||
|
|
|
|||
23
resources/views/user/shop_edit_name.blade.php
Normal file
23
resources/views/user/shop_edit_name.blade.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
@extends('layouts.layout-2')
|
||||
|
||||
@section('content')
|
||||
|
||||
{{-- @if ($errors->any())
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
--}}
|
||||
<h4 class="font-weight-bold py-2 mb-2">
|
||||
{{ __('navigation.my_shop') }}
|
||||
</h4>
|
||||
@include('user.components.user_shop_edit_name')
|
||||
@endsection
|
||||
|
|
@ -68,9 +68,10 @@
|
|||
href="{{url('/geschaeftsmodell/karrierechancen')}}">{{ __('website.career_opportunities') }} </a></li>
|
||||
<li class="{{ Request::is('kontakt') ? ' active' : '' }}"><a
|
||||
href="{{url('/kontakt')}}">{{ __('website.contact') }} </a></li>
|
||||
<li class="{{ Request::is('partner') ? ' register_user' : '' }}"><a
|
||||
<li class="{{ Request::is('partner') ? ' active' : '' }}"><a
|
||||
href="{{url('/partner')}}">{{ __('website.partner') }}</a></li>
|
||||
<li class="{{ Request::is('register_user') ? ' active' : '' }}">
|
||||
<li class="{{ Request::is('registrierung') ? ' active' : '' }}"><a
|
||||
href="{{url('/registrierung')}}">{{ __('website.register') }}</a></li>
|
||||
</ul>
|
||||
<!-- /Links -->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@
|
|||
<li class="{{ Request::is('partner') ? ' active' : '' }}"><a
|
||||
href="{{url('/partner')}}">{{ __('website.partner') }}</a></li>
|
||||
@if($user_shop)
|
||||
<li class="{{ Request::is('register_user') ? ' active' : '' }}"><a
|
||||
<li class="{{ Request::is('registrierung') ? ' active' : '' }}"><a
|
||||
href="{{url('/registrierung')}}">{{ __('website.register') }}</a></li>
|
||||
@endif
|
||||
</ul>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue