option('month') ?: now()->month); $year = (int) ($this->option('year') ?: now()->year); $dryRun = ! $this->option('force'); $isCurrentMonth = $month === (int) now()->month && $year === (int) now()->year; if (! $dryRun && ! $isCurrentMonth && ! $this->option('allow-closed-month')) { $this->error("Korrektur in {$month}/{$year} abgelehnt: das ist nicht der laufende Monat."); $this->line('Abgeschlossene Provisionsmonate bleiben so, wie sie abgerechnet wurden.'); $this->line('Nur wenn das wirklich gewollt ist: --allow-closed-month'); return self::FAILURE; } $this->info("Punkte-Repair für {$month}/{$year}".($dryRun ? ' (TROCKENLAUF — es wird nichts geschrieben)' : '')); $result = $service->repair($month, $year, $dryRun); if ($result['orders'] === []) { $this->info('Keine abweichenden Punkte gefunden. Nichts zu tun.'); return self::SUCCESS; } if ($result['addon_items'] !== []) { $this->newLine(); $this->info('Abo-Einmalartikel (abgeschnitten):'); $this->table( ['Order', 'Position', 'Produkt', 'von', 'auf', 'Menge', 'Delta'], array_map(fn (array $row) => [ $row['order_id'], $row['item_id'], mb_strimwidth($row['product'], 0, 40, '…'), number_format($row['from'], 2, ',', '.'), number_format($row['to'], 2, ',', '.'), $row['qty'], number_format($row['delta'], 2, ',', '.'), ], $result['addon_items']) ); } if ($result['collect_orders'] !== []) { $this->newLine(); $this->info('Sammelbestellungen (gerundet):'); $this->table( ['Order', 'Sammel-ID', 'von', 'auf', 'Delta'], array_map(fn (array $row) => [ $row['order_id'], $row['collect_id'], number_format($row['from'], 2, ',', '.'), number_format($row['to'], 2, ',', '.'), number_format($row['delta'], 2, ',', '.'), ], $result['collect_orders']) ); } $this->newLine(); $this->info('Zusammenfassung:'); $this->line(' Korrigierte Positionen: '.count($result['addon_items'])); $this->line(' Korrigierte Sammelbest.: '.count($result['collect_orders'])); $this->line(' Betroffene Bestellungen: '.count($result['orders'])); $this->line(' Betroffene Umsatz-Zeilen: '.count($result['sales_volumes'])); $this->line(' Betroffene Berater: '.count($result['users_recalculated'])); $this->line(' Punkte-Differenz gesamt: '.number_format($result['total_delta'], 2, ',', '.')); if ($dryRun) { $this->newLine(); $this->warn('Trockenlauf — es wurde nichts geschrieben. Zum Schreiben: --force'); return self::SUCCESS; } $this->newLine(); $this->info('Geschrieben. Monatssummen für '.count($result['users_recalculated']).' Berater neu berechnet.'); $this->line('Bereits ausgestellte Rechnungen/Lieferscheine bleiben unverändert (PDFs im Storage).'); return self::SUCCESS; } }