54 lines
1.6 KiB
PHP
54 lines
1.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Incentive;
|
|
|
|
use App\Models\Incentive;
|
|
use App\Models\IncentiveParticipant;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class IncentiveCalculationService
|
|
{
|
|
/**
|
|
* Full recalculation of an incentive (batch / cron / manual).
|
|
* Normal: Neuberechnung aus Tracking-Tabellen + Log.
|
|
* Force: Kompletter Neuaufbau aus Quelldaten (Users, UserAbos, UserSalesVolumes).
|
|
*/
|
|
public function recalculate(Incentive $incentive, bool $force = false): array
|
|
{
|
|
$stats = ['participants' => 0, 'errors' => 0];
|
|
|
|
$participants = $incentive->participants()->with('user')->get();
|
|
|
|
foreach ($participants as $participant) {
|
|
try {
|
|
$this->recalculateParticipant($participant, $force);
|
|
$stats['participants']++;
|
|
} catch (\Throwable $e) {
|
|
$stats['errors']++;
|
|
Log::error('IncentiveCalculation error for participant '.$participant->id.': '.$e->getMessage());
|
|
}
|
|
}
|
|
|
|
IncentiveTracker::updateRanking($incentive);
|
|
|
|
return $stats;
|
|
}
|
|
|
|
/**
|
|
* Recalculate a single participant.
|
|
* Force: Kompletter Neuaufbau aus Quelldaten.
|
|
* Normal: Neuberechnung aus vorhandenen Tracking-Tabellen + Log.
|
|
*/
|
|
public function recalculateParticipant(IncentiveParticipant $participant, bool $force = false): void
|
|
{
|
|
if (! $participant->user) {
|
|
return;
|
|
}
|
|
|
|
if ($force) {
|
|
$participant->rebuildFromSourceTables()->save();
|
|
} else {
|
|
$participant->recalculateFromTrackingTables()->save();
|
|
}
|
|
}
|
|
}
|