option('dry-run'); $months = $this->months($service); if ($months === null) { return self::FAILURE; } foreach ($months as ['month' => $month, 'year' => $year]) { $drift = $dryRun ? $service->detectDrift($month, $year) : $service->repair($month, $year); $label = sprintf('%02d/%d', $month, $year); if ($drift === []) { $this->info("Laufstaende {$label}: keine Abweichung."); continue; } $users = User::query()->whereIn('id', array_keys($drift))->get()->keyBy('id'); $this->warn(sprintf( 'Laufstaende %s: %d User mit Drift%s', $label, count($drift), $dryRun ? ' (DRY-RUN, nichts geschrieben)' : ', neu berechnet' )); $this->table( ['User', 'E-Mail', 'Zeilensumme', 'Laufstand vorher', 'Diff'], collect($drift)->map(fn (array $values, int $userId) => [ $userId, $users->get($userId)?->email ?? '-', number_format($values['rows'], 2, ',', '.'), number_format($values['running'], 2, ',', '.'), number_format($values['running'] - $values['rows'], 2, ',', '.'), ])->values()->all() ); \Log::channel('cron')->warning('sales:repair-running-totals: Laufstand-Drift', [ 'month' => $month, 'year' => $year, 'dry_run' => $dryRun, 'users' => $drift, ]); } return self::SUCCESS; } /** * @return array|null */ private function months(SalesVolumeRunningTotalService $service): ?array { if (! $this->argument('month')) { return $service->monthsToGuard(); } $month = (int) $this->argument('month'); $year = (int) ($this->argument('year') ?: now()->year); if ($month < 1 || $month > 12 || $year < 2020) { $this->error('Ungueltiger Monat/Jahr.'); return null; } if (SalesVolumeRunningTotalService::isMonthClosed($month, $year) && ! $this->option('dry-run') && ! $this->option('force')) { $this->error(sprintf( 'Monat %02d/%d ist abgerechnet — die Laufstaende sind so in die Provision eingegangen. Neu rechnen nur mit --force (aendert keine Gutschriften, nur die Datenbasis).', $month, $year )); return null; } return [['month' => $month, 'year' => $year]]; } }