mivita/resources/views/admin/dhl/cockpit.blade.php
2025-10-20 17:42:08 +02:00

496 lines
No EOL
19 KiB
PHP

@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>
<!-- 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="float-right">
<button type="button" class="btn btn-sm 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 class="batch-actions" style="display: none;">
{{-- Todo: Add cancel button
<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,
searching: false,
pageLength: 50,
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();
console.log(('#date_from').val());
console.log(('#date_to').val());
dhlTable.draw();
});
// Auto-reload on specific filter changes
$('#type, #status').change(function() {
dhlTable.draw();
});
// Tooltip initialization for static elements
$('[data-toggle="tooltip"]').tooltip();
// 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;
}
console.log(selectedIds);
console.log(action);
// Perform batch action
if (action === 'download_labels') {
// Handle file download differently
$.ajax({
url: '{{ route("admin.dhl.batch-action") }}',
method: 'POST',
data: {
action: action,
shipment_ids: selectedIds,
_token: '{{ csrf_token() }}'
},
xhrFields: {
responseType: 'blob'
},
success: function(data, status, xhr) {
// Check if it's actually a JSON error response
if (xhr.getResponseHeader('content-type') && xhr.getResponseHeader('content-type').indexOf('application/json') !== -1) {
var reader = new FileReader();
reader.onload = function() {
try {
var response = JSON.parse(reader.result);
if (response.success) {
showAlert('success', response.message);
} else {
showAlert('error', response.message);
}
} catch (e) {
showAlert('error', 'Fehler beim Verarbeiten der Antwort.');
}
};
reader.readAsText(data);
} else {
// It's a file download
var blob = new Blob([data]);
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = 'dhl_labels_' + new Date().toISOString().slice(0,19).replace(/:/g, '-') + '.zip';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
showAlert('success', 'Labels werden heruntergeladen...');
}
},
error: function(xhr) {
showAlert('error', 'Fehler beim Download der Labels.');
}
});
} else {
// Handle other batch actions normally
$.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();
});
*/
// 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">&times;</span>
</button>
</div>
`;
$('h4.font-weight-bold').after(alertHtml);
// Auto-hide after 5 seconds
setTimeout(function() {
$('.alert').alert('close');
}, 5000);
}
});
</script>
@endsection