leaders = $leaders; $this->vote = $vote; } public function accrualPoints() { DB::beginTransaction(); $procent_site = (int)$this->vote->procent_site; $procent_site = $procent_site / 100; $procent_top = (int)$this->vote->procent_top; $procent_top = $procent_top / 100; $subscriptions = Subscription::with('user.subscribers.subscription')->where('ends_at', '>', Carbon::now()) ->where('status', 'complete')->get(); $sum_site = 0; $sdr_leader_pay = 0; $sdr_users_pay = []; foreach ($subscriptions as $subscription) { $subscribers_simple = collect([]); $user = $subscription->user; $subscribers = $this->activeSubs($user->subscribers); $one_sub_is_leader = $this->oneLeaders($subscribers); if (! $one_sub_is_leader) { $subscribers_simple = $subscribers->filter(function ($subscriber) { return ! in_array($subscriber->id, $this->leaders); }); } $price = $subscription->price; $to_site = $price * $procent_site; $sum_site += $to_site; $sdr = round($price - $to_site); $sdr_leader = round($sdr * $procent_top); $sdr_simple = $sdr - $sdr_leader; if ($one_sub_is_leader) { //выплачиваем весь sdr если чел. подписан на лидеров, и у него больше нет простых $sdr_leader_pay += $sdr; } else { $sdr_leader_pay += $sdr_leader; } if ($subscribers_simple->isNotEmpty()) { //Выплачиваем каждому юзеру $sdr_parts = round($sdr_simple / $subscribers_simple->count()); //сохраняем транзакции простых пользователей foreach ($subscribers_simple as $subs) { $sdr_users_pay[$subs->id][] = $sdr_parts; } } $this->updateSubs($subscription); } $this->payForSimpleUser($sdr_users_pay); $this->payForLeaderUser($sdr_leader_pay); $this->payForSystemUser($sum_site); DB::commit(); } public function payForSystemUser($sum_site) { $system_user_id = User::system()->id; $this->addPoint($system_user_id, $sum_site); } //оплата лидеров public function payForLeaderUser($sdr_leader_pay) { $part_for_leader = round($sdr_leader_pay/count($this->leaders)); foreach ($this->leaders as $leader) { $this->addPoint($leader, $part_for_leader); } } //оплата обычных public function payForSimpleUser($sdr_users_pay) { $sdr_users_pay = array_map(function ($lines) { return array_sum($lines); }, $sdr_users_pay); foreach ($sdr_users_pay as $user_pay_id => $sdr_users) { $this->addPoint($user_pay_id, $sdr_users); } } public 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]); } public function updateSubs($sub) { $sub->status = 'end'; //YSV ENUM! $sub->save(); } // есть в списке только лидеры public function oneLeaders($subscribers) { if ($subscribers->count() <= count($this->leaders)) { $contains = $subscribers->filter(function ($subscriber) { return in_array($subscriber->id, $this->leaders); }); if ($contains->count() === $subscribers->count()) { return true; } } return false; } //проверка на акт. подписки public function activeSubs($subscribers) { return $subscribers->filter(function ($subscriber) { return optional($subscriber->subscription->first())->ends_at > Carbon::now(); }); } }