<?php
namespace App\Service;
use App\Entity\Adverts;
use App\Entity\Debit;
use App\EntityOtpusk\Events;
use App\Exception\EventsException;
use App\Repository\AgencyRepository;
use App\Repository\BlackListRepository;
use App\Repository\DebitRepository;
use App\Repository\EventsRepository;
use App\Repository\TourRepository;
use App\Repository\AdvertsRepository;
use App\Repository\ManagerLogsRepository;
use App\Service\Ipv6Service;
use ClickHouseDB\Exception\ClickHouseException;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Class EventsService
* @package App\Service
*/
class EventsService
{
/**
* @var EntityManagerInterface
*/
private $em;
/**
* @var TourRepository
*/
private $tourRepository;
/**
* @var EventsRepository
*/
private $eventsRepository;
/**
* @var KernelInterface
*/
private $kernelInterface;
/**
* @var DebitRepository
*/
private $debitRepository;
/**
* @var AgencyRepository
*/
private $agencyRepository;
/**
* @var NotificationService
*/
private $notificationService;
/**
* @var ManagerLogsRepository
*/
private $managerLogsRepository;
/**
* @var AdvertsRepository
*/
private $advertsRepository;
/**
* @var HttpClientInterface
*/
private $client;
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var \App\Repository\BlackListRepository
*/
private BlackListRepository $blackListRepository;
/**
* @var RequestStack
*/
private $requestStack;
/**
* EventsService constructor.
*
* @param EntityManagerInterface $em
* @param TourRepository $tourRepository
* @param EventsRepository $eventsRepository
* @param BlackListRepository $blackListRepository
* @param DebitRepository $debitRepository
* @param AgencyRepository $agencyRepository
* @param NotificationService $notificationService
* @param ManagerLogsRepository $managerLogsRepository
* @param AdvertsRepository $advertsRepository
* @param KernelInterface $kernelInterface
* @param LoggerInterface $logger
* @param HttpClientInterface $client
* @param Request $request
*/
public function __construct(
EntityManagerInterface $em,
TourRepository $tourRepository,
EventsRepository $eventsRepository,
BlackListRepository $blackListRepository,
DebitRepository $debitRepository,
AgencyRepository $agencyRepository,
NotificationService $notificationService,
ManagerLogsRepository $managerLogsRepository,
AdvertsRepository $advertsRepository,
KernelInterface $kernelInterface,
HttpClientInterface $client,
LoggerInterface $logger,
RequestStack $requestStack
) {
$this->em = $em;
$this->tourRepository = $tourRepository;
$this->eventsRepository = $eventsRepository;
$this->blackListRepository = $blackListRepository;
$this->kernelInterface = $kernelInterface;
$this->debitRepository = $debitRepository;
$this->agencyRepository = $agencyRepository;
$this->managerLogsRepository = $managerLogsRepository;
$this->advertsRepository = $advertsRepository;
$this->notificationService = $notificationService;
$this->client = $client;
$this->logger = $logger;
$this->requestStack = $requestStack;
}
public function getEvents(Events $event)
{
$this->eventsRepository->_connect();
}
public function saveEvent(Events $event, $getEvent=false)
{
$tourInfo = $this->tourRepository->getTourInfo(
$event->getOfferId(),
$event->getOperatorId(),
$event->getCruiseId()
);
if (isset($_COOKIE['DM'])) {
header('X-tourInfo: '.json_encode([
'offerId' => $tourInfo->getOfferId(),
'operatorId' => $tourInfo->getOperatorId(),
'countryId' => $tourInfo->getCountryId(),
'hotelId' => $tourInfo->getHotelId(),
'fromCityId' => $tourInfo->getFromCityId(),
'checkIn' => $tourInfo->getCheckIn() ? $tourInfo->getCheckIn()->format('Y-m-d') : null,
'nights' => $tourInfo->getNights(),
'adult' => $tourInfo->getAdult(),
'child' => $tourInfo->getChild(),
'food' => $tourInfo->getFood(),
'transport' => $tourInfo->getTransport(),
'roomId' => $tourInfo->getRoomId(),
'price' => $tourInfo->getPrice(),
'currency' => $tourInfo->getCurrency(),
]));
}
if ($tourInfo && $tourInfo->getOfferId()) {
$event->setOperatorId($tourInfo->getOperatorId());
$event->setCountryId($tourInfo->getCountryId());
$event->setHotelId($tourInfo->getHotelId());
$event->setFromCityId($tourInfo->getFromCityId());
$event->setCheckIn($tourInfo->getCheckIn());
$event->setNights($tourInfo->getNights());
if (empty($tourInfo->getChild())) {
$event->setPeople($tourInfo->getAdult());
} else {
if (empty($event->getPeople())) {
$child = $tourInfo->getChild();
if ($child == 1) {
$child = '06';
} elseif ($child == 2) {
$child = '0608';
} elseif ($child == 3) {
$child = '060810';
} elseif ($child == 4) {
$child = '05070911';
}
$event->setPeople($tourInfo->getAdult().$child);
}
}
$event->setFood($tourInfo->getFood());
$event->setTransport($tourInfo->getTransport());
$event->setRoomId($tourInfo->getRoomId());
if ($tourInfo->getCurrency() == 'uah') {
$priceUah = $tourInfo->getPrice();
} else {
$priceUah = $tourInfo->getPriceUah();
if (empty($priceUah)) {
$priceUah = $tourInfo->getPrice() * $tourInfo->getCurrencyRate();
}
}
$event->setPrice($priceUah);
$event->setCurrency($tourInfo->getCurrency());
}
if (empty($event->getHotelId()) && !empty($event->getOfferId())) {
$httpClient = HttpClient::create();
$offerId = $event->getOfferId();
$response = $httpClient->request(
'GET',
'https://api.otpusk.com/api/2.5/tours/offer?offerId='.$offerId.'&access_token=4b26a-e5237-9b0fa-bcc36-67732',
['headers' => ['User-Agent' => 'pro.otpusk.com']]
);
if (200 == $response->getStatusCode()) {
$offer = $response->toArray();
$content = $offer['offer'];
if (empty($event->getCountryId()) && isset($content['countryId']))
$event->setCountryId($content['countryId']);
if (empty($event->getHotelId()) && isset($offer['hotelId']))
$event->setHotelId($offer['hotelId']);
if (empty($event->getHotelId()) && isset($content['hotelId']))
$event->setHotelId($content['hotelId']);
if (empty($event->getFromCityId()) && isset($content['fromCity']))
$event->setFromCityId($content['fromCity']);
if (empty($event->getRoomId()) && isset($content['roomId']))
$event->setRoomId($content['roomId']);
if (empty($event->getPrice()) && isset($content['priceUah']))
$event->setPrice($content['priceUah']);
}
}
$event->setEventPrice(0);
// Ищем объявление
$advertsRepository = $this->em->getRepository(Adverts::class);
/** @var $advertInfo Adverts */
$advertInfo = $advertsRepository->find($event->getAdvertId());
$event->setEventPrice(0);
if ($advertInfo && $advertInfo->getAgency() &&
$advertInfo->getAgency()->getActive() > 0 &&
$advertInfo->getAgency()->getStatus() == 'premium')
{
$event->setAgencyId($advertInfo->getAgency()->getId());
$event->setEventPrice($advertInfo->getPrice() ?? 50);
} else {
$event->setEventPosition(22);
}
/*
if ($event->getEventPrice() > 0) {
if (!$tourInfo || !$tourInfo->getOfferId()) {
// если не найден offer
$event->setEventPrice(0);
$event->setEventPosition(24);
}
}
*/
// fixme: нужно как-то проверять относится ли officeId и advertId к одному агентству
if ($event->getEventPrice() > 0) {
try {
$ip = $this->blackListRepository->getByIp(intval($event->getIp()));
if ($ip) {
// Ip в черном списке
$event->setEventPrice(0);
$event->setEventPosition(31);
}
} catch (ClickHouseException $e) {
$events = 'error: '.$e->getMessage();
}
if (isset($_COOKIE['DM'])) {
header('X-31-blacklist: '.$ip);
}
}
if ($event->getEventPrice() > 0) {
// проверяем был ли уже такое событие сегодня у этого объявления
$option = array(
\Memcached::OPT_PREFIX_KEY => (getenv('MEMCACHED_PREFIX') ? getenv(
'MEMCACHED_PREFIX'
) : ($_ENV['MEMCACHED_PREFIX'] ?? '')),
);
$client = MemcachedAdapter::createConnection(
getenv('MEMCACHED_SERV') ? getenv('MEMCACHED_SERV') : $_ENV['MEMCACHED_SERV'],
$option
);
$cache_key = 'event_'.$event->getEventDate()->format('Ymd').'_'.$event->getAdvertId().'_'.$event->getIp();
if (isset($_COOKIE['DM'])) {
$MEMCACHED_PREFIX = (getenv('MEMCACHED_PREFIX') ? getenv(
'MEMCACHED_PREFIX'
) : ($_ENV['MEMCACHED_PREFIX'] ?? ''));
$MEMCACHED_SERV = (getenv('MEMCACHED_SERV') ? getenv('MEMCACHED_SERV') : $_ENV['MEMCACHED_SERV']);
$client->set('test_'.$cache_key, time(), 24 * 60 * 60);
header(
'X-26-memTest: '.$MEMCACHED_SERV.'@'.$MEMCACHED_PREFIX.'&'.$cache_key.'='.$client->get(
'test_'.$cache_key
)
);
}
if ($event_time = $client->get($cache_key)) {
// уникальное событие, если сегодня уже было
$event->setEventPrice(0);
$event->setEventPosition(26);
} else {
$client->set($cache_key, time(), time() + (24 * 60 * 60));
}
}
if ($event->getEventPrice() > 0) {
try {
$log = $this->managerLogsRepository->findOneBy(['ip' => $event->getIp()]);
if ($log && $log->getIp2Long() == $event->getIp()) {
// игнорируем если это IP менеджера любого из агентства
$event->setEventPrice(0);
$event->setEventPosition(27);
}
} catch (Exception $e) {
}
if (isset($_COOKIE['DM'])) {
header('X-27-isManager: '.$event->getIp().'='.($log ? $log->getIp2Long() : -1));
}
}
if ($event->getEventPrice() > 0) {
if ($advertInfo->getDaybudget() > 0) {
try {
$dayCost = $this->debitRepository->findCostsForCurrentDay($advertInfo->getAgency()->getId());
if ($dayCost > 0 && $dayCost >= $advertInfo->getDaybudget()) {
// если превысили дневной бюджет
$event->setEventPrice(0);
$event->setEventPosition(28);
}
} catch (Exception $e) {
$dayCost = 'error: '.$e->getMessage();
}
if (isset($_COOKIE['DM'])) {
header('X-28-dayLimit: '.$dayCost.'>='.$advertInfo->getDaybudget());
}
}
}
if ($event->getEventPrice() > 0) {
try {
$events = $this->eventsRepository->getTotalEventsToDayByIp(intval($event->getIp()));
if ($events >= 3) {
// Не более 3-х платных взаимодействий в сутки с одного IP в не зависимости от объявлений
$event->setEventPrice(0);
$event->setEventPosition(29);
}
} catch (ClickHouseException $e) {
$events = 'error: '.$e->getMessage();
}
if (isset($_COOKIE['DM'])) {
header('X-29-events: '.$events.'>='. 3);
}
}
// TODO return if didnt help
/*
if ($event->getEventPrice() > 0) {
if (isset($_COOKIE['DM'])) header('X-30-IP: ' . $event->getIp() .' = '. Ipv6Service::long2ip($event->getIp()));
try {
$countryIso = $this->eventsRepository->checkCountryIp($event->getIp());
if ($countryIso && $countryIso != 'UA') {
//Если ip не из Украины
$event->setEventPrice(0);
$event->setEventPosition(30);
}
} catch (ClickHouseException $e) {
$countryIso = 'error: '.$e->getMessage();
}
if (isset($_COOKIE['DM'])) header('X-30-CountryCode: ' . $countryIso);
}
*/
try {
$this->eventsRepository->save($event);
} catch (ClickHouseException $e) {
if (isset($_COOKIE['DM'])) {
header('X-88-error: '.$e->getMessage());
}
}
if (false !== stripos($getEvent??$event->getEventTypeName(), 'showFormAd')) {
// для собитий show ціни немає
$event->setEventPrice(0);
$event->setEventPosition(32);
}
return $event->getEventPrice();
}
public function sendGA($clientId=false, $sessionId=false, Events $event, $getEvent=false)
{
$APP_ENV = (getenv('APP_ENV') ? getenv('APP_ENV') : $_ENV['APP_ENV']);
if ($APP_ENV != 'prod') {
$this->logger->info('Error Send GA env: '.$APP_ENV);
return false;
}
$account_id = (getenv('GA_ACCOUNT') ? getenv('GA_ACCOUNT') : ($_ENV['GA_ACCOUNT'] ?? ''));
if (isset($_COOKIE['DM'])) {
header('X-ACCOUNT-ID: '.$account_id);
header('X-Event-Price: '.$event->getEventPrice());
header('X-client: '.$clientId);
}
if ($event->getEventPrice() <= 0) {
$this->logger->info('Error Send GA price: '.$event->getEventPrice());
return false;
}
if (empty($account_id)) {
$this->logger->info('Error Send GA account: '.$account_id);
return null;
}
$trans_id = date('d0m').'0'
.sprintf("%u", $event->getIp()).'_'
.$event->getAdvertId().'_'
.($event->getCruiseId() > 0 ? '' : $event->getCountryId().'_')
.$event->getRegionId().'_'
.($event->getCruiseId() > 0 ? 'excursion' : 'package');
if (isset($_COOKIE['DM'])) {
header('X-TRANS-ID: '.$trans_id);
}
if (!empty($clientId)) {
/*
// send GA #33394
$response = $this->client->request(
'POST',
'http://www.google-analytics.com/collect',
[
'body' => [
'v' => '1', //версия протокола, походу второй нет, только первая
'tid' => $account_id, //ид гугл аналитики.
'cid' => $clientId, //Client ID – будет отдавать фронт
't' => 'transaction', //тип хита в этом случае
'ti' => $trans_id, //ид транзакции
'tr' => $event->getEventPrice() // сумма транзакции
],
'timeout' => 5,
'max_duration' => 5,
'buffer' => false,
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'User-Agent' => 'www.otpusk.com',
],
]
);
$this->logger->info('Send GA1 ' . $response->getInfo('url') . ' status: ' . $response->getStatusCode());
if (isset($_COOKIE['DM'])) {
header('X-SEND-GA1: ' . $response->getStatusCode());
}
$response = $this->client->request(
'POST',
'http://www.google-analytics.com/collect',
[
'body' => [
'v' => '1', //версия протокола, походу второй нет, только первая
'tid' => $account_id, //ид гугл аналитики.
'cid' => $clientId, //Client ID – будет отдавать фронт
't' => 'item', //тип хита в этом случае
'ti' => $trans_id, //ид транзакции
'in' => $event->getAgencyId(), // Название турфирмы
'ip' => $event->getPrice(), // стоимость товара
'iv' => ($event->getCruiseId() > 0 ? 'Excursion' : 'Package'),
],
'timeout' => 5,
'max_duration' => 5,
'buffer' => false,
'verify_peer' => false,
'verify_host' => false,
'headers' => [
'User-Agent' => 'www.otpusk.com',
],
]
);
$this->logger->info('Send GA2 ' . $response->getInfo('url') . ' status: ' . $response->getStatusCode());
if (isset($_COOKIE['DM'])) {
header('X-SEND-GA2: ' . $response->getStatusCode());
}
*/
$post = [
'client_id' => $clientId,
'non_personalized_ads' => false,
'events' => [
[
//'name' => 'purchase',
'name' => 'api'.ucfirst($getEvent??$event->getEventTypeName()), // 'purchase',
//'timestamp_micros' => microtime(true) * 1000000,
'params' => [
'eventCategory' => 'offerPageAds',
'type' => ($event->getCruiseId() > 0 ? 'Excursion' : 'Package'),
'value' => (float)$event->getEventPrice(),
'lang' => 'UK',
'currency' => 'UAH',
'client_id' => $clientId,
'session_id' => $sessionId,
'debug_mode' => true,
/*
'transaction_id' => $trans_id,
//'agency_id' => $event->getAgencyId(),
'items' => [
[
'item_id' => (string)($event->getAdvertId() . $event->getRegionId()),
'item_name' => 'id: ' . ((string)$event->getAdvertId() . $event->getRegionId()),
//'item_name' => $event->getEventType(),
'item_category' => ($event->getCruiseId() > 0 ? 'Excursion' : 'Package'),
//'item_brand' => $event->getAgencyId(),
'price' => (float)$event->getEventPrice(),
'currency' => 'UAH',
'quantity' => 1,
]
],
*/
]
]
],
//'validationBehavior' => 'ENFORCE_RECOMMENDATIONS'
];
$userAgent = 'www.otpusk.com';
$currentRequest = $this->requestStack->getCurrentRequest();
if ($currentRequest) {
$userAgent = $currentRequest->headers->get('User-Agent', 'www.otpusk.com');
}
$headers = [
'User-Agent' => $userAgent,
'Content-Type' => 'application/json',
//'Accept' => 'application/json',
];
$response = $this->client->request(
'POST',
//'https://www.google-analytics.com/debug/mp/collect?api_secret=' . urlencode('X7iB6sPfTWqTIvOwjwqV7Q') . '&measurement_id=' . urlencode('G-V52QLQJ1C6'),
'https://www.google-analytics.com/mp/collect?api_secret=' . urlencode('X7iB6sPfTWqTIvOwjwqV7Q') . '&measurement_id=' . urlencode('G-V52QLQJ1C6'),
[
'body' => json_encode($post),
'timeout' => 5,
'max_duration' => 5,
'buffer' => false,
'verify_peer' => false,
'verify_host' => false,
'headers' => $headers,
]
);
$this->logger->info('Send GA4 ' . $response->getInfo('url') . ' status: ' . $response->getStatusCode());
if (isset($_COOKIE['DM'])) {
header('X-SEND-GA4: ' . $response->getInfo('url') . ' ' . $response->getStatusCode() . ' ' . json_encode($post) . ' ' . json_encode($headers));
}
}
return true;
}
public function gelLast($limit = 20)
{
return $this->eventsRepository->findAll(10);
}
public function updateDebitsByEvents($date = null)
{
$startTime = microtime(true);
$startMemory = memory_get_usage(true);
if ($date) {
try {
$now = new \DateTime($date);
$now = $now->format('Y-m-d');
} catch (\Exception $e) {
echo 'Invalid date format. Use YYYY-MM-DD'.PHP_EOL;
return;
}
} else {
$now = new \DateTime('now');
$now = $now->format('Y-m-d');
}
echo PHP_EOL.'========== DEBITS BY EVENTS PROCESSING =========='.PHP_EOL;
echo 'Start time: '.date('Y-m-d H:i:s').PHP_EOL;
echo 'Processing date: '.$now.PHP_EOL.PHP_EOL;
$events = $this->eventsRepository->findToDayEvents($now);
echo '[INFO] Found '.count($events).' events/agencies'.PHP_EOL;
$totalProcessed = 0;
$totalCreated = 0;
$totalUpdated = 0;
$totalErrors = 0;
$negativeBalanceAgencies = 0;
foreach ($events as $event) {
$data = false;
if ($event['agencyId']) {
$agency = $this->agencyRepository->findOneBy(['id' => $event['agencyId'], 'status' => 'premium']);
if ($agency) {
$debit = $this->debitRepository->findByAgencyAndEvent($agency, $now);
$isNew = !$debit;
if ( ! $debit) {
$debit = new Debit();
$debit->setAgency($agency);
$debit->setDateType(3);
$debit->setType('event');
$debit->setStatus('paid');
$debit->setDate(new \DateTime($now));
$debit->setCreatedAt(new \DateTime($now.' 12:00:00'));
$totalCreated++;
} else {
$totalUpdated++;
}
$debit->setSum($event['eventPrices']);
$this->em->persist($debit);
$this->em->flush();
$totalProcessed++;
echo ' [OK] Agency #'.$event['agencyId'].' - Sum: '.$event['eventPrices'].' ('.($isNew ? 'CREATED' : 'UPDATED').')'.PHP_EOL;
$data = $this->debitRepository->checkingNegativeBalance($event['agencyId']);
} else {
$totalErrors++;
echo ' [ERROR] Agency #'.$event['agencyId'].' is not premium or not found'.PHP_EOL;
}
}
if ($data) {
$negativeBalanceAgencies++;
if ($agency && $agency->getStatus() == 'premium') {
echo ' [WARNING] Agency #'.$event['agencyId'].' has NEGATIVE BALANCE: '.$data['balance'].PHP_EOL;
$handle = curl_init();
$url = 'https://control.otpusk.com/api/setagencynopaid?agencyId='.$event['agencyId'].'&access_token=4b26a-e5237-9b0fa-bcc36-67732';
curl_setopt($handle, CURLOPT_USERAGENT, 'pro.otpusk.com');
curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_FAILONERROR, true);
$curlResult = curl_exec($handle);
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
echo ' [CURL] HTTP Code: '.$httpCode.PHP_EOL;
echo 'http code: '.var_export(curl_getinfo($handle, CURLINFO_HTTP_CODE), 1).PHP_EOL;
echo 'agencyId: '.var_export($event['agencyId'], 1).PHP_EOL;
echo 'curl error: '.var_export(curl_error($handle), 1).PHP_EOL;
curl_close($handle);
if ($data['email']) {
echo ' [EMAIL] Notification sent to: '.$data['email'].PHP_EOL;
$this->notificationService->negativeBalance($data);
}
}
}
}
$endTime = microtime(true);
$endMemory = memory_get_usage(true);
$duration = round($endTime - $startTime, 2);
$memoryUsed = round(($endMemory - $startMemory) / 1024 / 1024, 2);
echo PHP_EOL.'========== PROCESSING SUMMARY =========='.PHP_EOL;
echo 'Date processed: '.$now.PHP_EOL;
echo 'Total events found: '.count($events).PHP_EOL;
echo 'Total debits processed: '.$totalProcessed.PHP_EOL;
echo ' - Created: '.$totalCreated.PHP_EOL;
echo ' - Updated: '.$totalUpdated.PHP_EOL;
echo ' - Errors: '.$totalErrors.PHP_EOL;
echo 'Agencies with negative balance: '.$negativeBalanceAgencies.PHP_EOL;
echo 'Execution time: '.$duration.' sec'.PHP_EOL;
echo 'Memory used: '.$memoryUsed.' MB'.PHP_EOL;
echo 'End time: '.date('Y-m-d H:i:s').PHP_EOL;
echo '=========================================='.PHP_EOL.PHP_EOL;
}
public function updateDebitsByEventsAgencies($date = null)
{
$startTime = microtime(true);
$startMemory = memory_get_usage(true);
if ($date) {
try {
$now = new \DateTime($date);
$now = $now->format('Y-m-d');
} catch (\Exception $e) {
echo 'Invalid date format. Use YYYY-MM-DD'.PHP_EOL;
return;
}
} else {
$now = new \DateTime('now');
$now = $now->format('Y-m-d');
}
echo PHP_EOL.'========== DEBITS BY EVENTS AGENCIES PROCESSING =========='.PHP_EOL;
echo 'Start time: '.date('Y-m-d H:i:s').PHP_EOL;
echo 'Processing date: '.$now.PHP_EOL.PHP_EOL;
$agencies = $this->eventsRepository->findAgenciesByEvents();
$agencies = array_column($agencies, 'agencyId');
echo '[INFO] Found '.count($agencies).' active agencies (last 1 min)'.PHP_EOL;
$totalProcessed = 0;
$totalCreated = 0;
$totalUpdated = 0;
$totalErrors = 0;
$negativeBalanceAgencies = 0;
if ( ! empty($agencies)) {
$events = $this->eventsRepository->findToDayEvents($now, $agencies);
echo '[INFO] Found '.count($events).' events for these agencies'.PHP_EOL.PHP_EOL;
foreach ($events as $event) {
$data = false;
if ($event['agencyId']) {
$agency = $this->agencyRepository->findOneBy(['id' => $event['agencyId'], 'status' => 'premium']);
if ($agency) {
$debit = $this->debitRepository->findByAgencyAndEvent($agency, $now);
$isNew = !$debit;
if ( ! $debit) {
$debit = new Debit();
$debit->setAgency($agency);
$debit->setDateType(3);
$debit->setType('event');
$debit->setStatus('paid');
$debit->setDate(new \DateTime($now));
$debit->setCreatedAt(new \DateTime($now.' 12:00:00'));
$totalCreated++;
} else {
$totalUpdated++;
}
$debit->setSum($event['eventPrices']);
$this->em->persist($debit);
$this->em->flush();
$totalProcessed++;
echo ' [OK] Agency #'.$event['agencyId'].' - Sum: '.$event['eventPrices'].' ('.($isNew ? 'CREATED' : 'UPDATED').')'.PHP_EOL;
$data = $this->debitRepository->checkingNegativeBalance($event['agencyId']);
} else {
$totalErrors++;
echo ' [ERROR] Agency #'.$event['agencyId'].' is not premium or not found'.PHP_EOL;
}
}
if ($data) {
$negativeBalanceAgencies++;
if ($agency && $agency->getStatus() == 'premium') {
echo ' [WARNING] Agency #'.$event['agencyId'].' has NEGATIVE BALANCE: '.$data['balance'].PHP_EOL;
$handle = curl_init();
$url = 'https://control.otpusk.com/api/setagencynopaid?agencyId='.$event['agencyId'].'&access_token=4b26a-e5237-9b0fa-bcc36-67732';
curl_setopt($handle, CURLOPT_USERAGENT, 'pro.otpusk.com');
curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_FAILONERROR, true);
$curlResult = curl_exec($handle);
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
echo ' [CURL] HTTP Code: '.$httpCode.PHP_EOL;
curl_close($handle);
if ($data['email']) {
echo ' [EMAIL] Notification sent to: '.$data['email'].PHP_EOL;
$this->notificationService->negativeBalance($data);
}
}
}
}
} else {
echo '[INFO] No active agencies found'.PHP_EOL;
}
$endTime = microtime(true);
$endMemory = memory_get_usage(true);
$duration = round($endTime - $startTime, 2);
$memoryUsed = round(($endMemory - $startMemory) / 1024 / 1024, 2);
echo PHP_EOL.'========== PROCESSING SUMMARY =========='.PHP_EOL;
echo 'Date processed: '.$now.PHP_EOL;
echo 'Active agencies: '.count($agencies).PHP_EOL;
echo 'Total debits processed: '.$totalProcessed.PHP_EOL;
echo ' - Created: '.$totalCreated.PHP_EOL;
echo ' - Updated: '.$totalUpdated.PHP_EOL;
echo ' - Errors: '.$totalErrors.PHP_EOL;
echo 'Agencies with negative balance: '.$negativeBalanceAgencies.PHP_EOL;
echo 'Execution time: '.$duration.' sec'.PHP_EOL;
echo 'Memory used: '.$memoryUsed.' MB'.PHP_EOL;
echo 'End time: '.date('Y-m-d H:i:s').PHP_EOL;
echo '=========================================='.PHP_EOL.PHP_EOL;
}
public function fixDebitsByEvents()
{
$datesArray = [
'2021-04-12',
'2021-04-11',
'2021-04-10',
'2021-04-09',
'2021-04-08',
'2021-04-07',
'2021-04-06',
'2021-04-05',
'2021-04-04',
'2021-04-03',
'2021-04-02',
];
foreach ($datesArray as $now) {
$events = $this->eventsRepository->findToDayEvents($now);
foreach ($events as $event) {
if ($event['agencyId']) {
$agency = $this->agencyRepository->findOneBy(['id' => $event['agencyId']]);
if ($agency) {
$debit = $this->debitRepository->findByAgencyAndEvent($agency, $now);
if ( ! $debit) {
$debit = new Debit();
$debit->setAgency($agency);
$debit->setDateType(3);
$debit->setType('event');
$debit->setStatus('paid');
$debit->setDate(new \DateTime($now));
}
$debit->setSum($event['eventPrices']);
$this->em->persist($debit);
$this->em->flush();
}
}
}
}
}
public function updateEmptyEvents()
{
$events = $this->eventsRepository->findEventsUntillNow('2021-10-19');
foreach ($events as $event) {
$httpClient = HttpClient::create();
$offreId = $event['offerId'];
$response = $httpClient->request(
'GET',
'https://api.otpusk.com/api/2.5/tours/offer?offerId='.$offreId.'&access_token=4b26a-e5237-9b0fa-bcc36-67732',
['headers' => ['User-Agent' => 'pro.otpusk.com']]
);
if (200 == $response->getStatusCode()) {
$content = $response->toArray()['offer'];
if ($content) {
var_dump($event['offerId']);
$this->eventsRepository->updateEvent($event, $content);
sleep(1);
}
}
}
}
}