leaders = $leaders; $this->vote = $vote; } public function accrualPoints() { DB::beginTransaction(); $procent_site = (int)nova_get_setting('vote_procent_site'); $procent_site = $procent_site / 100; $procent_top = (int)nova_get_setting('vote_procent_leader'); $procent_top = $procent_top / 100; $procent_local = (int)nova_get_setting('vote_procent_local_leader'); $procent_local = $procent_local / 100; $subscriptions = Subscription::with('user.subscribers.subscription')->where('ends_at', '>', Carbon::now()) ->where('status', 'complete')->get(); $sum_site = 0; $sdr_leader_pay = 0; $sdr_leader_for_all_pay = []; foreach ($subscriptions as $subscription) { $user = $subscription->user; $subscribers = $this->activeSubs($user->subscribers); // Фильтр лидеров $subscribersLeader = $subscribers->filter(function ($subscriber) { return $subscriber->pivot->leader === 1; }); // Фильтр простых пользователей $subscribersSimple = $subscribers->filter(function ($subscriber) { return $subscriber->pivot->leader === 0; }); $price = $subscription->price; $to_site = round($price * $procent_site); $sum_site += $to_site; $sdr = round($price - $to_site); // сумма для распределения $sdr_leader_global = round($sdr * $procent_top); $sdr_leader_local = round($sdr * $procent_local); $sdr_simple = $sdr - $sdr_leader_global - $sdr_leader_local; // добавляем лидерам $sdr_leader_pay += $sdr_leader_global; //если 0 подписок, но куплена подписка на сайт // отдаем лидеру 40%, а 60% сайту if($subscribers->isEmpty()){ $sum_site += ($sdr - $sdr_leader_global); // 20%сайту(вместо локальных) и 40%сайту (вместо простых) }else { if ($subscribersLeader->isNotEmpty()) { //Выплачиваем каждому локальному лидеру $sdr_parts_local = round($sdr_leader_local / $subscribersLeader->count()); //сохраняем транзакции локальных лидеров foreach ($subscribersLeader as $subs) { $sdr_leader_for_all_pay[$subs->id][] = $sdr_parts_local; } }else{ $sum_site += $sdr_leader_local; //если у пользователя есть подписки, но он не выбрал лидеров } if ($subscribersSimple->isNotEmpty()) { //Выплачиваем каждому юзеру $sdr_parts = round($sdr_simple / $subscribersSimple->count()); //сохраняем транзакции простых пользователей foreach ($subscribersSimple as $subs) { $sdr_leader_for_all_pay[$subs->id][] = $sdr_parts; } }else{ $sum_site += $sdr_simple; } } $this->updateSubs($subscription); } $part_for_leader = round($sdr_leader_pay/count($this->leaders)); foreach ($this->leaders as $leader) { $sdr_leader_for_all_pay[$leader][] = $part_for_leader; } $this->payUsers($sdr_leader_for_all_pay); $this->payForSystemUser($sum_site); DB::commit(); } private function payUsers($sdr) { $sdr_users_pay = array_map(function ($lines) { return array_sum($lines); }, $sdr); foreach ($sdr_users_pay as $user_pay_id => $sdr_user) { $this->addPoint($user_pay_id, $sdr_user); } } private function payForSystemUser($sum_site) { $system_user_id = User::system()->id; $this->addPoint($system_user_id, $sum_site); } private function addPoint($user_id, $amount) { $point = new Point; $point->user_id = $user_id; $point->point = $amount; $point->type = 'votes'; //YSV ENUM! $point->direction = DirectionEnum::COMING(); $point->save(); $this->vote->users()->attach($user_id, ['payment' => $amount]); } private function updateSubs($sub) { $sub->status = 'end'; //YSV ENUM! $sub->save(); } //проверка на акт. подписки private function activeSubs($subscribers) { return $subscribers->filter(function ($subscriber) { return optional($subscriber->subscription->first())->ends_at > Carbon::now(); }); } public function freeMode() { $users = SubscriptionService::freeLeaders(); foreach ($users as $leader) { $this->vote->users()->attach($leader->id, ['payment' => $leader->countVote]); } } }