OpenXE/classes/Modules/Pipedrive/Scheduler/PipedrivePullDealsTask.php
2021-05-21 08:49:41 +02:00

285 lines
9.4 KiB
PHP

<?php
declare(strict_types=1);
namespace Xentral\Modules\Pipedrive\Scheduler;
use ArrayObject;
use Exception;
use Xentral\Components\Database\Database;
use Xentral\Modules\Pipedrive\Exception\PipedriveConfigurationException;
use Xentral\Modules\Pipedrive\Exception\PipedriveDealServiceException;
use Xentral\Modules\Pipedrive\Exception\PipedriveMetaException;
use Xentral\Modules\Pipedrive\Gateway\PipedriveDealGateway;
use Xentral\Modules\Pipedrive\Service\PipedriveConfigurationService;
use Xentral\Modules\Pipedrive\Service\PipedriveDealService;
use Xentral\Modules\Pipedrive\Service\PipedriveEventService;
use Xentral\Modules\Pipedrive\Service\PipedriveMetaReaderService;
use Xentral\Modules\Pipedrive\Service\PipedriveMetaWriterService;
use Xentral\Modules\Pipedrive\Wrapper\PipedriveResubmissionWrapper;
final class PipedrivePullDealsTask implements PipedriveSchedulerTaskInterface
{
/** @var Database $db */
private $db;
/** @var PipedriveMetaWriterService $metaWrite */
private $metaWrite;
/** @var PipedriveDealGateway $gateway */
private $gateway;
/** @var PipedriveDealService $dealService */
private $dealService;
/** @var PipedriveConfigurationService $configuration */
private $configuration;
/** @var PipedriveEventService $eventService */
private $eventService;
/** @var PipedriveMetaReaderService $metaReaderService */
private $metaReaderService;
/** @var PipedriveResubmissionWrapper $resubmissionWrapper */
private $resubmissionWrapper;
/**
* @param PipedriveDealService $dealService
* @param Database $db
* @param PipedriveMetaWriterService $metaWriterService
* @param PipedriveDealGateway $gateway
* @param PipedriveConfigurationService $configuration
* @param PipedriveEventService $eventService
* @param PipedriveMetaReaderService $metaReaderService
* @param PipedriveResubmissionWrapper $resubmissionWrapper
*/
public function __construct(
PipedriveDealService $dealService,
Database $db,
PipedriveMetaWriterService $metaWriterService,
PipedriveDealGateway $gateway,
PipedriveConfigurationService $configuration,
PipedriveEventService $eventService,
PipedriveMetaReaderService $metaReaderService,
PipedriveResubmissionWrapper $resubmissionWrapper
) {
$this->db = $db;
$this->dealService = $dealService;
$this->metaWrite = $metaWriterService;
$this->gateway = $gateway;
$this->configuration = $configuration;
$this->eventService = $eventService;
$this->metaReaderService = $metaReaderService;
$this->resubmissionWrapper = $resubmissionWrapper;
}
/**
* @param array $option
* @param string|null $type
* @param bool $recursiveMode
*
* @throws PipedriveConfigurationException
* @throws PipedriveDealServiceException
* @throws PipedriveMetaException
*
* @return void
*/
public function execute(array $option = [], ?string $type = null, bool $recursiveMode = false): void
{
$settings = $this->configuration->getSettings();
if ($settings['pd_sync_deals'] !== true) {
return;
}
$type = $type ?? 'pipedrive_recently_updated_deals';
if ($type !== 'pipedrive_recently_updated_deals' && empty($recursiveMode) &&
$this->db->fetchValue('SELECT COUNT(id) FROM `pipedrive_deals` WHERE `hidden` = 0') > 0) {
$type = 'pipedrive_recently_updated_deals';
}
$ret = $this->pull($type, $option);
if (array_key_exists('has_more', $ret) && $ret['has_more'] === true) {
$this->execute($option, $type, true);
}
}
/**
* @return void
*/
public function cleanup(): void
{
// TODO: Implement cleanup() method.
}
/**
* @param string $type
* @param array $options
*
* @throws PipedriveDealServiceException
* @throws PipedriveMetaException
* @throws Exception
*
* @return array
*/
protected function pull(string $type = 'pipedrive_recently_updated_deals', array $options = []): array
{
$response = $this->dealService->pullDeals($type, $options);
if ($response->getStatusCode() !== 200) {
return [];
}
$deals = $response->getData();
$pagination = $response->getPagination();
$metaFile = sprintf('%s.json', $type);
$metaOption = $this->metaReaderService->readFromFile($metaFile);
$hasMore = is_array($pagination) && array_key_exists(
'more_items_in_collection',
$pagination
) ? $pagination['more_items_in_collection'] : false;
$startOffset = 0;
if (empty($metaOption)) {
$timeOffset = '1970-01-01 23:59:59';
$this->metaWrite->save($metaFile, ['timeOffset' => $timeOffset]);
} elseif (array_key_exists('has_more', $options) && $options['has_more'] === true) {
$timeOffset = $options['previous_timeOffset'] ?? '1970-01-01 23:59:59';
$startOffset += 100;
} else {
$timeOffset = $metaOption['timeOffset'];
}
if (is_array($deals) && count($deals) > 0) {
foreach ($deals as $deal) {
$dealId = $deal['id'];
$hDeal = $deal['data'];
if ($hDeal['deleted'] === true) {
// DELETE IT HERE
if ($mapping = $this->gateway->getDealByPipedriveId($dealId)) {
$this->db->perform(
'DELETE FROM `pipedrive_deals` WHERE `pd_deal_id` = :id',
['id' => $dealId]
);
$this->db->perform(
'DELETE FROM `wiedervorlage` WHERE id = :id',
['id' => $mapping['wiedervorlage_id']]
);
}
continue;
}
if ($mapping = $this->gateway->getDealByPipedriveId($dealId)) {
$this->updateXTDeal($hDeal, $mapping['wiedervorlage_id']);
} elseif ($pipelineId = $this->addXTDeal($hDeal)) {
$this->db->perform(
'INSERT INTO `pipedrive_deals` (`pd_deal_id`, `created_at`, `wiedervorlage_id`)
VALUES (:id,NOW(), :pipelineId)',
['id' => (int)$dealId, 'pipelineId' => $pipelineId]
);
}
}
}
if (!empty($metaOption) && !array_key_exists('previous_timeOffset', $metaOption)) {
$this->metaWrite->save($metaFile, ['timeOffset' => gmdate('Y-m-d H:i:s')]);
}
return [
'has_more' => $hasMore,
'previous_timeOffset' => $timeOffset,
'startOffset' => $startOffset,
];
}
/**
* @param ArrayObject $data
*
* @throws PipedriveConfigurationException
*
* @return mixed|void
*/
public function beforeScheduleAction(ArrayObject $data)
{
if (empty($this->configuration->tryGetConfiguration('pipedrive_settings'))) {
return;
}
try {
$leadsFields = $this->configuration->matchSelectedAddressFreeField();
} catch (PipedriveConfigurationException $exception) {
return;
}
if (empty($leadsFields)) {
return;
}
}
/**
* @param ArrayObject $data
*/
public function afterScheduleAction(ArrayObject $data)
{
}
/**
* @param array $deal
*
* @throws Exception
*
* @return int
*/
private function addXTDeal(array $deal): int
{
$internalDeal = $this->configuration->formatDealToInternal($deal);
if (!$internalDeal) {
return 0;
}
$latestId = $this->resubmissionWrapper->addResubmission($internalDeal);
if ($data = $this->gateway->getMappingStageByResubmissionStageId($internalDeal['stages'])) {
$viewId = $data['wiedervorlage_view_id'];
$eventMsg = sprintf(
'Neues Deal (<a href="/index.php?module=wiedervorlage&action=list&view=%d">%s</a>) vom Pipedrive hinzugef&uuml;gt ins Xentral importiert',
$viewId,
$internalDeal['bezeichnung']
);
$this->eventService->add($eventMsg);
}
return $latestId;
}
/**
* @param array $deal
* @param int $wvId
*
* @throws Exception
*
* @return void
*/
private function updateXTDeal(array $deal, int $wvId): void
{
$internalDeal = $this->configuration->formatDealToInternal($deal);
if (!$internalDeal) {
return;
}
$this->resubmissionWrapper->updateResubmission($wvId, $internalDeal);
if ($data = $this->gateway->getMappingStageByResubmissionStageId($internalDeal['stages'])) {
$viewId = $data['wiedervorlage_view_id'];
$eventMsg = sprintf(
'Deal (<a href="/index.php?module=wiedervorlage&action=list&view=%d">%s</a>)
vom Pipedrive ge&auml;ndert und ins Xentral importiert',
$viewId,
$internalDeal['bezeichnung']
);
$this->eventService->add($eventMsg);
}
}
}