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
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue