/
home
/
corsairdevelopme
/
public_html
/
amplivo-console
/
app
/
Models
/
Upload File
HOME
<?php namespace App\Models; use Carbon\Carbon; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; class MemberDRY extends Model { use HasFactory; protected $table = 'member_dry'; protected $fillable = [ 'id', 'status', 'sponsor_id', 'personal_sponsor_id', 'tsv', 'wtsv', 'customer', 'level', 'rank', 'pgv', 'qgv', 'sponsor_ids', 'personal_sponsor_ids' ]; const CUSTOMER_CUSTOMER = 1; const STATUS_DELETED = 'deleted'; protected $connection = 'mysql'; use HasFactory; public $allSponsorIds = []; public $depthofsp = 0; public $starRanks = []; public $pageName = "Member"; protected $casts = [ 'sponsor_ids' => 'json', ]; protected $primaryKey = 'member_id'; const memberStatus = [ "active", "abandoned", "suspended", "deleted", "lockout", "external", ]; protected $memberStatus = self::memberStatus; public static function boot() { parent::boot(); self::created(function ($model) { if (empty($model->id)) { $model->id = $model->user_id; } $model->save(); }); } public static function updateStarRankArray() { $starrank = collect(); $rankdata = CustomerLevel::whereNull('template_id')->where('for_what', 'Configuration parameters for Star Ranks')->first(); $rank = json_decode($rankdata->value, true); foreach ($rank as $value) { $temp['rank'] = $value['rank']; $temp['minimumTsv'] = $value['minimum_tsv']; $temp['maximumTsvRatioPerLeg'] = $value['maximum_tsv_ratio_per_leg']; $temp['minimumPsu'] = $value['minimum_psu']; $temp['minimumPsuCustomerLevel'] = $value['minimum_psu_customer_level']; $temp['minimumPsuLevel'] = $value['minimum_psu_level']; $temp['minimumSu'] = $value['minimum_su']; $temp['minimumSuRank'] = $value['minimum_su_rank']; $temp['maximumSuPerLeg'] = $value['maximum_su_per_leg']; $temp['maximumUsedMatchingBonusLevel'] = $value['maximum_used_matching_bonus_level']; $temp['teamsiteLicenseNeeded'] = true; $temp['reward'] = [Wallet::TYPE_COMPULSORY => [WalletLog::STAR_RANK => $value['reward']]]; $starrank[] = $temp; } $starrank = $starrank->sortBy('rank'); $starrank->values()->all(); return $starrank->toArray(); } public static function getCsrAddress($userId) { $address = UserCsrAddress::where('user_id', $userId)->orderBy('id', 'desc')->limit(1)->get(); return $address ? $address[0]['address'] : null; } public function levelDetail() { return $this->belongsTo(Level::class, 'level', 'level_no')->whereNull('template_id'); } public function personalSponsor() { return $this->belongsTo(self::class, 'personal_sponsor_id', 'user_id'); } public function user() { return $this->belongsTo(User::class, 'user_id')->with('details'); } public function UserQualificationLog() { return $this->hasMany(UserQualificationLog::class, 'user_id', 'id'); } public function UserTeamsiteLicenses() { return $this->hasMany(UserTeamsiteLicense::class, 'user_id', 'id'); } public function userTeamsiteLicensesHas() { return $this->hasOne(UserTeamsiteLicense::class, 'user_id', 'id')->where( 'start', '<=', Carbon::now() ) ->where( 'end', '>=', Carbon::now() ); } public function sponsor() { return $this->belongsTo(self::class, 'sponsor_id', 'user_id'); } public function allSponsorUplineIds() { $sponsorIds = [$this->attributes['sponsor_id']]; $sponsor = $this->sponsor; if ($sponsor) { $getAllSponsorIdsDB_Array = $sponsor->getAllSponsorIdsDB(); if (!is_array($getAllSponsorIdsDB_Array)) { $getAllSponsorIdsDB_Array = [(int)$getAllSponsorIdsDB_Array]; } $sponsorIds = array_merge($sponsorIds, $getAllSponsorIdsDB_Array); } return $sponsorIds; } public function getDepth() { $sponsorIds = json_decode($this->attributes['sponsor_ids']) ?? []; if (count($sponsorIds) <= 0) { $this->refreshAllSponsorIds(); $sponsorIds = $this->getAllSponsorIdsDB(); } return count($sponsorIds); } public function refreshAllSponsorIds() { $this->reloadAllSponsorIds(); $this->save(); } public function reloadAllSponsorIds() { $sponsorIds = [$this->attributes['sponsor_id']]; $sponsor = $this->sponsor; if ($sponsor) { $sponsorIds = array_merge($sponsorIds, $this->sponsor->getAllSponsorIds($this->attributes['sponsor_id'])); } $this->allSponsorIds = array_values(array_unique((array_merge($this->allSponsorIds, $sponsorIds)))); $this->attributes['sponsor_ids'] = json_encode($this->allSponsorIds); } public function getAllSponsorIds($sid) { $sponsor = MemberDRY::where('id', $sid)->first(); if ($sponsor) { $this->allSponsorIds[] = $sponsor->id; if ($sponsor->sponsor_id) { $this->getAllSponsorIds($sponsor->sponsor_id); } } return $this->allSponsorIds; } public function getAllSponsorIdsDB() { $sponsorIds = json_decode($this->attributes['sponsor_ids']); if (!$sponsorIds) { $this->refreshAllSponsorIds(); $sponsorIds = $this->getAllSponsorIdsDB(); } // $sponsorIds = array_unique($sponsorIds); return array_filter($sponsorIds); } public function getPersonalSponsorIdsAttribute() { return json_decode($this->attributes['personal_sponsor_ids']) ?? []; } public function getDymanicCompressedPersonalSponsorUpline($calculationDay, $skipStatuses, $minSponsorLevel, $minStarRank, $bv = 0) { $sponsors = $this->getAllPersonalSponsorUplines(); foreach ($sponsors as $sponsor) { if (in_array($sponsor->status, $skipStatuses)) { continue; } elseif ($sponsor->level < $minSponsorLevel) { continue; } elseif ($sponsor->rank < $minStarRank) { continue; } elseif (!$this->isEligibleForCommission($sponsor, $calculationDay[0], $calculationDay[1])) { continue; } return $sponsor; } } public function getAllPersonalSponsorUplines($status = null) { $sponsorIds = $this->allPersonalSponsorUplineIds(); $sponsors = MemberDRY::whereIn('id', $sponsorIds); if ($status) { $sponsors->where('status', $status); } $sponsors = $sponsors->pluck('id')->toArray(); $result = []; foreach ($sponsorIds as $sponsorId) { if (in_array($sponsorId, $sponsors)) { $result[] = MemberDRY::where('id', $sponsorId)->first(); } } return $result; } public function allPersonalSponsorUplineIds() { $sponsorIds = [$this->attributes['personal_sponsor_id']]; $psu = $this->personalSponsor; if ($psu) { $getAllSponsorIdsDB_Array = $psu->getAllSponsorIdsDB(); if (!is_array($getAllSponsorIdsDB_Array)) { $getAllSponsorIdsDB_Array = [(int)$getAllSponsorIdsDB_Array]; } $sponsorIds = array_merge($sponsorIds, $getAllSponsorIdsDB_Array); } return $sponsorIds; } public function isEligibleForCommission($sponsor, $start, $end) { return UserTeamsiteLicense::where([['user_id', $sponsor->id], ['start', '<', $start], ['end', '>', $end]])->exists(); } public function getDymanicCompressedSponsor($calculationDay, $skipStatuses, $minSponsorLevel, $minStarRank, $bv = 0, $avoidCache = false) { $sponsors = $this->getAllSponsors(null, $calculationDay[0], $calculationDay[1], $avoidCache); foreach ($sponsors as $sponsor) { if (in_array($sponsor->status, $skipStatuses)) { continue; } elseif ($sponsor->level < $minSponsorLevel) { continue; } elseif ($sponsor->rank < $minStarRank) { continue; } elseif (count($sponsor->UserTeamsiteLicenses) == 0) { Log::info(sprintf('Skipped %s, date issue', $sponsor->username)); continue; } return $sponsor; } } public function getAllSponsors($status = null, $date1, $date2, $avoidCache = false) { if ($avoidCache == false) { if (Cache::has($this->attributes['id'] . "sps")) { return Cache::get($this->attributes['id'] . "sps"); } } $sponsorIds = $this->getAllSponsorIdsDB(); $sponsors = MemberDRY::with(['UserTeamsiteLicenses' => function ($q) use ($date1, $date2) { $q->where([['start', '<', $date1], ['end', '>', $date2]]); }])->whereIn('id', $sponsorIds); if ($status) { $sponsors->where('status', $status); } $sponsors = $sponsors->get()->keyBy('id'); $result = []; foreach ($sponsorIds as $sponsorId) { if (isset($sponsors[$sponsorId])) { $result[] = $sponsors[$sponsorId]; } } if ($avoidCache == false) { Cache::put($this->attributes['id'] . "sps", $result, now()->addMinutes(240)); } return $result; } public function getAllSponsorsWithoutLincenses($status = null) { if (Cache::has($this->attributes['id'] . "sps-wtd")) { return Cache::get($this->attributes['id'] . "sps-wtd"); } else { $sponsorIds = $this->getAllSponsorIdsDB(); $sponsors = MemberDRY::whereIn('id', $sponsorIds); if ($status) { $sponsors->where('status', $status); } $sponsors = $sponsors->get()->pluck('id')->toArray(); $result = []; foreach ($sponsorIds as $sponsorId) { if (in_array($sponsorId, $sponsors)) { $result[] = MemberDRY::where('id', $sponsorId)->first(); } } Cache::put($this->attributes['id'] . "sps-wtd", $result, now()->addMinutes(240)); return $result; } } public function refreshStarRank($starRanks) { $this->starRanks = $starRanks; $oldRank = $this->attributes['rank']; $newRank = $this->calculateStarRankForUser($this->attributes['id']); if ($newRank > $oldRank) { $this->rank = $newRank; $this->save(); $log = "Start rank updated from $oldRank to $newRank"; saveLog($log, $this, $this, 'Star Rank', User::find($this->user_id)); } if ($newRank > 0) { $log = UserQualificationLog::where([ ['user_id', $this->id], ['type', 'rank'], ['value', $newRank], ['source', UserQualificationLog::SOURCE_PERFORMANCE], ])->first(); if (!$log) { $this->createUserQualificationLog('rank', $newRank, $oldRank, UserQualificationLog::SOURCE_PERFORMANCE); } } for ($rank = 1; $rank <= $this->attributes['rank']; ++$rank) { $this->addStarRankReward($rank, Carbon::now()->toDateString()); } } public function calculateStarRankForUser($id) { $newRank = 0; $rankResults = $this->getStarRankResultsForUser($id); foreach ($rankResults as $rank => $rankResult) { if ($rankResult['tsvDone'] && $rankResult['psuDone'] && $rankResult['suDone']) { $newRank = $rank; } } return $newRank; } public function getStarRankResultsForUser($id) { $user = MemberDRY::where('id', $id)->first(); $results = []; // Load the active license if exists $hasTeamsiteLicense = $user->userTeamsiteLicensesHas ? true : false; $psus = MemberDRY::select('level', 'customer', DB::raw('count(*) as cnt')) ->where( 'personal_sponsor_id', $user->id ) ->groupBy('level', 'customer') ->get() ->toArray(); $level1Sus = MemberDRY::select('id', 'tsv') ->where( 'sponsor_id', $user->id ) ->get() ->toArray(); $extra = UserExtra::where([ ['user_id', $user->id], ['type', UserExtra::TYPE_ADDITIONAL_TSV], ])->first(); $extraTsv = $extra ? (int) $extra->value : 0; $specialBvs = []; // Determine the number of all personally sponsored users grouped by their sponsor and customer level. $specialPsus = MemberDRY::where( 'personal_sponsor_id', $user->id ) ->whereColumn('personal_sponsor_id', '!=', 'sponsor_id') ->get() ->pluck('id') ->toArray(); if (!empty($specialPsus)) { $specialBvs = BV::select('user_id', DB::raw('SUM(value) value')) ->where('origin', BV::ORIGIN_PERSONAL_SPONSOR) ->whereIn('user_id', $specialPsus) ->groupBy('user_id') ->get() ->toArray(); } foreach ($this->starRanks as $index => $requirements) { $rank = $requirements['rank']; $results[$rank]['hasTeamsiteLicense'] = $hasTeamsiteLicense; foreach ($psus as $psu) { if ($psu['level'] >= $requirements['minimumPsuLevel'] || $psu['customer'] >= $requirements['minimumPsuCustomerLevel']) { if (!isset($results[$rank]['psu'])) { $results[$rank]['psu'] = 0; } $results[$rank]['psu'] += $psu['cnt']; } } $maxTsvPerLeg = $requirements['maximumTsvRatioPerLeg'] * $requirements['minimumTsv']; $tsv = MemberDRY::select(DB::raw(sprintf('SUM(IF(tsv > %f, %f, tsv)) as stsv', $maxTsvPerLeg, $maxTsvPerLeg))) ->where( 'sponsor_id', $user->id ) ->first(); $results[$rank]['tsv'] = $tsv ? $tsv->stsv : 0; foreach ($specialBvs as $specialBv) { if (!isset($results[$rank]['tsv'])) { $results[$rank]['tsv'] = 0; } $results[$rank]['tsv'] += min($specialBv['value'], $maxTsvPerLeg); } $results[$rank]['tsv'] += min($extraTsv, $maxTsvPerLeg); } $level1SuStarRanks = []; // Populate container for holding sponsored user numbers by Star Rank for legs. foreach ($level1Sus as $su) { $level1SuStarRanks[$su['id']] = [ 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0, 7 => 0, ]; } $rankedUsers = MemberDRY::where( 'rank', '>', 0 )->get(); $level1SuIds = array_column($level1Sus, 'id'); $temp = []; // Iterate over users with Star Rank to determine which of them belongs to any legs. foreach ($rankedUsers as $rankedUser) { $sponsors = $rankedUser->getAllSponsorIdsDB(); $sponsors[] = $rankedUser->id; $validSponsors = $this->intersectFast($sponsors, $level1SuIds); $temp[] = [ $rankedUser->id => $validSponsors, ]; // Intersect the sponsors with the legs. foreach ($validSponsors as $id) { if (isset($level1SuStarRanks[$id])) { try { ++$level1SuStarRanks[$id][$rankedUser->rank]; //code... } catch (\Throwable $th) { //throw $th; } } } } foreach ($this->starRanks as $index => $requirements) { $innerRank = $requirements['rank']; if ($requirements['minimumSu'] > 0) { foreach ($level1SuStarRanks as $suRanks) { $total = 0; foreach ($suRanks as $suRank => $cnt) { if ($suRank >= $requirements['minimumSuRank']) { $total += $cnt; } } if (!isset($results[$innerRank]['su'])) { $results[$innerRank]['su'] = 0; } $results[$innerRank]['su'] += min($requirements['maximumSuPerLeg'], $total); } } $results[$innerRank]['tsv'] = isset($results[$innerRank]['tsv']) ? $results[$innerRank]['tsv'] : 0; $results[$innerRank]['psu'] = isset($results[$innerRank]['psu']) ? $results[$innerRank]['psu'] : 0; $results[$innerRank]['su'] = isset($results[$innerRank]['su']) ? $results[$innerRank]['su'] : 0; $results[$innerRank]['tsvDone'] = $results[$innerRank]['tsv'] >= $requirements['minimumTsv']; $results[$innerRank]['psuDone'] = $results[$innerRank]['psu'] >= $requirements['minimumPsu']; $results[$innerRank]['suDone'] = $results[$innerRank]['su'] >= $requirements['minimumSu']; $results[$innerRank]['teamsiteLicenseDone'] = !$requirements['teamsiteLicenseNeeded'] || $hasTeamsiteLicense; } return $results; } public static function intersectFast($array1, $array2) { $index = array_flip($array1); $second = array_flip($array2); $x = array_intersect_key($index, $second); return array_flip($x); } private function createUserQualificationLog($attribute, $newValue, $oldValue, $source = null) { if (is_null($source)) { $source = UserQualificationLog::SOURCE_PERFORMANCE; } $log = UserQualificationLog::create([ 'user_id' => $this->id, 'type' => $attribute, 'value' => $newValue, 'value_before' => $oldValue, 'source' => $source, ]); if ($source == UserQualificationLog::SOURCE_ADMIN && $attribute == 'level' && $oldValue == 0 && $newValue > 0) { // Ha 0-ról nőtt a level admin által, akkor adni kell Business License-t, ha nem volt még $licenseExpiration = $this->getBusinessLicenseExpiration(); // Ha lejárt a meglévő Business License, akkor adjunk újat (töröljük a lejárati dátumot) if (!is_null($licenseExpiration) && strtotime($licenseExpiration) < time()) { $licenseExpiration = null; } if (is_null($licenseExpiration)) { UserTeamsiteLicense::create([ 'user_id' => $this->id, 'type' => UserTeamsiteLicense::TYPE_12_MONTHS, 'start' => date('Y-m-d H:i:s'), 'end' => date('Y-m-d H:i:s', strtotime('+ 12 months')), ]); } } return $log; } public function getBusinessLicenseExpiration() { $licenses = $this->userTeamsiteLicenses; $expire = null; foreach ($licenses as $license) { if (is_null($expire) || strtotime($license->end) > strtotime($expire)) { $expire = $license->end; } } return $expire; } public function addStarRankReward($rank, $createdAt = null) { $key = array_search($rank, array_column($this->starRanks, 'rank')); $reward = $this->starRanks[$key]['reward']; foreach ($reward as $action => $walletData) { foreach ($walletData as $walletType => $value) { Wallet::firstOrCreate([['type', $walletType], ['user_id', $this->attributes['id']]]); distributeBonus($this, $value, [ $walletType => [$action, 1], ], [ 'unique_id' => $rank, 'created_at' => $createdAt, ]); } } } public function distributeBonus($bonus, $wallets) { // For every wallet a new wallet_log entry is created. foreach ($wallets as $type => $parameters) { $action = $parameters[0]; $multiplier = $parameters[1]; $value = $bonus * $multiplier; $wid = Wallet::firstOrCreate([['type', $type], ['user_id', $this->attributes['id']]]); WalletLog::create([ 'wallet_id' => $wid->id, 'value' => $value, 'action' => $action, ]); } } // public function email() // { // return $this->belongsTo(User::class, 'email'); // } }