update 20.10.2025
This commit is contained in:
parent
8c11130b5d
commit
a939cd51ef
616 changed files with 84821 additions and 4121 deletions
136
app/Console/Commands/BusinessClearData.php
Normal file
136
app/Console/Commands/BusinessClearData.php
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\UserBusinessStructure;
|
||||
use App\Models\UserBusiness;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class BusinessClearData extends Command
|
||||
{
|
||||
/**
|
||||
* php artisan business:clear-data {month} {year}
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'business:clear-data {month} {year} {--force : Force deletion without confirmation}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Clear stored business structure data for a specific month/year';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
try {
|
||||
$month = (int) $this->argument('month');
|
||||
$year = (int) $this->argument('year');
|
||||
|
||||
// Validierung
|
||||
if ($month < 1 || $month > 12) {
|
||||
$this->error('Invalid month. Must be between 1 and 12.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
$currentYear = (int) date('Y');
|
||||
if ($year < 2020 || $year > $currentYear + 1) {
|
||||
$this->error('Invalid year. Must be between 2020 and ' . ($currentYear + 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->info("Preparing to clear business data for month: {$month} | year: {$year}");
|
||||
|
||||
// Finde bestehende Struktur
|
||||
$existingStructure = UserBusinessStructure::where('year', $year)
|
||||
->where('month', $month)
|
||||
->first();
|
||||
|
||||
if (!$existingStructure) {
|
||||
$this->info('No stored business structure found for the specified month/year');
|
||||
return 0;
|
||||
}
|
||||
|
||||
$structureId = $existingStructure->id;
|
||||
$userBusinessCount = UserBusiness::where('b_structure_id', $structureId)->count();
|
||||
$userCount = is_array($existingStructure->users) ? count($existingStructure->users) : 0;
|
||||
|
||||
$this->info("Found structure ID: {$structureId}");
|
||||
$this->info("- UserBusiness records: {$userBusinessCount}");
|
||||
$this->info("- Users in structure: {$userCount}");
|
||||
$this->info("- Completed: " . ($existingStructure->completed ? 'Yes' : 'No'));
|
||||
|
||||
// Bestätigung (außer bei --force)
|
||||
if (!$this->option('force')) {
|
||||
if (!$this->confirm('Are you sure you want to delete this business structure data?')) {
|
||||
$this->info('Operation cancelled by user');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
$startTime = microtime(true);
|
||||
|
||||
// Lösche UserBusiness Einträge
|
||||
if ($userBusinessCount > 0) {
|
||||
$this->info("Deleting {$userBusinessCount} UserBusiness records...");
|
||||
UserBusiness::where('b_structure_id', $structureId)->delete();
|
||||
$this->info('✓ UserBusiness records deleted');
|
||||
}
|
||||
|
||||
// Lösche UserBusinessStructure
|
||||
$this->info('Deleting UserBusinessStructure...');
|
||||
$existingStructure->delete();
|
||||
$this->info('✓ UserBusinessStructure deleted');
|
||||
|
||||
// Garbage Collection
|
||||
gc_collect_cycles();
|
||||
|
||||
$endTime = microtime(true);
|
||||
$duration = round(($endTime - $startTime) * 1000, 2);
|
||||
|
||||
$this->info("✅ Successfully cleared all business data in {$duration}ms");
|
||||
$this->logMemoryUsage();
|
||||
|
||||
return 0;
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Error clearing business data: ' . $e->getMessage());
|
||||
$this->error('Stack trace: ' . $e->getTraceAsString());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loggt aktuelle Memory-Nutzung
|
||||
*/
|
||||
private function logMemoryUsage(): void
|
||||
{
|
||||
$currentMemory = memory_get_usage();
|
||||
$peakMemory = memory_get_peak_usage();
|
||||
|
||||
$currentFormatted = $this->formatBytes($currentMemory);
|
||||
$peakFormatted = $this->formatBytes($peakMemory);
|
||||
|
||||
$this->info("Memory - Current: {$currentFormatted} | Peak: {$peakFormatted}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatiert Bytes in lesbare Einheiten
|
||||
*/
|
||||
private function formatBytes(int $bytes, int $precision = 2): string
|
||||
{
|
||||
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
||||
|
||||
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
|
||||
$bytes /= 1024;
|
||||
}
|
||||
|
||||
return round($bytes, $precision) . ' ' . $units[$i];
|
||||
}
|
||||
}
|
||||
149
app/Console/Commands/BusinessLevelReports.php
Normal file
149
app/Console/Commands/BusinessLevelReports.php
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Services\LevelReportService;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class BusinessLevelReports extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'business:level-reports {--month= : Filter by specific month} {--year= : Filter by specific year} {--user-id= : Filter by specific user ID} {--csv : Export as CSV file} {--not-updated : Show only users not yet updated to their new level}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Generate reports showing who achieved new career levels and when';
|
||||
|
||||
private $levelReportService;
|
||||
|
||||
public function __construct(LevelReportService $levelReportService)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->levelReportService = $levelReportService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
try {
|
||||
$this->info('Generiere Level-Aufstieg-Report...');
|
||||
|
||||
// Filter Parameter
|
||||
$filters = [
|
||||
'month' => $this->option('month'),
|
||||
'year' => $this->option('year'),
|
||||
'user_id' => $this->option('user-id'),
|
||||
'only_not_updated' => $this->option('not-updated')
|
||||
];
|
||||
|
||||
$exportCsv = $this->option('csv');
|
||||
|
||||
// Lade Level-Aufstiege über Service
|
||||
$levelPromotions = $this->levelReportService->getLevelPromotions($filters);
|
||||
|
||||
if ($levelPromotions->isEmpty()) {
|
||||
$this->info('Keine Level-Aufstiege gefunden.');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($exportCsv) {
|
||||
$filepath = $this->levelReportService->exportToCsv($levelPromotions);
|
||||
$this->info('');
|
||||
$this->info('CSV-Export erstellt: ' . $filepath);
|
||||
$this->info('Anzahl Datensätze: ' . $levelPromotions->count());
|
||||
} else {
|
||||
$this->displayReport($levelPromotions);
|
||||
}
|
||||
|
||||
$this->info('Report erfolgreich generiert.');
|
||||
return 0;
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Fehler beim Generieren des Reports: ' . $e->getMessage());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private function displayReport($promotions)
|
||||
{
|
||||
$statistics = $this->levelReportService->getStatistics($promotions);
|
||||
|
||||
$this->info('');
|
||||
$this->info('=== LEVEL-AUFSTIEG REPORT ===');
|
||||
$this->info('');
|
||||
|
||||
if ($promotions->isEmpty()) {
|
||||
$this->info('Keine Level-Aufstiege gefunden.');
|
||||
return;
|
||||
}
|
||||
|
||||
$headers = [
|
||||
'Datum',
|
||||
'User ID',
|
||||
'Name',
|
||||
'E-Mail',
|
||||
'Von Level',
|
||||
'Zu Level',
|
||||
'Aktueller Level',
|
||||
'Margin',
|
||||
'KP Req',
|
||||
'PP Req',
|
||||
'Growth Bonus',
|
||||
'User PP',
|
||||
'User KP',
|
||||
'Level Update',
|
||||
'Aktiv'
|
||||
];
|
||||
|
||||
$rows = [];
|
||||
foreach ($promotions->toArray() as $promotion) {
|
||||
$rows[] = [
|
||||
$promotion['date'],
|
||||
$promotion['user_id'],
|
||||
$promotion['first_name'] . ' ' . $promotion['last_name'],
|
||||
$promotion['email'],
|
||||
$promotion['from_level_name'] . ' (ID:' . $promotion['from_level_id'] . ')',
|
||||
$promotion['to_level_name'] . ' (ID:' . $promotion['to_level_id'] . ')',
|
||||
$promotion['current_user_level_name'] . ' (ID:' . ($promotion['current_user_level_id'] ?? 'N/A') . ')',
|
||||
$promotion['to_level_margin'] . '%',
|
||||
number_format($promotion['to_level_qual_kp'], 0, ',', '.'),
|
||||
number_format($promotion['to_level_qual_pp'], 0, ',', '.'),
|
||||
$promotion['to_level_growth_bonus'] . '%',
|
||||
number_format($promotion['total_pp'], 0, ',', '.'),
|
||||
number_format($promotion['sales_volume_points_sum'], 0, ',', '.'),
|
||||
$promotion['level_updated'],
|
||||
$promotion['active_account'],
|
||||
];
|
||||
}
|
||||
|
||||
$this->table($headers, $rows);
|
||||
|
||||
// Zusammenfassung
|
||||
$this->info('');
|
||||
$this->info('=== ZUSAMMENFASSUNG ===');
|
||||
$this->info('Anzahl Level-Aufstiege: ' . $statistics['total_count']);
|
||||
|
||||
$this->info('');
|
||||
$this->info('Aufstiege nach Ziel-Level:');
|
||||
foreach ($statistics['level_stats'] as $level => $count) {
|
||||
$this->info(" - {$level}: {$count}");
|
||||
}
|
||||
|
||||
$this->info('');
|
||||
$this->info('Aufstiege nach Zeitraum:');
|
||||
foreach ($statistics['period_stats'] as $period => $count) {
|
||||
$this->info(" - {$period}: {$count}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ class BusinessStore extends Command
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create Business Structur and UserDetails';
|
||||
protected $description = 'Create Business Structure and UserDetails with optimized performance';
|
||||
|
||||
private $timeStart;
|
||||
private $month;
|
||||
|
|
@ -52,121 +52,140 @@ class BusinessStore extends Command
|
|||
*/
|
||||
public function handle()
|
||||
{
|
||||
try {
|
||||
$executeDay = (int) Setting::getContentBySlug('day-exectute-business-structur');
|
||||
$presentDay = (int) date('d');
|
||||
|
||||
$this->info('RUN Command BusinessStore on Day: ' . $executeDay);
|
||||
$this->info('RUN Command BusinessStore present Day: ' . $presentDay);
|
||||
\Log::channel('cron')->info('RUN Command BusinessStore on Day: ' . $executeDay);
|
||||
\Log::channel('cron')->info('RUN Command BusinessStore present Day: ' . $presentDay);
|
||||
$this->logMemoryUsage('Command Start');
|
||||
|
||||
if ($executeDay !== $presentDay) {
|
||||
$this->info('NOT RUN Command BusinessStore is not present Day: ' . $presentDay);
|
||||
\Log::channel('cron')->info('NOT RUN Command BusinessStore is not present Day: ' . $presentDay);
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->timeStart = microtime(true);
|
||||
|
||||
// Argumente mit Standardwerten für den Vormonat
|
||||
$this->month = $this->argument('month') ?: (int) date("m", strtotime("-1 month"));
|
||||
$this->year = $this->argument('year') ?: (int) date("Y", strtotime("-1 month"));
|
||||
|
||||
$this->info('RUN Command BusinessStore on month: ' . $this->month . ' | year: ' . $this->year);
|
||||
\Log::channel('cron')->info('RUN Command BusinessStore on month: ' . $this->month . ' | year: ' . $this->year);
|
||||
$this->logMemoryUsage('Parameters initialized');
|
||||
|
||||
// Prozesse ausführen mit Fehlerbehandlung
|
||||
$this->executeWithErrorHandling('Business Structure Storage', function () {
|
||||
$this->storeBusinessStructureUsersDetailMonth();
|
||||
});
|
||||
|
||||
$this->executeWithErrorHandling('Commission Calculation', function () {
|
||||
$this->userBusinessCommissionsToCredit();
|
||||
});
|
||||
|
||||
// Auskommentierte Prozesse bleiben inaktiv
|
||||
// $this->userCreatePaymentCreditsPDF();
|
||||
// $this->userLevelUpdate();
|
||||
// $this->storeBusinessStructureUsersDetailPeriod(1, 6);
|
||||
|
||||
$this->logExecutionTime('COMMAND COMPLETED SUCCESSFULLY');
|
||||
$this->logMemoryUsage('Command End');
|
||||
\Log::channel('cron')->info('COMMAND COMPLETED SUCCESSFULLY');
|
||||
|
||||
$executeDay = (int) Setting::getContentBySlug('day-exectute-business-structur');
|
||||
$presentDay = (int) date('d');
|
||||
|
||||
$this->info('RUN Command BusinessStore on Day: '. $executeDay);
|
||||
$this->info('RUN Command BusinessStore present Day: '. $presentDay);
|
||||
|
||||
if($executeDay !== $presentDay){
|
||||
$this->info('NOT RUN Command BusinessStore is not present Day: '. $presentDay);
|
||||
return 0;
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Command failed with error: ' . $e->getMessage());
|
||||
$this->error('Stack trace: ' . $e->getTraceAsString());
|
||||
$this->logExecutionTime('COMMAND FAILED');
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->timeStart = microtime(true);
|
||||
|
||||
// Argumente mit Standardwerten für den Vormonat
|
||||
$this->month = $this->argument('month') ?: (int) date("m", strtotime("-1 month"));
|
||||
$this->year = $this->argument('year') ?: (int) date("Y", strtotime("-1 month"));
|
||||
|
||||
$this->info('RUN Command BusinessStore on month: '.$this->month.' | year: '.$this->year);
|
||||
|
||||
// Prozesse ausführen
|
||||
$this->storeBusinessStructureUsersDetailMonth();
|
||||
$this->userBusinessCommissionsToCredit();
|
||||
|
||||
// Auskommentierte Prozesse
|
||||
// $this->userCreatePaymentCreditsPDF();
|
||||
// $this->userLevelUpdate();
|
||||
// $this->storeBusinessStructureUsersDetailPeriod(1, 6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function storeBusinessStructureUsersDetailMonth(){
|
||||
private function storeBusinessStructureUsersDetailMonth()
|
||||
{
|
||||
|
||||
$this->info('storeBusinessStructureUsersDetailMonth month: '.$this->month.' year:'.$this->year);
|
||||
$businessUsersStore = new BusinessUsersStore($this->month, $this->year);
|
||||
$businessUsersStore->storeUserBusinessStructure();
|
||||
$businessUsersStore->storeBusinessUsersDetail();
|
||||
$bool = $businessUsersStore->storeBusinessCompleted();
|
||||
|
||||
$this->logExecutionTime('END Command storeBusinessStructureUsersDetailMonth: '.$bool);
|
||||
$this->info('storeBusinessStructureUsersDetailMonth month: ' . $this->month . ' year:' . $this->year);
|
||||
$businessUsersStore = new BusinessUsersStore($this->month, $this->year);
|
||||
$businessUsersStore->storeUserBusinessStructure();
|
||||
$businessUsersStore->storeBusinessUsersDetail();
|
||||
$bool = $businessUsersStore->storeBusinessCompleted();
|
||||
|
||||
$this->logExecutionTime('END Command storeBusinessStructureUsersDetailMonth: ' . $bool);
|
||||
}
|
||||
|
||||
private function userBusinessCommissionsToCredit(){
|
||||
private function userBusinessCommissionsToCredit()
|
||||
{
|
||||
|
||||
$this->info('userBusinessCommissionsToCredit month: '.$this->month.' year:'.$this->year);
|
||||
$this->info('userBusinessCommissionsToCredit month: ' . $this->month . ' year:' . $this->year);
|
||||
$userPaymentCredits = new UserPaymentCredits($this->month, $this->year);
|
||||
$userBusinesses = $userPaymentCredits->getUserBusinessByMonthYear();
|
||||
|
||||
foreach($userBusinesses as $userBusiness){
|
||||
foreach ($userBusinesses as $userBusiness) {
|
||||
$ret = $userPaymentCredits->addUserCreditItem($userBusiness);
|
||||
$this->info('userBusinessCredit: '.$ret->user_id.' : Team: '.$ret->commission_pp_total.' | Shop: '.$ret->commission_shop_sales);
|
||||
$this->info('userBusinessCredit: ' . $ret->user_id . ' : Team: ' . $ret->commission_pp_total . ' | Shop: ' . $ret->commission_shop_sales);
|
||||
}
|
||||
$this->logExecutionTime('END Command userBusinessCommissionsToCredit:');
|
||||
|
||||
}
|
||||
|
||||
private function userCreatePaymentCreditsPDF(){
|
||||
private function userCreatePaymentCreditsPDF()
|
||||
{
|
||||
|
||||
$this->info('userCreatePaymentCreditsPDF month: '.$this->month.' year:'.$this->year);
|
||||
$this->info('userCreatePaymentCreditsPDF month: ' . $this->month . ' year:' . $this->year);
|
||||
$userPaymentCredits = new UserPaymentCredits($this->month, $this->year);
|
||||
$creditItemUsers = $userPaymentCredits->getUserCreditItemUsersByMonthYear();
|
||||
|
||||
foreach($creditItemUsers as $creditItemUser){
|
||||
foreach ($creditItemUsers as $creditItemUser) {
|
||||
$bool = $userPaymentCredits->makeCreditPaymentPDF($creditItemUser->user_id, $this->sendCreditMail);
|
||||
$this->info('creditsPDF: '.$bool.' user_id: '.$creditItemUser->user_id);
|
||||
$this->info('creditsPDF: ' . $bool . ' user_id: ' . $creditItemUser->user_id);
|
||||
}
|
||||
|
||||
$this->logExecutionTime('END Command userCreatePaymentCreditsPDF:');
|
||||
|
||||
$this->logExecutionTime('END Command userCreatePaymentCreditsPDF:');
|
||||
}
|
||||
|
||||
private function userLevelUpdate(){
|
||||
private function userLevelUpdate()
|
||||
{
|
||||
|
||||
$this->info('userLevelUpdate month: '.$this->month.' year:'.$this->year);
|
||||
$this->info('userLevelUpdate month: ' . $this->month . ' year:' . $this->year);
|
||||
|
||||
$userLevelUpdate = new UserLevelUpdate($this->month, $this->year);
|
||||
$levelUpdateUsers = $userLevelUpdate->getUserBusinessByMonthYear();
|
||||
|
||||
foreach($levelUpdateUsers as $userBusiness){
|
||||
|
||||
foreach ($levelUpdateUsers as $userBusiness) {
|
||||
$ret = $userLevelUpdate->makeUserLevelUpdate($userBusiness, $this->sendUpdateMail);
|
||||
if($ret){
|
||||
$this->info('updateLevel: '.$userBusiness->user->id.' | '.$userBusiness->user->email.' | '.
|
||||
'from: '.$userBusiness->m_level_id.' '.$userBusiness->user_level_name.' | '.
|
||||
'to: '.$ret);
|
||||
if ($ret) {
|
||||
$this->info('updateLevel: ' . $userBusiness->user->id . ' | ' . $userBusiness->user->email . ' | ' .
|
||||
'from: ' . $userBusiness->m_level_id . ' ' . $userBusiness->user_level_name . ' | ' .
|
||||
'to: ' . $ret);
|
||||
}
|
||||
|
||||
}
|
||||
$this->logExecutionTime('END Command userLevelUpdate:');
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function storeBusinessStructureUsersDetailPeriod($from, $to)
|
||||
private function storeBusinessStructureUsersDetailPeriod($from, $to)
|
||||
{
|
||||
for($i = $from; $i <= $to; $i++){
|
||||
$this->info('Store Business Structure Users Detail month: '.$i.' year:'.$this->year);
|
||||
for ($i = $from; $i <= $to; $i++) {
|
||||
$this->info('Store Business Structure Users Detail month: ' . $i . ' year:' . $this->year);
|
||||
$businessUsersStore = new BusinessUsersStore($i, $this->year);
|
||||
$businessUsersStore->storeUserBusinessStructure();
|
||||
$businessUsersStore->storeBusinessUsersDetail();
|
||||
$bool = $businessUsersStore->storeBusinessCompleted();
|
||||
|
||||
$this->logExecutionTime('Period BusinessStore: '.$bool);
|
||||
$this->logExecutionTime('Period BusinessStore: ' . $bool);
|
||||
}
|
||||
}
|
||||
|
||||
private function logExecutionTime($message)
|
||||
private function logExecutionTime($message)
|
||||
{
|
||||
$diff = microtime(true) - $this->timeStart;
|
||||
$sec = intval($diff);
|
||||
$micro = $diff - $sec;
|
||||
|
||||
$this->info($message. ' | Time: '.$sec. 'sec :' . round($micro * 1000, 4) . " ms");
|
||||
}
|
||||
|
||||
$this->info($message . ' | Time: ' . $sec . 'sec :' . round($micro * 1000, 4) . " ms");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
368
app/Console/Commands/BusinessStoreOptimized.php
Normal file
368
app/Console/Commands/BusinessStoreOptimized.php
Normal file
|
|
@ -0,0 +1,368 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Setting;
|
||||
use App\Models\UserBusinessStructure;
|
||||
use App\Models\UserBusiness;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Cron\BusinessUsersStoreOptimized;
|
||||
use App\Cron\UserLevelUpdate;
|
||||
use App\Cron\UserPaymentCredits;
|
||||
|
||||
class BusinessStoreOptimized extends Command
|
||||
{
|
||||
/**
|
||||
* ln -sfv /usr/bin/php73 /usr/bin/php
|
||||
* php artisan business:store-optimized month year
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'business:store-optimized {month} {year} {--clear : Clear stored data before processing}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create Business Structure and UserDetails with optimized performance and monitoring';
|
||||
|
||||
private $timeStart;
|
||||
private $month;
|
||||
private $year;
|
||||
|
||||
private $sendCreditMail = false;
|
||||
private $sendUpdateMail = false;
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
try {
|
||||
$executeDay = (int) Setting::getContentBySlug('day-exectute-business-structur');
|
||||
$presentDay = (int) date('d');
|
||||
|
||||
$this->info('RUN Command BusinessStoreOptimized on Day: ' . $executeDay);
|
||||
$this->info('RUN Command BusinessStoreOptimized present Day: ' . $presentDay);
|
||||
\Log::channel('cron')->info('RUN Command BusinessStoreOptimized on Day: ' . $executeDay);
|
||||
\Log::channel('cron')->info('RUN Command BusinessStoreOptimized present Day: ' . $presentDay);
|
||||
$this->logMemoryUsage('Command Start');
|
||||
|
||||
if ($executeDay !== $presentDay) {
|
||||
$this->info('NOT RUN Command BusinessStoreOptimized is not present Day: ' . $presentDay);
|
||||
\Log::channel('cron')->info('NOT RUN Command BusinessStoreOptimized is not present Day: ' . $presentDay);
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->timeStart = microtime(true);
|
||||
|
||||
// Argumente mit Standardwerten für den Vormonat
|
||||
$this->month = $this->argument('month') ?: (int) date("m", strtotime("-1 month"));
|
||||
$this->year = $this->argument('year') ?: (int) date("Y", strtotime("-1 month"));
|
||||
|
||||
$this->info('RUN Command BusinessStoreOptimized on month: ' . $this->month . ' | year: ' . $this->year);
|
||||
$this->logMemoryUsage('Parameters initialized');
|
||||
|
||||
// Prüfe --clear Option und lösche gespeicherte Daten falls gewünscht
|
||||
if ($this->option('clear')) {
|
||||
$this->executeWithErrorHandling('Clear Stored Data', function () {
|
||||
$this->clearStoredData();
|
||||
});
|
||||
}
|
||||
|
||||
// Prozesse ausführen mit optimierter Fehlerbehandlung
|
||||
$this->executeWithErrorHandling('Business Structure Storage', function () {
|
||||
\Log::channel('cron')->info('RUN Command BusinessStoreOptimized Business Structure Storage');
|
||||
$this->storeBusinessStructureUsersDetailMonth();
|
||||
});
|
||||
|
||||
$this->executeWithErrorHandling('Commission Calculation', function () {
|
||||
\Log::channel('cron')->info('RUN Command BusinessStoreOptimized Commission Calculation');
|
||||
$this->userBusinessCommissionsToCredit();
|
||||
});
|
||||
|
||||
// Auskommentierte Prozesse bleiben inaktiv
|
||||
// $this->userCreatePaymentCreditsPDF();
|
||||
// $this->userLevelUpdate();
|
||||
// $this->storeBusinessStructureUsersDetailPeriod(1, 6);
|
||||
|
||||
$this->logExecutionTime('COMMAND COMPLETED SUCCESSFULLY');
|
||||
$this->logMemoryUsage('Command End');
|
||||
\Log::channel('cron')->info('COMMAND COMPLETED SUCCESSFULLY');
|
||||
|
||||
return 0;
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Command failed with error: ' . $e->getMessage());
|
||||
$this->error('Stack trace: ' . $e->getTraceAsString());
|
||||
$this->logExecutionTime('COMMAND FAILED');
|
||||
\Log::channel('cron')->info('COMMAND FAILED');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private function storeBusinessStructureUsersDetailMonth()
|
||||
{
|
||||
$this->info('storeBusinessStructureUsersDetailMonth month: ' . $this->month . ' year:' . $this->year);
|
||||
|
||||
try {
|
||||
$businessUsersStore = new BusinessUsersStoreOptimized($this->month, $this->year);
|
||||
$businessUsersStore->storeUserBusinessStructure();
|
||||
$businessUsersStore->storeBusinessUsersDetail();
|
||||
$bool = $businessUsersStore->storeBusinessCompleted();
|
||||
|
||||
$this->logExecutionTime('END Command storeBusinessStructureUsersDetailMonth: ' . $bool);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Error in storeBusinessStructureUsersDetailMonth: ' . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private function userBusinessCommissionsToCredit()
|
||||
{
|
||||
$this->info('userBusinessCommissionsToCredit month: ' . $this->month . ' year:' . $this->year);
|
||||
|
||||
try {
|
||||
$userPaymentCredits = new UserPaymentCredits($this->month, $this->year);
|
||||
$userBusinesses = $userPaymentCredits->getUserBusinessByMonthYear();
|
||||
|
||||
$processedCount = 0;
|
||||
foreach ($userBusinesses as $userBusiness) {
|
||||
$ret = $userPaymentCredits->addUserCreditItem($userBusiness);
|
||||
$this->info('userBusinessCredit: ' . $ret->user_id . ' : Team: ' . $ret->commission_pp_total . ' | Shop: ' . $ret->commission_shop_sales);
|
||||
$processedCount++;
|
||||
|
||||
// Memory-Check alle 100 User
|
||||
if ($processedCount % 100 === 0) {
|
||||
$this->logMemoryUsage("After processing {$processedCount} users");
|
||||
}
|
||||
}
|
||||
|
||||
$this->info("Processed {$processedCount} user businesses total");
|
||||
$this->logExecutionTime('END Command userBusinessCommissionsToCredit:');
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Error in userBusinessCommissionsToCredit: ' . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private function userCreatePaymentCreditsPDF()
|
||||
{
|
||||
$this->info('userCreatePaymentCreditsPDF month: ' . $this->month . ' year:' . $this->year);
|
||||
|
||||
try {
|
||||
$userPaymentCredits = new UserPaymentCredits($this->month, $this->year);
|
||||
$creditItemUsers = $userPaymentCredits->getUserCreditItemUsersByMonthYear();
|
||||
|
||||
$processedCount = 0;
|
||||
foreach ($creditItemUsers as $creditItemUser) {
|
||||
$bool = $userPaymentCredits->makeCreditPaymentPDF($creditItemUser->user_id, $this->sendCreditMail);
|
||||
$this->info('creditsPDF: ' . $bool . ' user_id: ' . $creditItemUser->user_id);
|
||||
$processedCount++;
|
||||
|
||||
// Memory-Check alle 50 PDFs
|
||||
if ($processedCount % 50 === 0) {
|
||||
$this->logMemoryUsage("After processing {$processedCount} PDFs");
|
||||
}
|
||||
}
|
||||
|
||||
$this->info("Created {$processedCount} PDF files total");
|
||||
$this->logExecutionTime('END Command userCreatePaymentCreditsPDF:');
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Error in userCreatePaymentCreditsPDF: ' . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private function userLevelUpdate()
|
||||
{
|
||||
$this->info('userLevelUpdate month: ' . $this->month . ' year:' . $this->year);
|
||||
|
||||
try {
|
||||
$userLevelUpdate = new UserLevelUpdate($this->month, $this->year);
|
||||
$levelUpdateUsers = $userLevelUpdate->getUserBusinessByMonthYear();
|
||||
|
||||
$updatedCount = 0;
|
||||
foreach ($levelUpdateUsers as $userBusiness) {
|
||||
$ret = $userLevelUpdate->makeUserLevelUpdate($userBusiness, $this->sendUpdateMail);
|
||||
if ($ret) {
|
||||
$this->info('updateLevel: ' . $userBusiness->user->id . ' | ' . $userBusiness->user->email . ' | ' .
|
||||
'from: ' . $userBusiness->m_level_id . ' ' . $userBusiness->user_level_name . ' | ' .
|
||||
'to: ' . $ret);
|
||||
$updatedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
$this->info("Updated {$updatedCount} user levels total");
|
||||
$this->logExecutionTime('END Command userLevelUpdate:');
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Error in userLevelUpdate: ' . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private function storeBusinessStructureUsersDetailPeriod($from, $to)
|
||||
{
|
||||
try {
|
||||
for ($i = $from; $i <= $to; $i++) {
|
||||
$this->info('Store Business Structure Users Detail month: ' . $i . ' year:' . $this->year);
|
||||
$this->logMemoryUsage("Before month {$i}");
|
||||
|
||||
$businessUsersStore = new BusinessUsersStoreOptimized($i, $this->year);
|
||||
$businessUsersStore->storeUserBusinessStructure();
|
||||
$businessUsersStore->storeBusinessUsersDetail();
|
||||
$bool = $businessUsersStore->storeBusinessCompleted();
|
||||
|
||||
$this->logExecutionTime('Period BusinessStore: ' . $bool);
|
||||
$this->logMemoryUsage("After month {$i}");
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Error in storeBusinessStructureUsersDetailPeriod: ' . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht gespeicherte Business Structure Daten für den angegebenen Monat/Jahr
|
||||
*/
|
||||
private function clearStoredData()
|
||||
{
|
||||
try {
|
||||
$this->info("Clearing stored business data for month: {$this->month} | year: {$this->year}");
|
||||
|
||||
// Finde bestehende UserBusinessStructure
|
||||
$existingStructure = UserBusinessStructure::where('year', $this->year)
|
||||
->where('month', $this->month)
|
||||
->first();
|
||||
|
||||
if (!$existingStructure) {
|
||||
$this->info('No stored business structure found to clear');
|
||||
return;
|
||||
}
|
||||
|
||||
$structureId = $existingStructure->id;
|
||||
$this->info("Found existing structure with ID: {$structureId}");
|
||||
|
||||
// Lösche zugehörige UserBusiness Einträge
|
||||
$deletedUserBusinesses = UserBusiness::where('b_structure_id', $structureId)->count();
|
||||
if ($deletedUserBusinesses > 0) {
|
||||
UserBusiness::where('b_structure_id', $structureId)->delete();
|
||||
$this->info("Deleted {$deletedUserBusinesses} UserBusiness records");
|
||||
}
|
||||
|
||||
// Lösche die UserBusinessStructure
|
||||
$existingStructure->delete();
|
||||
$this->info("Deleted UserBusinessStructure with ID: {$structureId}");
|
||||
|
||||
// Garbage Collection nach dem Löschen
|
||||
gc_collect_cycles();
|
||||
|
||||
$this->info('Successfully cleared all stored business data');
|
||||
$this->logMemoryUsage('After clearing data');
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Error clearing stored data: ' . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private function logExecutionTime($message)
|
||||
{
|
||||
$diff = microtime(true) - $this->timeStart;
|
||||
$sec = intval($diff);
|
||||
$micro = $diff - $sec;
|
||||
|
||||
$this->info($message . ' | Time: ' . $sec . 'sec :' . round($micro * 1000, 4) . " ms");
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt eine Funktion mit Fehlerbehandlung aus
|
||||
*/
|
||||
private function executeWithErrorHandling(string $processName, callable $callback): void
|
||||
{
|
||||
try {
|
||||
$startTime = microtime(true);
|
||||
$this->info("Starting: {$processName}");
|
||||
$this->logMemoryUsage("Before {$processName}");
|
||||
|
||||
$callback();
|
||||
|
||||
$endTime = microtime(true);
|
||||
$duration = round(($endTime - $startTime) * 1000, 2);
|
||||
$this->info("Completed: {$processName} in {$duration}ms");
|
||||
$this->logMemoryUsage("After {$processName}");
|
||||
} catch (\Exception $e) {
|
||||
$this->error("Error in {$processName}: " . $e->getMessage());
|
||||
$this->error("Stack trace: " . $e->getTraceAsString());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loggt aktuelle Memory-Nutzung
|
||||
*/
|
||||
private function logMemoryUsage(string $checkpoint): void
|
||||
{
|
||||
$currentMemory = memory_get_usage();
|
||||
$peakMemory = memory_get_peak_usage();
|
||||
$memoryLimit = $this->parseMemoryLimit(ini_get('memory_limit'));
|
||||
|
||||
$currentFormatted = $this->formatBytes($currentMemory);
|
||||
$peakFormatted = $this->formatBytes($peakMemory);
|
||||
$limitFormatted = $this->formatBytes($memoryLimit);
|
||||
$usagePercent = round(($currentMemory / $memoryLimit) * 100, 2);
|
||||
|
||||
$this->info("[{$checkpoint}] Memory: {$currentFormatted} / {$limitFormatted} ({$usagePercent}%) | Peak: {$peakFormatted}");
|
||||
|
||||
if ($usagePercent > 80) {
|
||||
$this->warn("High memory usage detected at {$checkpoint}: {$usagePercent}%");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert Memory-Limit String zu Bytes
|
||||
*/
|
||||
private function parseMemoryLimit(string $limit): int
|
||||
{
|
||||
$limit = trim($limit);
|
||||
$last = strtolower($limit[strlen($limit) - 1]);
|
||||
$number = (int) $limit;
|
||||
|
||||
switch ($last) {
|
||||
case 'g':
|
||||
$number *= 1024;
|
||||
case 'm':
|
||||
$number *= 1024;
|
||||
case 'k':
|
||||
$number *= 1024;
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatiert Bytes in lesbare Einheiten
|
||||
*/
|
||||
private function formatBytes(int $bytes, int $precision = 2): string
|
||||
{
|
||||
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
||||
|
||||
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
|
||||
$bytes /= 1024;
|
||||
}
|
||||
|
||||
return round($bytes, $precision) . ' ' . $units[$i];
|
||||
}
|
||||
}
|
||||
182
app/Console/Commands/BusinessTestAccount.php
Normal file
182
app/Console/Commands/BusinessTestAccount.php
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\User;
|
||||
use App\Models\UserBusiness;
|
||||
use App\Services\BusinessPlan\BusinessUserItemOptimized;
|
||||
use App\Cron\UserPaymentCredits;
|
||||
use Illuminate\Console\Command;
|
||||
use stdClass;
|
||||
|
||||
class BusinessTestAccount extends Command
|
||||
{
|
||||
/**
|
||||
* php artisan business:test-account {user_id} {month} {year}
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'business:test-account {user_id} {month} {year} {--commissions : Calculate and show user commissions}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Test account data loading for a specific user in business calculations, with optional commission calculation';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
try {
|
||||
$userId = (int) $this->argument('user_id');
|
||||
$month = (int) $this->argument('month');
|
||||
$year = (int) $this->argument('year');
|
||||
|
||||
$this->info("Testing account data for User ID: {$userId}, Month: {$month}, Year: {$year}");
|
||||
$this->line('');
|
||||
|
||||
// Lade User mit Account
|
||||
$user = User::with('account', 'user_level')->find($userId);
|
||||
|
||||
if (!$user) {
|
||||
$this->error("User {$userId} not found");
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->info("User found: {$user->email}");
|
||||
$this->info("Account ID: " . ($user->account_id ?? 'NULL'));
|
||||
|
||||
if ($user->account) {
|
||||
$this->info("Account loaded: YES");
|
||||
$this->info("Account m_account: " . ($user->account->m_account ?? 'NULL'));
|
||||
$this->info("Account first_name: " . ($user->account->first_name ?? 'NULL'));
|
||||
$this->info("Account last_name: " . ($user->account->last_name ?? 'NULL'));
|
||||
$this->info("Account birthday: " . ($user->account->birthday ?? 'NULL'));
|
||||
$this->info("Account phone: " . ($user->account->getPhoneNumber() ?? 'NULL'));
|
||||
} else {
|
||||
$this->warn("Account loaded: NO");
|
||||
}
|
||||
|
||||
$this->line('');
|
||||
$this->info('Testing BusinessUserItemOptimized...');
|
||||
|
||||
// Erstelle Date Object
|
||||
$date = new stdClass();
|
||||
$date->month = $month;
|
||||
$date->year = $year;
|
||||
$date->start_date = "{$year}-{$month}-01 00:00:00";
|
||||
$date->end_date = date('Y-m-t 23:59:59', strtotime("{$year}-{$month}-01"));
|
||||
|
||||
// Teste BusinessUserItemOptimized
|
||||
$businessUserItem = new BusinessUserItemOptimized($date);
|
||||
$businessUserItem->makeUserFromModel($user, true);
|
||||
|
||||
$bUser = $businessUserItem->getBUser();
|
||||
|
||||
$this->line('');
|
||||
$this->info('Results from BusinessUserItemOptimized:');
|
||||
$this->info("m_account: " . ($bUser->m_account ?? 'NULL'));
|
||||
$this->info("first_name: " . ($bUser->first_name ?? 'NULL'));
|
||||
$this->info("last_name: " . ($bUser->last_name ?? 'NULL'));
|
||||
$this->info("user_birthday: " . ($bUser->user_birthday ?? 'NULL'));
|
||||
$this->info("user_phone: " . ($bUser->user_phone ?? 'NULL'));
|
||||
$this->info("email: " . ($bUser->email ?? 'NULL'));
|
||||
|
||||
$this->line('');
|
||||
$this->info('Sales Volume Fields:');
|
||||
$this->info("sales_volume_KP_points: " . ($bUser->sales_volume_KP_points ?? 'NULL'));
|
||||
$this->info("sales_volume_TP_points: " . ($bUser->sales_volume_TP_points ?? 'NULL'));
|
||||
$this->info("sales_volume_points_shop: " . ($bUser->sales_volume_points_shop ?? 'NULL'));
|
||||
$this->info("sales_volume_points_KP_sum: " . ($bUser->sales_volume_points_KP_sum ?? 'NULL'));
|
||||
$this->info("sales_volume_points_TP_sum: " . ($bUser->sales_volume_points_TP_sum ?? 'NULL'));
|
||||
$this->info("sales_volume_total: " . ($bUser->sales_volume_total ?? 'NULL'));
|
||||
$this->info("sales_volume_total_shop: " . ($bUser->sales_volume_total_shop ?? 'NULL'));
|
||||
$this->info("sales_volume_total_sum: " . ($bUser->sales_volume_total_sum ?? 'NULL'));
|
||||
|
||||
$this->line('');
|
||||
$this->info('Commission Fields:');
|
||||
$this->info("payline_points: " . ($bUser->payline_points ?? 'NULL'));
|
||||
$this->info("commission_pp_total: " . ($bUser->commission_pp_total ?? 'NULL'));
|
||||
$this->info("commission_shop_sales: " . ($bUser->commission_shop_sales ?? 'NULL'));
|
||||
$this->info("commission_growth_total: " . ($bUser->commission_growth_total ?? 'NULL'));
|
||||
|
||||
// Test UserSalesVolume directly
|
||||
$this->line('');
|
||||
$this->info('Testing UserSalesVolume data directly:');
|
||||
$userSalesVolume = $user->getUserSalesVolume($month, $year, 'first');
|
||||
if ($userSalesVolume) {
|
||||
$this->info("UserSalesVolume found: ID {$userSalesVolume->id}");
|
||||
$this->info("month_KP_points: " . ($userSalesVolume->month_KP_points ?? 'NULL'));
|
||||
$this->info("month_TP_points: " . ($userSalesVolume->month_TP_points ?? 'NULL'));
|
||||
$this->info("month_shop_points: " . ($userSalesVolume->month_shop_points ?? 'NULL'));
|
||||
$this->info("month_total_net: " . ($userSalesVolume->month_total_net ?? 'NULL'));
|
||||
$this->info("month_shop_total_net: " . ($userSalesVolume->month_shop_total_net ?? 'NULL'));
|
||||
} else {
|
||||
$this->warn("No UserSalesVolume found for month {$month}/{$year}");
|
||||
|
||||
// Check if any UserSalesVolume exists for this user
|
||||
$anyVolume = \App\Models\UserSalesVolume::where('user_id', $userId)->orderBy('year', 'desc')->orderBy('month', 'desc')->first();
|
||||
if ($anyVolume) {
|
||||
$this->info("Latest UserSalesVolume found: {$anyVolume->month}/{$anyVolume->year}");
|
||||
} else {
|
||||
$this->warn("No UserSalesVolume records found for this user at all");
|
||||
}
|
||||
}
|
||||
|
||||
$this->line('');
|
||||
|
||||
// Prüfe ob UserBusiness bereits gespeichert ist
|
||||
$existingUserBusiness = UserBusiness::where('user_id', $userId)
|
||||
->where('month', $month)
|
||||
->where('year', $year)
|
||||
->first();
|
||||
|
||||
if ($existingUserBusiness) {
|
||||
$this->info('Existing UserBusiness found:');
|
||||
$this->info("m_account: " . ($existingUserBusiness->m_account ?? 'NULL'));
|
||||
$this->info("first_name: " . ($existingUserBusiness->first_name ?? 'NULL'));
|
||||
$this->info("last_name: " . ($existingUserBusiness->last_name ?? 'NULL'));
|
||||
$this->info("user_birthday: " . ($existingUserBusiness->user_birthday ?? 'NULL'));
|
||||
$this->info("user_phone: " . ($existingUserBusiness->user_phone ?? 'NULL'));
|
||||
$this->info("email: " . ($existingUserBusiness->email ?? 'NULL'));
|
||||
} else {
|
||||
$this->info('No existing UserBusiness found for this period');
|
||||
}
|
||||
|
||||
if ($this->option('commissions')) {
|
||||
$this->line('');
|
||||
$this->info('Testing UserBusiness Commissions to Credit...');
|
||||
|
||||
if ($existingUserBusiness) {
|
||||
try {
|
||||
$userPaymentCredits = new UserPaymentCredits($month, $year);
|
||||
$ret = $userPaymentCredits->addUserCreditItem($existingUserBusiness);
|
||||
$this->info('UserBusinessCredit calculated:');
|
||||
$this->info('User ID: ' . $ret->user_id);
|
||||
$this->info('Team Commission: ' . $ret->commission_pp_total);
|
||||
$this->info('Shop Commission: ' . $ret->commission_shop_sales);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Error calculating commissions: ' . $e->getMessage());
|
||||
}
|
||||
} else {
|
||||
$this->warn('No UserBusiness record found, cannot calculate commissions.');
|
||||
}
|
||||
}
|
||||
|
||||
$this->line('');
|
||||
$this->info('✅ Test completed successfully');
|
||||
|
||||
return 0;
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Test failed with error: ' . $e->getMessage());
|
||||
$this->error('Stack trace: ' . $e->getTraceAsString());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -46,22 +46,24 @@ class UserCleanUp extends Command
|
|||
{
|
||||
|
||||
$this->info('RUN Command user:cleanup');
|
||||
\Log::channel('cleanup')->info('COMMAND [user:cleanup] started.');
|
||||
|
||||
$this->timeStart = microtime(true);
|
||||
|
||||
$this->deleteInavtiveUsers();
|
||||
//alle inaktive User werden deaktivert, die childs werden dem nächsten aktiven Berater (parent) zugewiesen.
|
||||
$this->cleanUpInActiveUser();
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
//\Log::info('Cron is running');
|
||||
|
||||
\Log::channel('cleanup')->info('COMMAND [user:cleanup] finished.');
|
||||
//return 0;
|
||||
}
|
||||
|
||||
|
||||
//gibt es gelöschte Berater mit Kunden und childs???
|
||||
|
||||
private function deleteInavtiveUsers(){
|
||||
private function deleteInavtiveUsers()
|
||||
{
|
||||
|
||||
$this->info('START Command deleteInavtiveUsers');
|
||||
$count = 0;
|
||||
|
|
@ -69,20 +71,20 @@ class UserCleanUp extends Command
|
|||
$date = Carbon::now()->modify('-2 month');
|
||||
$delete_users = User::where('admin', 0)->where('payment_account', '<', $date)->get();
|
||||
|
||||
foreach($delete_users as $delete_user){
|
||||
foreach ($delete_users as $delete_user) {
|
||||
/*
|
||||
dump('delete_users ---------- ');
|
||||
dump($delete_user->id);
|
||||
dump($delete_user->email);
|
||||
*/
|
||||
//finde nächsten aktiven Sponsor $delete_user->id kann sponsor oder pre sponsor sein
|
||||
$active_sponsor = UserUtil::findNextActiveSponsor($delete_user->id);
|
||||
if($active_sponsor){
|
||||
$active_sponsor = UserUtil::findNextActiveSponsor($delete_user->id);
|
||||
if ($active_sponsor) {
|
||||
//setze alle Berater vom Sponsor für alle childs
|
||||
UserUtil::setNewSponsorToChilds($delete_user->id, $active_sponsor->id);
|
||||
UserUtil::setNewSponsorToChilds($delete_user->id, $active_sponsor->id);
|
||||
UserUtil::setShoppingUserToNewMember($delete_user->id, $active_sponsor->id);
|
||||
}else{
|
||||
\Log::channel('cleanup')->error('deleteInavtiveUsers find no active_sponsor by delete_user_id:'.$delete_user->id);
|
||||
} else {
|
||||
\Log::channel('cleanup')->error('deleteInavtiveUsers find no active_sponsor by delete_user_id:' . $delete_user->id);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
|
|
@ -99,8 +101,8 @@ class UserCleanUp extends Command
|
|||
'm_first_name' => $delete_user->account ? $delete_user->account->m_first_name : '',
|
||||
'm_last_name' => $delete_user->account ? $delete_user->account->m_last_name : '',
|
||||
];
|
||||
$count ++;
|
||||
\Log::channel('cleanup')->info('deleteUser: '.json_encode($data));
|
||||
$count++;
|
||||
\Log::channel('cleanup')->info('deleteUser: ' . json_encode($data));
|
||||
UserUtil::deleteUser($delete_user);
|
||||
}
|
||||
|
||||
|
|
@ -108,52 +110,52 @@ class UserCleanUp extends Command
|
|||
$sec = intval($diff);
|
||||
$micro = $diff - $sec;
|
||||
|
||||
$this->info('END Command deleteInavtiveUsers: '.$count. ' | Time: '.$sec. 'sec :' . round($micro * 1000, 4) . " ms");
|
||||
|
||||
$this->info('END Command deleteInavtiveUsers: ' . $count . ' | Time: ' . $sec . 'sec :' . round($micro * 1000, 4) . " ms");
|
||||
}
|
||||
|
||||
private function cleanUpInActiveUser(){
|
||||
private function cleanUpInActiveUser()
|
||||
{
|
||||
|
||||
$this->info('START Command cleanUpInActiveUser');
|
||||
$count = 0;
|
||||
|
||||
|
||||
//clean up user where inactive since 2 weeks
|
||||
$date = Carbon::now()->modify('-2 weeks');
|
||||
|
||||
$inactive_users = User::where('active', true)->where('m_sponsor', '!=', null)->where('payment_account', '<', $date)->get();
|
||||
foreach($inactive_users as $inactive_user){
|
||||
foreach ($inactive_users as $inactive_user) {
|
||||
/*
|
||||
dump('inactive_user ---------- ');
|
||||
dump($inactive_user->id);
|
||||
dump($inactive_user->email);
|
||||
*/
|
||||
$active_sponsor = UserUtil::findNextActiveSponsor($inactive_user->m_sponsor);
|
||||
if($active_sponsor){
|
||||
if ($active_sponsor) {
|
||||
UserUtil::setNewSponsorToChilds($inactive_user->id, $active_sponsor->id);
|
||||
}else{
|
||||
\Log::channel('cleanup')->error('cleanUpInActiveUser find no active_sponsor by inactive_user:'.$inactive_user->id);
|
||||
} else {
|
||||
\Log::channel('cleanup')->error('cleanUpInActiveUser find no active_sponsor by inactive_user:' . $inactive_user->id);
|
||||
}
|
||||
/*
|
||||
dump('findNextActiveSponsor');
|
||||
dump($active_sponsor->email);
|
||||
*/
|
||||
$data = [
|
||||
'user_id' => $inactive_user->id,
|
||||
'user_id' => $inactive_user->id,
|
||||
'email' => $inactive_user->email,
|
||||
'm_account' => $inactive_user->account ? $inactive_user->account->m_account : '',
|
||||
'm_first_name' => $inactive_user->account ? $inactive_user->account->m_first_name : '',
|
||||
'm_last_name' => $inactive_user->account ? $inactive_user->account->m_last_name : '',
|
||||
];
|
||||
$count ++;
|
||||
$count++;
|
||||
|
||||
\Log::channel('cleanup')->info('inactive_user: '.json_encode($data));
|
||||
\Log::channel('cleanup')->info('inactive_user: ' . json_encode($data));
|
||||
UserUtil::deactiveUser($inactive_user);
|
||||
}
|
||||
|
||||
$diff = microtime(true) - $this->timeStart;
|
||||
$sec = intval($diff);
|
||||
$micro = $diff - $sec;
|
||||
|
||||
$this->info('END Command cleanUpInActiveUser: '.$count. ' | Time: '.$sec. 'sec :' . round($micro * 1000, 4) . " ms");
|
||||
|
||||
$diff = microtime(true) - $this->timeStart;
|
||||
$sec = intval($diff);
|
||||
$micro = $diff - $sec;
|
||||
|
||||
$this->info('END Command cleanUpInActiveUser: ' . $count . ' | Time: ' . $sec . 'sec :' . round($micro * 1000, 4) . " ms");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,18 +56,18 @@ class UserMakeAboOrder extends Command
|
|||
public function handle()
|
||||
{
|
||||
$this->timeStart = microtime(true);
|
||||
Log::info('UserMakeAboOrder: Befehl gestartet');
|
||||
\Log::channel('cron')->info('UserMakeAboOrder: Befehl gestartet');
|
||||
$this->info('RUN Command user:make_abo_order');
|
||||
|
||||
try {
|
||||
$this->checkAbosToOrder();
|
||||
$executionTime = $this->getExecutionTime();
|
||||
Log::info("UserMakeAboOrder: Befehl erfolgreich abgeschlossen in {$executionTime}");
|
||||
\Log::channel('cron')->info("UserMakeAboOrder: Befehl erfolgreich abgeschlossen in {$executionTime}");
|
||||
$this->info("Befehl erfolgreich abgeschlossen in {$executionTime}");
|
||||
|
||||
|
||||
return 0;
|
||||
} catch (\Exception $e) {
|
||||
Log::error('UserMakeAboOrder: Fehler beim Ausführen des Befehls', [
|
||||
\Log::channel('cron')->error('UserMakeAboOrder: Fehler beim Ausführen des Befehls', [
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
|
|
@ -84,40 +84,40 @@ class UserMakeAboOrder extends Command
|
|||
private function checkAbosToOrder()
|
||||
{
|
||||
$dateNow = Carbon::now()->format('Y-m-d');
|
||||
|
||||
Log::info('UserMakeAboOrder: Suche nach fälligen Abos für Datum', ['date' => $dateNow]);
|
||||
|
||||
|
||||
\Log::channel('abo_order')->info('UserMakeAboOrder: Suche nach fälligen Abos für Datum', ['date' => $dateNow]);
|
||||
|
||||
$userAbos = UserAbo::where('next_date', '=', $dateNow)
|
||||
->where('active', true)
|
||||
->get();
|
||||
|
||||
->where('active', true)
|
||||
->get();
|
||||
|
||||
$count = $userAbos->count();
|
||||
Log::info("UserMakeAboOrder: {$count} fällige Abos gefunden");
|
||||
\Log::channel('abo_order')->info("UserMakeAboOrder: {$count} fällige Abos gefunden");
|
||||
$this->info("Gefundene fällige Abos: {$count}");
|
||||
|
||||
foreach ($userAbos as $userAbo) {
|
||||
Log::info('UserMakeAboOrder: Verarbeite Abo', [
|
||||
'abo_id' => $userAbo->id,
|
||||
\Log::channel('abo_order')->info('UserMakeAboOrder: Verarbeite Abo', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'payone_userid' => $userAbo->payone_userid
|
||||
]);
|
||||
|
||||
|
||||
$this->info("Verarbeite Abo: {$userAbo->id} (PayoneUserid: {$userAbo->payone_userid})");
|
||||
|
||||
|
||||
try {
|
||||
$shoppingOrder = $this->makeOrder($userAbo);
|
||||
|
||||
|
||||
if ($shoppingOrder) {
|
||||
Log::info('UserMakeAboOrder: Bestellung erstellt', [
|
||||
\Log::channel('abo_order')->info('UserMakeAboOrder: Bestellung erstellt', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'order_id' => $shoppingOrder->id
|
||||
]);
|
||||
$this->info("Bestellung erstellt: {$shoppingOrder->id}");
|
||||
} else {
|
||||
Log::warning('UserMakeAboOrder: Keine Bestellung erstellt für Abo', ['abo_id' => $userAbo->id]);
|
||||
\Log::channel('abo_order')->warning('UserMakeAboOrder: Keine Bestellung erstellt für Abo', ['abo_id' => $userAbo->id]);
|
||||
$this->warn("Keine Bestellung erstellt für Abo: {$userAbo->id}");
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('UserMakeAboOrder: Fehler bei der Verarbeitung des Abos', [
|
||||
\Log::channel('abo_order')->error('UserMakeAboOrder: Fehler bei der Verarbeitung des Abos', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
|
|
@ -135,36 +135,36 @@ class UserMakeAboOrder extends Command
|
|||
*/
|
||||
private function makeOrder($userAbo)
|
||||
{
|
||||
Log::info('UserMakeAboOrder: Starte Bestellungserstellung', ['abo_id' => $userAbo->id]);
|
||||
\Log::channel('abo_order')->info('UserMakeAboOrder: Starte Bestellungserstellung', ['abo_id' => $userAbo->id]);
|
||||
$this->info('Starte Bestellungserstellung für Abo: ' . $userAbo->id);
|
||||
|
||||
|
||||
$shoppingOrder = null;
|
||||
$userOrder = new UserMakeOrder($userAbo);
|
||||
|
||||
|
||||
try {
|
||||
if (!$userOrder->createShoppingUser()) {
|
||||
Log::error('UserMakeAboOrder: Konnte Shopping-User nicht erstellen', ['abo_id' => $userAbo->id]);
|
||||
\Log::channel('abo_order')->error('UserMakeAboOrder: Konnte Shopping-User nicht erstellen', ['abo_id' => $userAbo->id]);
|
||||
$this->error("Konnte Shopping-User für Abo {$userAbo->id} nicht erstellen");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
$shoppingOrder = $userOrder->makeShoppingOrder();
|
||||
if (!$shoppingOrder) {
|
||||
Log::error('UserMakeAboOrder: Konnte Bestellung nicht erstellen', ['abo_id' => $userAbo->id]);
|
||||
\Log::channel('abo_order')->error('UserMakeAboOrder: Konnte Bestellung nicht erstellen', ['abo_id' => $userAbo->id]);
|
||||
$this->error("Konnte Bestellung für Abo {$userAbo->id} nicht erstellen");
|
||||
return null;
|
||||
}
|
||||
|
||||
Log::info('UserMakeAboOrder: Bestellung erstellt, starte Zahlungsvorgang', [
|
||||
|
||||
\Log::channel('abo_order')->info('UserMakeAboOrder: Bestellung erstellt, starte Zahlungsvorgang', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'order_id' => $shoppingOrder->id
|
||||
]);
|
||||
|
||||
|
||||
$response = $userOrder->makePayment();
|
||||
$this->info('makePayment response: ' . json_encode($response));
|
||||
|
||||
if (!isset($response['status'])) {
|
||||
Log::error('UserMakeAboOrder: Ungültige Zahlungsantwort', [
|
||||
\Log::channel('abo_order')->error('UserMakeAboOrder: Ungültige Zahlungsantwort', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'order_id' => $shoppingOrder->id,
|
||||
'response' => $response
|
||||
|
|
@ -172,9 +172,9 @@ class UserMakeAboOrder extends Command
|
|||
$this->error("Ungültige Zahlungsantwort für Abo {$userAbo->id}");
|
||||
return $shoppingOrder;
|
||||
}
|
||||
|
||||
|
||||
if ($response['status'] === 'APPROVED') {
|
||||
Log::info('UserMakeAboOrder: Zahlung erfolgreich', [
|
||||
\Log::channel('abo_order')->info('UserMakeAboOrder: Zahlung erfolgreich', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'order_id' => $shoppingOrder->id,
|
||||
'response' => $response
|
||||
|
|
@ -182,22 +182,22 @@ class UserMakeAboOrder extends Command
|
|||
$this->info("Zahlung erfolgreich für Abo {$userAbo->id}");
|
||||
$this->updateAbo($userAbo, $shoppingOrder, 1);
|
||||
} elseif ($response['status'] === 'ERROR') {
|
||||
Log::error('UserMakeAboOrder: Zahlungsfehler', [
|
||||
\Log::channel('abo_order')->error('UserMakeAboOrder: Zahlungsfehler', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'order_id' => $shoppingOrder->id,
|
||||
'error' => $response
|
||||
]);
|
||||
$this->error("Zahlungsfehler für Abo {$userAbo->id}");
|
||||
|
||||
|
||||
MyLog::writeLog(
|
||||
'userabo',
|
||||
'error',
|
||||
'Error:3002 App\Console\Commands\UserMakeAboOrder::makeOrder / makePayment Error response',
|
||||
'userabo',
|
||||
'error',
|
||||
'Error:3002 App\Console\Commands\UserMakeAboOrder::makeOrder / makePayment Error response',
|
||||
$response
|
||||
);
|
||||
|
||||
|
||||
$this->updateAbo($userAbo, $shoppingOrder, 3);
|
||||
|
||||
|
||||
$shoppingPayment = $userOrder->getShoppingPayment();
|
||||
$data = [
|
||||
'mode' => $shoppingPayment->mode,
|
||||
|
|
@ -205,10 +205,10 @@ class UserMakeAboOrder extends Command
|
|||
'send_link' => false,
|
||||
'payment_error' => $response,
|
||||
];
|
||||
|
||||
|
||||
Payment::paymentStatusSendMail($shoppingOrder, $shoppingPayment, $data);
|
||||
} else {
|
||||
Log::warning('UserMakeAboOrder: Unbekannter Zahlungsstatus', [
|
||||
\Log::channel('abo_order')->warning('UserMakeAboOrder: Unbekannter Zahlungsstatus', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'order_id' => $shoppingOrder->id,
|
||||
'status' => $response['status']
|
||||
|
|
@ -216,14 +216,14 @@ class UserMakeAboOrder extends Command
|
|||
$this->warn("Unbekannter Zahlungsstatus für Abo {$userAbo->id}: {$response['status']}");
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('UserMakeAboOrder: Ausnahme bei der Bestellungserstellung', [
|
||||
\Log::channel('abo_order')->error('UserMakeAboOrder: Ausnahme bei der Bestellungserstellung', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
$this->error("Ausnahme bei Abo {$userAbo->id}: " . $e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
return $shoppingOrder;
|
||||
}
|
||||
|
||||
|
|
@ -237,38 +237,38 @@ class UserMakeAboOrder extends Command
|
|||
*/
|
||||
private function updateAbo($userAbo, $shoppingOrder, $status = 1)
|
||||
{
|
||||
Log::info('UserMakeAboOrder: Aktualisiere Abo', [
|
||||
\Log::channel('abo_order')->info('UserMakeAboOrder: Aktualisiere Abo', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'order_id' => $shoppingOrder->id,
|
||||
'status' => $status
|
||||
]);
|
||||
|
||||
|
||||
$this->info("Aktualisiere Abo: {$userAbo->id} mit Status {$status}");
|
||||
|
||||
|
||||
$updateData = [
|
||||
'next_date' => AboHelper::setNextDate(now(), $userAbo->abo_interval),
|
||||
'last_date' => now(),
|
||||
];
|
||||
|
||||
|
||||
if ($status !== 1) {
|
||||
$updateData['status'] = $status;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
$userAbo->update($updateData);
|
||||
|
||||
|
||||
UserAboOrder::create([
|
||||
'user_abo_id' => $userAbo->id,
|
||||
'shopping_order_id' => $shoppingOrder->id,
|
||||
'status' => $status,
|
||||
]);
|
||||
|
||||
Log::info('UserMakeAboOrder: Abo erfolgreich aktualisiert', [
|
||||
|
||||
\Log::channel('abo_order')->info('UserMakeAboOrder: Abo erfolgreich aktualisiert', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'next_date' => $updateData['next_date']
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('UserMakeAboOrder: Fehler beim Aktualisieren des Abos', [
|
||||
\Log::channel('abo_order')->error('UserMakeAboOrder: Fehler beim Aktualisieren des Abos', [
|
||||
'abo_id' => $userAbo->id,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
|
@ -286,7 +286,7 @@ class UserMakeAboOrder extends Command
|
|||
$diff = microtime(true) - $this->timeStart;
|
||||
$sec = intval($diff);
|
||||
$micro = $diff - $sec;
|
||||
|
||||
|
||||
return $sec . ' Sekunden und ' . round($micro * 1000, 2) . ' ms';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
18
app/Console/Kernel.php
Executable file → Normal file
18
app/Console/Kernel.php
Executable file → Normal file
|
|
@ -31,15 +31,15 @@ class Kernel extends ConsoleKernel
|
|||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// Job 1: Überprüft täglich um 02:00 Uhr die Zahlungskonten.
|
||||
$schedule->command('payments:check-accounts')->dailyAt('02:00');
|
||||
// Job 1: Überprüft täglich um 02:00 Uhr die Zahlungskonten.
|
||||
$schedule->command('payments:check-accounts')->dailyAt('02:00');
|
||||
// Jobs 2, 3, 4: Die Befehle aus deinem alten Shell-Skript.
|
||||
// Werden nacheinander täglich zu unterschiedlichen Zeiten ausgeführt,
|
||||
// um die Serverlast zu verteilen.
|
||||
$schedule->command('store-optimized 0 0')->dailyAt('03:00');
|
||||
|
||||
// Jobs 2, 3, 4: Die Befehle aus deinem alten Shell-Skript.
|
||||
// Werden nacheinander täglich zu unterschiedlichen Zeiten ausgeführt,
|
||||
// um die Serverlast zu verteilen.
|
||||
$schedule->command('business:store 0 0')->dailyAt('03:00');
|
||||
$schedule->command('user:cleanup')->dailyAt('03:30');
|
||||
$schedule->command('user:make_abo_order')->dailyAt('04:00');
|
||||
$schedule->command('user:cleanup')->dailyAt('03:30');
|
||||
$schedule->command('user:make_abo_order')->dailyAt('04:00');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -49,7 +49,7 @@ class Kernel extends ConsoleKernel
|
|||
*/
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
$this->load(__DIR__ . '/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue