156 lines
4.8 KiB
PHP
156 lines
4.8 KiB
PHP
<?php
|
||
namespace App\Domain\Votes\Services;
|
||
|
||
use DB;
|
||
use Carbon\Carbon;
|
||
use App\Models\User;
|
||
use App\Domain\Points\Models\Point;
|
||
use App\Domain\Points\Enums\DirectionEnum;
|
||
use App\Domain\Subscriptions\Models\Subscription;
|
||
use App\Domain\Subscriptions\Service\SubscriptionService;
|
||
|
||
class VoteServiceOld
|
||
{
|
||
public $vote;
|
||
public $leaders;
|
||
|
||
public function __construct($vote)
|
||
{
|
||
$leaders = SubscriptionService::leaders();
|
||
$leaders = array_column(array_slice($leaders, 0, 2), 'user_id');
|
||
$this->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();
|
||
});
|
||
}
|
||
}
|