10.April 2026
This commit is contained in:
parent
a00c42e770
commit
f58c709945
208 changed files with 19280 additions and 2914 deletions
129
app/Console/Commands/RepairMissingInvoices.php
Normal file
129
app/Console/Commands/RepairMissingInvoices.php
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Repositories\InvoiceRepository;
|
||||
use App\Services\BusinessPlan\SalesPointsVolume;
|
||||
use App\Services\Incentive\IncentiveTracker;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class RepairMissingInvoices extends Command
|
||||
{
|
||||
protected $signature = 'repair:missing-invoices
|
||||
{--fix : Tatsaechlich reparieren (ohne Flag nur Vorschau)}
|
||||
{--no-mail : Keine Rechnungs-Mails versenden}
|
||||
{--since=2026-02-20 : Ab welchem Datum suchen}';
|
||||
|
||||
protected $description = 'Repariert fehlende Rechnungen und SalesVolumes fuer bezahlte Bestellungen (Bug: addSalesPointsVolumeUser)';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$since = $this->option('since') ?? '2026-03-16';
|
||||
$fix = $this->option('fix') ?? false;
|
||||
|
||||
$orders = ShoppingOrder::query()
|
||||
->where('mode', 'live')
|
||||
->where('paid', 0)
|
||||
->where('txaction', 'paid')
|
||||
->where('created_at', '>=', $since)
|
||||
->whereNull('deleted_at')
|
||||
->whereDoesntHave('user_invoice')
|
||||
->whereDoesntHave('user_sales_volume')
|
||||
// ->whereDoesntHave('shopping_payments', fn($q) => $q->where('clearingtype', 'vor'))
|
||||
->orderBy('created_at')
|
||||
->get();
|
||||
|
||||
$this->info("Betroffene Bestellungen seit {$since}: {$orders->count()}");
|
||||
|
||||
if ($orders->isEmpty()) {
|
||||
$this->info('Keine betroffenen Bestellungen gefunden.');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
// Zusammenfassung
|
||||
$total = $orders->sum('total');
|
||||
$byPaymentFor = $orders->groupBy('payment_for')->map->count();
|
||||
$this->table(
|
||||
['payment_for', 'Anzahl'],
|
||||
$byPaymentFor->map(fn ($count, $type) => [$type, $count])->values()
|
||||
);
|
||||
$this->info("Gesamtwert: {$total} EUR");
|
||||
|
||||
if (! $fix) {
|
||||
$this->warn('Trockenlauf! Nutze --fix um die Reparatur durchzufuehren.');
|
||||
$this->newLine();
|
||||
|
||||
// Erste 10 anzeigen
|
||||
$this->table(
|
||||
['ID', 'payment_for', 'total', 'txaction', 'created_at'],
|
||||
$orders->take(100)->map(fn ($o) => [
|
||||
$o->id,
|
||||
$o->payment_for,
|
||||
$o->total,
|
||||
$o->txaction,
|
||||
$o->created_at->format('Y-m-d H:i'),
|
||||
])
|
||||
);
|
||||
|
||||
if ($orders->count() > 100) {
|
||||
$this->info('... und '.($orders->count() - 100).' weitere');
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$send_mail = ! $this->option('no-mail');
|
||||
|
||||
if ($send_mail) {
|
||||
$this->info('Rechnungs-Mails werden versendet. Nutze --no-mail um dies zu unterdruecken.');
|
||||
} else {
|
||||
$this->warn('Rechnungs-Mails werden NICHT versendet.');
|
||||
}
|
||||
|
||||
if (! $this->confirm("Wirklich {$orders->count()} Bestellungen reparieren?")) {
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$success = 0;
|
||||
$errors = 0;
|
||||
$bar = $this->output->createProgressBar($orders->count());
|
||||
$bar->start();
|
||||
|
||||
foreach ($orders as $order) {
|
||||
try {
|
||||
// 1. SalesVolume erstellen
|
||||
$user_sales_volume = SalesPointsVolume::User($order);
|
||||
|
||||
// 2. Rechnung erstellen (mit Mail-Versand)
|
||||
$invoice_repo = new InvoiceRepository($order);
|
||||
$user_invoice = $invoice_repo->create([
|
||||
'invoice_send_mail' => $send_mail,
|
||||
]);
|
||||
|
||||
// 3. SalesVolume mit Rechnung verknuepfen
|
||||
$user_sales_volume->user_invoice_id = $user_invoice->id;
|
||||
$user_sales_volume->save();
|
||||
|
||||
// 4. Incentive tracking (falls relevant)
|
||||
IncentiveTracker::trackSalesVolume($user_sales_volume);
|
||||
|
||||
$success++;
|
||||
$this->info("Order #{$order->id}: Reparatur erfolgreich");
|
||||
} catch (\Throwable $e) {
|
||||
$errors++;
|
||||
$this->newLine();
|
||||
$this->error("Order #{$order->id}: {$e->getMessage()}");
|
||||
}
|
||||
|
||||
$bar->advance();
|
||||
}
|
||||
|
||||
$bar->finish();
|
||||
$this->newLine(2);
|
||||
$this->info("Fertig: {$success} repariert, {$errors} Fehler.");
|
||||
|
||||
return $errors > 0 ? self::FAILURE : self::SUCCESS;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue