23-01-2026
This commit is contained in:
parent
a939cd51ef
commit
a8b395e20d
248 changed files with 29342 additions and 4805 deletions
226
app/Console/Commands/DhlUpdateTracking.php
Normal file
226
app/Console/Commands/DhlUpdateTracking.php
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Acme\Dhl\Models\DhlShipment;
|
||||
use App\Mail\MailDhlTracking;
|
||||
use App\Services\DhlTrackingService;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class DhlUpdateTracking extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'dhl:update-tracking
|
||||
{--days=14 : Sendungen der letzten X Tage aktualisieren}
|
||||
{--send-emails : Automatisch E-Mails bei Transit-Status senden}
|
||||
{--dry-run : Nur simulieren, keine Änderungen}
|
||||
{--test-email= : Test-E-Mail an angegebene Adresse senden}
|
||||
{--order= : Nur für bestimmte Bestellung (Order-ID)}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Aktualisiert Tracking-Status für alle aktiven DHL Sendungen und sendet automatisch E-Mails bei Transit-Status';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$days = (int) $this->option('days');
|
||||
$sendEmails = $this->option('send-emails');
|
||||
$dryRun = $this->option('dry-run');
|
||||
$testEmail = $this->option('test-email');
|
||||
$orderId = $this->option('order');
|
||||
|
||||
$this->info('DHL Tracking Update gestartet');
|
||||
$this->info("Optionen: --days={$days}, --send-emails=" . ($sendEmails ? 'ja' : 'nein') . ', --dry-run=' . ($dryRun ? 'ja' : 'nein'));
|
||||
if ($testEmail) {
|
||||
$this->info("Test-Modus: E-Mails werden an {$testEmail} gesendet");
|
||||
}
|
||||
if ($orderId) {
|
||||
$this->info("Filter: Nur Order-ID {$orderId}");
|
||||
}
|
||||
$this->newLine();
|
||||
|
||||
// Hole alle aktiven Sendungen der letzten X Tage
|
||||
$query = DhlShipment::active()
|
||||
->where('created_at', '>=', now()->subDays($days))
|
||||
->whereNotNull('dhl_shipment_no');
|
||||
|
||||
// Filter nach Order-ID wenn angegeben
|
||||
if ($orderId) {
|
||||
$query->where('order_id', $orderId);
|
||||
}
|
||||
|
||||
$shipments = $query->orderBy('created_at', 'desc')->get();
|
||||
|
||||
$total = $shipments->count();
|
||||
$this->info("Gefundene aktive Sendungen: {$total}");
|
||||
|
||||
if ($total === 0) {
|
||||
$this->info('Keine Sendungen zum Aktualisieren gefunden.');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$bar = $this->output->createProgressBar($total);
|
||||
$bar->start();
|
||||
|
||||
$trackingService = new DhlTrackingService;
|
||||
$stats = [
|
||||
'updated' => 0,
|
||||
'failed' => 0,
|
||||
'emails_sent' => 0,
|
||||
'skipped' => 0,
|
||||
];
|
||||
|
||||
foreach ($shipments as $shipment) {
|
||||
try {
|
||||
$oldStatus = $shipment->status;
|
||||
|
||||
if (! $dryRun) {
|
||||
// Tracking aktualisieren
|
||||
$result = $trackingService->updateTracking($shipment, ['auto_retrack' => false]);
|
||||
|
||||
if ($result['success']) {
|
||||
$shipment->refresh();
|
||||
$stats['updated']++;
|
||||
|
||||
// Prüfen ob E-Mail gesendet werden soll
|
||||
if ($sendEmails && $this->shouldSendEmail($shipment, $oldStatus)) {
|
||||
$this->sendTrackingEmail($shipment, $testEmail);
|
||||
$stats['emails_sent']++;
|
||||
}
|
||||
} else {
|
||||
$stats['failed']++;
|
||||
Log::warning('[DHL Cron] Tracking update failed', [
|
||||
'shipment_id' => $shipment->id,
|
||||
'message' => $result['message'] ?? 'Unknown error',
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$stats['skipped']++;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$stats['failed']++;
|
||||
Log::error('[DHL Cron] Exception during tracking update', [
|
||||
'shipment_id' => $shipment->id,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
|
||||
$bar->advance();
|
||||
}
|
||||
|
||||
$bar->finish();
|
||||
$this->newLine(2);
|
||||
|
||||
// Zusammenfassung
|
||||
$this->info('Zusammenfassung:');
|
||||
$this->table(
|
||||
['Metrik', 'Anzahl'],
|
||||
[
|
||||
['Gesamt', $total],
|
||||
['Aktualisiert', $stats['updated']],
|
||||
['Fehlgeschlagen', $stats['failed']],
|
||||
['E-Mails gesendet', $stats['emails_sent']],
|
||||
['Übersprungen (Dry-Run)', $stats['skipped']],
|
||||
]
|
||||
);
|
||||
|
||||
Log::info('[DHL Cron] Tracking update completed', $stats);
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ob eine E-Mail gesendet werden soll
|
||||
*/
|
||||
private function shouldSendEmail(DhlShipment $shipment, string $oldStatus): bool
|
||||
{
|
||||
// E-Mail nur senden wenn:
|
||||
// 1. Status ist jetzt "in_transit"
|
||||
// 2. Vorheriger Status war NICHT "in_transit" (also Status hat sich geändert)
|
||||
// 3. Noch keine E-Mail gesendet wurde
|
||||
return $shipment->status === 'in_transit'
|
||||
&& $oldStatus !== 'in_transit'
|
||||
&& ! $shipment->wasTrackingEmailSent()
|
||||
&& $shipment->canSendTrackingEmail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sendet die Tracking-E-Mail (mit Unterstützung für mehrere Sendungen pro Bestellung)
|
||||
*/
|
||||
private function sendTrackingEmail(DhlShipment $shipment, ?string $testEmail = null): void
|
||||
{
|
||||
try {
|
||||
$order = $shipment->shoppingOrder;
|
||||
|
||||
// Determine recipient email: test email > shipment email > shopping user email
|
||||
$recipientEmail = null;
|
||||
if ($testEmail) {
|
||||
$recipientEmail = $testEmail;
|
||||
} elseif (! empty($shipment->email)) {
|
||||
$recipientEmail = $shipment->email;
|
||||
} elseif ($order->shopping_user && ! empty($order->shopping_user->email)) {
|
||||
$recipientEmail = $order->shopping_user->email;
|
||||
}
|
||||
|
||||
if (! $recipientEmail) {
|
||||
Log::warning('[DHL Cron] Cannot send email - no recipient', [
|
||||
'shipment_id' => $shipment->id,
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Sammle alle Sendungen für diese Bestellung, die noch keine E-Mail erhalten haben
|
||||
$allShipments = DhlShipment::where('order_id', $order->id)
|
||||
->where('status', 'in_transit')
|
||||
->whereNotNull('dhl_shipment_no')
|
||||
->whereNull('tracking_email_sent_at')
|
||||
->get();
|
||||
|
||||
// Wenn keine Sendungen gefunden, nutze nur die aktuelle
|
||||
if ($allShipments->isEmpty()) {
|
||||
$allShipments = collect([$shipment]);
|
||||
}
|
||||
|
||||
// Sende E-Mail mit allen Sendungen
|
||||
Mail::to($recipientEmail)->send(new MailDhlTracking($allShipments, $order));
|
||||
|
||||
// Markiere alle Sendungen als versendet
|
||||
foreach ($allShipments as $s) {
|
||||
$s->markTrackingEmailSent('auto');
|
||||
}
|
||||
|
||||
Log::info('[DHL Cron] Tracking email sent automatically', [
|
||||
'shipment_ids' => $allShipments->pluck('id')->toArray(),
|
||||
'shipments_count' => $allShipments->count(),
|
||||
'dhl_shipment_nos' => $allShipments->pluck('dhl_shipment_no')->toArray(),
|
||||
'email' => $recipientEmail,
|
||||
'is_test' => ! is_null($testEmail),
|
||||
]);
|
||||
|
||||
if ($allShipments->count() > 1) {
|
||||
$this->line(" -> E-Mail mit {$allShipments->count()} Sendungen gesendet an: {$recipientEmail}");
|
||||
} else {
|
||||
$this->line(" -> E-Mail gesendet an: {$recipientEmail}");
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('[DHL Cron] Failed to send tracking email', [
|
||||
'shipment_id' => $shipment->id,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue