mivita/app/Console/Commands/IncentiveDebugTrackSalesVolume.php
2026-04-10 17:15:27 +02:00

241 lines
10 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\Incentive;
use App\Models\IncentiveNewAbo;
use App\Models\IncentiveNewPartner;
use App\Models\IncentivePointsLog;
use App\Models\ShoppingOrder;
use App\Models\UserSalesVolume;
use Illuminate\Console\Command;
class IncentiveDebugTrackSalesVolume extends Command
{
protected $signature = 'incentive:debug-track-sv {sv_id : UserSalesVolume ID}';
protected $description = 'Debuggt trackSalesVolume Schritt fuer Schritt fuer einen bestimmten SalesVolume-Eintrag';
public function handle(): int
{
$sv_id = $this->argument('sv_id');
$usv = UserSalesVolume::find($sv_id);
if (! $usv) {
$this->error("UserSalesVolume #{$sv_id} nicht gefunden.");
return self::FAILURE;
}
$this->info("=== Debug trackSalesVolume fuer USV #{$sv_id} ===");
$this->newLine();
// 1. SalesVolume-Daten
$this->info('[1] SalesVolume-Daten:');
$this->table(['Feld', 'Wert'], [
['id', $usv->id],
['user_id', $usv->user_id ?? 'NULL'],
['shopping_order_id', $usv->shopping_order_id ?? 'NULL'],
['user_invoice_id', $usv->user_invoice_id ?? 'NULL'],
['month', $usv->month ?? 'NULL'],
['year', $usv->year ?? 'NULL'],
['points', $usv->getRawOriginal('points') ?? 'NULL'],
['status', $usv->status.' ('.($usv->getStatusType() ?: '-').')'],
['status_points', $usv->status_points ?? 'NULL'],
['status_turnover', $usv->status_turnover ?? 'NULL'],
['message', $usv->message ?? 'NULL'],
]);
// 2. Fruehe Abbruch-Checks
$month = $usv->month;
$year = $usv->year;
if (! $month || ! $year) {
$this->error('[ABBRUCH] month oder year ist NULL -> return');
return self::SUCCESS;
}
$points = (int) abs($usv->getRawOriginal('points') ?? 0);
if ($points <= 0) {
$this->error("[ABBRUCH] points = {$points} (<= 0) -> return");
return self::SUCCESS;
}
$this->info(" Effektive Punkte: {$points}");
// 3. Aktive Incentives
$this->newLine();
$this->info('[2] Aktive Incentives:');
$active_incentives = Incentive::query()->active()->get();
$this->info(" Anzahl aktive: {$active_incentives->count()}");
foreach ($active_incentives as $incentive) {
$in_scope = $incentive->isDateInScope($month, $year);
$scope_label = $in_scope ? 'IM SCOPE' : 'AUSSERHALB';
$this->info(" #{$incentive->id} {$incentive->name}: {$month}/{$year} -> {$scope_label}");
$this->info(" Qualification: {$incentive->qualification_start} - {$incentive->qualification_end}, Calc End: {$incentive->calculation_end}");
}
// ===== TEIL A: Neupartner-Check =====
$this->newLine();
$this->info('========================================');
$this->info('[A] NEUPARTNER-CHECK: Ist User #'.$usv->user_id.' ein gettrackter Neupartner?');
$this->info('========================================');
$partner_trackings = IncentiveNewPartner::where('user_id', $usv->user_id)
->with('participant.incentive')
->get();
$this->info(" IncentiveNewPartner-Eintraege fuer user_id={$usv->user_id}: {$partner_trackings->count()}");
if ($partner_trackings->isEmpty()) {
$this->warn(' -> User ist KEIN gettrackter Neupartner in irgendeinem Incentive.');
}
foreach ($partner_trackings as $tracking) {
$participant = $tracking->participant;
$incentive = $participant->incentive ?? null;
$this->newLine();
$this->table(['Feld', 'Wert'], [
['NewPartner #', $tracking->id],
['participant_id', $tracking->participant_id],
['Participant User', $participant->user_id],
['Incentive', $incentive ? "#{$incentive->id}: {$incentive->name}" : 'NULL'],
['Incentive Status', $incentive ? $incentive->status : 'NULL'],
['Incentive aktiv?', $incentive && $incentive->status == 1 ? 'JA' : 'NEIN'],
]);
if (! $incentive || $incentive->status != 1) {
$this->warn(' -> Incentive nicht aktiv -> SKIP');
continue;
}
$in_scope = $incentive->isDateInScope($month, $year);
$this->info(" isDateInScope({$month}, {$year}): ".($in_scope ? 'JA' : 'NEIN'));
if (! $in_scope) {
$this->warn(' -> Monat/Jahr ausserhalb Scope -> SKIP');
continue;
}
// Duplikat-Check
$exists = IncentivePointsLog::where('participant_id', $participant->id)
->where('user_sales_volume_id', $usv->id)
->where('is_storno', false)
->exists();
$this->info(' Log-Eintrag existiert bereits: '.($exists ? 'JA (Duplikat -> kein neuer Eintrag)' : 'NEIN -> wuerde erstellt'));
$this->info(' ==> MATCH! Punkte wuerden Participant #'.$participant->id." (User #{$participant->user_id}) gutgeschrieben");
$this->info(" Typ: partner, Punkte: {$points} (accumulated)");
}
// ===== TEIL B: Neuabo-Check =====
$this->newLine();
$this->info('========================================');
$this->info('[B] NEUABO-CHECK: Stammt die Bestellung von einem gettrackten Abo-Kunden?');
$this->info('========================================');
if (! $usv->shopping_order_id) {
$this->warn(' shopping_order_id ist NULL -> Abo-Check uebersprungen.');
} else {
$order = ShoppingOrder::find($usv->shopping_order_id);
if (! $order) {
$this->error(" ShoppingOrder #{$usv->shopping_order_id} nicht gefunden.");
} else {
$this->table(['Feld', 'Wert'], [
['Order ID', $order->id],
['shopping_user_id', $order->shopping_user_id ?? 'NULL'],
['auth_user_id', $order->auth_user_id ?? 'NULL'],
['member_id', $order->member_id ?? 'NULL'],
['payment_for', $order->payment_for],
['is_abo', $order->is_abo ? 'JA' : 'NEIN'],
]);
if (! $order->shopping_user_id) {
$this->warn(' shopping_user_id ist NULL -> kein Abo-Matching moeglich.');
} else {
$abo_trackings = IncentiveNewAbo::whereHas(
'userAbo',
fn ($q) => $q->where('shopping_user_id', $order->shopping_user_id)
)
->with('participant.incentive', 'userAbo')
->get();
$this->info(" IncentiveNewAbo mit shopping_user_id={$order->shopping_user_id}: {$abo_trackings->count()}");
if ($abo_trackings->isEmpty()) {
$this->warn(' -> Keine gettrackten Abos fuer diesen Kunden.');
}
foreach ($abo_trackings as $tracking) {
$participant = $tracking->participant;
$incentive = $participant->incentive ?? null;
$abo = $tracking->userAbo;
$this->newLine();
$this->table(['Feld', 'Wert'], [
['NewAbo #', $tracking->id],
['user_abo_id', $tracking->user_abo_id],
['Abo shopping_user_id', $abo ? $abo->shopping_user_id : 'NULL'],
['participant_id', $tracking->participant_id],
['Participant User', $participant->user_id],
['Incentive', $incentive ? "#{$incentive->id}: {$incentive->name}" : 'NULL'],
['Incentive aktiv?', $incentive && $incentive->status == 1 ? 'JA' : 'NEIN'],
]);
if (! $incentive || $incentive->status != 1) {
$this->warn(' -> Incentive nicht aktiv -> SKIP');
continue;
}
$in_scope = $incentive->isDateInScope($month, $year);
$this->info(" isDateInScope({$month}, {$year}): ".($in_scope ? 'JA' : 'NEIN'));
if (! $in_scope) {
$this->warn(' -> Monat/Jahr ausserhalb Scope -> SKIP');
continue;
}
$exists = IncentivePointsLog::where('participant_id', $participant->id)
->where('user_sales_volume_id', $usv->id)
->where('is_storno', false)
->exists();
$this->info(' Log-Eintrag existiert bereits: '.($exists ? 'JA (Duplikat)' : 'NEIN -> wuerde erstellt'));
$this->info(' ==> MATCH! Punkte wuerden Participant #'.$participant->id." (User #{$participant->user_id}) gutgeschrieben");
$this->info(" Typ: abo, Punkte: {$points} (accumulated)");
}
}
}
}
// ===== Zusammenfassung =====
$this->newLine();
$this->info('=== ZUSAMMENFASSUNG ===');
$total_partner = $partner_trackings->filter(function ($t) use ($month, $year) {
return $t->participant->incentive
&& $t->participant->incentive->status == 1
&& $t->participant->incentive->isDateInScope($month, $year);
})->count();
$this->info(" Neupartner-Matches: {$total_partner}");
$this->info(' Neuabo-Matches: siehe oben');
if ($total_partner === 0) {
$this->warn(' -> Keine Punkte wuerden vergeben (kein Match).');
}
return self::SUCCESS;
}
}