<?php
namespace App\Subscriber\Balance\Webmaster;
use App\Dictionary\BalanceType;
use App\Dictionary\VAT;
use App\Event\Balance\BalanceWebmasterProvisionCreatedEvent;
use App\Event\User\MemberCreatedEvent;
use App\Lib\Payment\PayMethod\AdminBonusMethod;
use App\Lib\System\Job\DelineSunctionPaymentTrackingJob;
use App\Service\Property\WebmasterPropertyService;
use App\Service\System\JobService;
use App\Service\User\WebmasterService;
use App\Service\Webmaster\BalanceWebmasterService;
use App\Service\Webmaster\WebmasterProvisionSignupCampaignService;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProvisionTrackingSubscriber implements EventSubscriberInterface
{
protected BalanceWebmasterService $balanceWebmasterService;
protected JobService $jobService;
protected WebmasterPropertyService $webmasterPropertyService;
protected WebmasterProvisionSignupCampaignService $service;
/**
* @var array|int[]
*/
protected array $advertiserIds = [];
/**
* ProvisionTrackingSubscriber constructor.
*/
public function __construct(JobService $jobService, BalanceWebmasterService $balanceWebmasterService,
WebmasterPropertyService $webmasterPropertyService,
WebmasterProvisionSignupCampaignService $webmasterProvisionSignupCampaignService,
ParameterBagInterface $params,
) {
$this->jobService = $jobService;
$this->balanceWebmasterService = $balanceWebmasterService;
$this->webmasterPropertyService = $webmasterPropertyService;
$this->service = $webmasterProvisionSignupCampaignService;
$advertiserIds = explode(',', $params->get('advertiser_ids'));
$this->advertiserIds = array_map(function ($item) {
return (int) trim($item);
}, $advertiserIds);
}
public static function getSubscribedEvents(): array
{
return [
BalanceWebmasterProvisionCreatedEvent::class => [
['trackIncome', 0],
],
MemberCreatedEvent::class => [
['createWebmasterProvisionOnMemberSignupCompleted', 0],
],
];
}
protected function getPaymentMethodBlacklist(): array
{
return [
AdminBonusMethod::NAME,
];
}
protected function getAdvertiserIds(): array
{
return $this->advertiserIds;
}
protected function ensureConditionsForIncomeProvision(BalanceWebmasterProvisionCreatedEvent $event): bool
{
$provision = $event->getBalance();
if (BalanceType::INCOME !== $provision->getType()) {
return false;
}
$advertisingWebmaster = $provision->getWebmaster();
// exit early, as this is only for some webmaster ids
if (!in_array($advertisingWebmaster->getId(), $this->getAdvertiserIds())) {
return false;
}
// payment could be null for provisions of provisions
$payment = $provision->getPayment();
if (!$payment) {
return false;
}
// ignore bonuses
if (in_array($payment->getMethod(), $this->getPaymentMethodBlacklist())) {
return false;
}
$account = $payment->getAccount();
// nothing to do without a tracking id
$trackingId = $account->getAdvertisedByTrackingId();
if (empty($trackingId)) {
return false;
}
if (!$account->getAdvertisedBy() || $account->getAdvertisedBy()->getId() != $advertisingWebmaster->getId()) {
return false;
}
return true;
}
/**
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function trackIncome(BalanceWebmasterProvisionCreatedEvent $event)
{
if (!$this->ensureConditionsForIncomeProvision($event)) {
return;
}
$provision = $event->getBalance();
$payment = $provision->getPayment();
$account = $payment->getAccount();
$trackingId = $account->getAdvertisedByTrackingId();
$jobManager = $this->jobService;
$job = new DelineSunctionPaymentTrackingJob($trackingId, $provision->getAmount(), $payment->getId(), $account->getId());
$jobManager->createSaveAndSchedule($job, '', null, DelineSunctionPaymentTrackingJob::queue);
}
public function createWebmasterProvisionOnMemberSignupCompleted(MemberCreatedEvent $event)
{
if (!$this->service->canTriggerSignupProvision($event->getMember())) {
return;
}
$webmaster = $event->getAccount()->getAdvertisedBy();
$provisionAmount = $this->webmasterPropertyService->getValueForWebmaster($webmaster, WebmasterService::PROPERTY_MEMBERCREATED_PROVISION_AMOUNT_NET);
$provision = $this->balanceWebmasterService->createSignupProvisionByWebmaster($webmaster, BalanceType::INCOME);
$provision->setAmountAddVat($provisionAmount, VAT::PERCENT_21_FACTOR);
$this->balanceWebmasterService->storeBalanceWebmaster($provision);
}
}