first commit
This commit is contained in:
244
bundles/External/HannahBundle/SAP/Synchronizer/BaseSynchronizer.php
vendored
Normal file
244
bundles/External/HannahBundle/SAP/Synchronizer/BaseSynchronizer.php
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace External\HannahBundle\SAP\Synchronizer;
|
||||
|
||||
use Doctrine\DBAL\Exception\DeadlockException;
|
||||
use Doctrine\DBAL\Exception\LockWaitTimeoutException;
|
||||
use External\HannahBundle\SAP\Exception\SAPException;
|
||||
use External\HannahBundle\SAP\Util\SAPUtil;
|
||||
use External\HannahBundle\Util\Configuration;
|
||||
use KupShop\AdminBundle\Util\ActivityLog;
|
||||
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
abstract class BaseSynchronizer implements SynchronizerInterface
|
||||
{
|
||||
protected static $type;
|
||||
protected $logging = true;
|
||||
|
||||
protected bool $allowFullSync = false;
|
||||
|
||||
/** @required */
|
||||
public Configuration $configuration;
|
||||
|
||||
protected $sapUtil;
|
||||
|
||||
protected $activityLog;
|
||||
|
||||
protected $sentryLogger;
|
||||
|
||||
protected string $currentImportType = 'DIFF';
|
||||
protected bool $isFileImport = false;
|
||||
|
||||
protected array $context = [];
|
||||
|
||||
protected $logger;
|
||||
|
||||
protected $processItemCallback;
|
||||
|
||||
public function __construct(
|
||||
SAPUtil $sapUtil,
|
||||
LoggerInterface $logger,
|
||||
ActivityLog $activityLog,
|
||||
SentryLogger $sentryLogger,
|
||||
) {
|
||||
$this->sapUtil = $sapUtil;
|
||||
$this->activityLog = $activityLog;
|
||||
$this->logger = $logger;
|
||||
$this->sentryLogger = $sentryLogger;
|
||||
}
|
||||
|
||||
public static function getType(): string
|
||||
{
|
||||
if (empty(static::$type)) {
|
||||
throw new SAPException('Missing required property "$type" of synchronizer service');
|
||||
}
|
||||
|
||||
return static::$type;
|
||||
}
|
||||
|
||||
public function setProcessItemCallback(?callable $callback): void
|
||||
{
|
||||
$this->processItemCallback = $callback;
|
||||
}
|
||||
|
||||
public function setAllowFullSync(bool $allowFullSync): void
|
||||
{
|
||||
$this->allowFullSync = $allowFullSync;
|
||||
}
|
||||
|
||||
public function process(array $data): void
|
||||
{
|
||||
$this->createContext($data);
|
||||
|
||||
foreach ($this->getHandledFields() as $field => $methodName) {
|
||||
// missing data, or not expected structure
|
||||
if (!isset($data[$field]['item'])) {
|
||||
if (!array_key_exists($field, $data)) {
|
||||
// kibana log
|
||||
$this->log($data, sprintf('Unexpected data of "%s"', static::getType()));
|
||||
// activity log
|
||||
$this->activityLog->addActivityLog(
|
||||
ActivityLog::SEVERITY_WARNING,
|
||||
ActivityLog::TYPE_SYNC,
|
||||
sprintf('Data has unexpected format! Missing "%s" field of type "%s".', $field, static::getType()),
|
||||
$this->currentImportType === 'FULL' ? [] : ['data' => $data]
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$method = 'process'.ucfirst($methodName);
|
||||
if (!method_exists($this, $method)) {
|
||||
throw new SAPException(
|
||||
sprintf('Missing "%s:%s" method', static::class, $method)
|
||||
);
|
||||
}
|
||||
|
||||
// process data
|
||||
foreach (((array) $data[$field]['item']) as $item) {
|
||||
// zalogovat prichozi data
|
||||
$this->log((array) $item);
|
||||
|
||||
// process data
|
||||
try {
|
||||
$this->{$method}((array) $item);
|
||||
} catch (LockWaitTimeoutException|DeadlockException $e) {
|
||||
if ($this->currentImportType === 'FULL' && $this->isFileImport) {
|
||||
$this->onDeadLockFailure((array) $item);
|
||||
continue;
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($this->processItemCallback) {
|
||||
call_user_func($this->processItemCallback, (array) $item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->postprocess();
|
||||
|
||||
if ($this->context['isFileImport'] ?? false) {
|
||||
// prejmenuju soubor na FTP, aby koncil na ".done"
|
||||
if (!empty($this->context['filename'])) {
|
||||
$this->sapUtil->updateJSONFileAsDone($this->context['filename']);
|
||||
}
|
||||
|
||||
$this->sapUtil->addActivityLog('Úspěšně zpracován JSON: '.$this->context['filename'], severity: ActivityLog::SEVERITY_SUCCESS);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
if (isDevelopment()) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->sentryLogger->captureException($e);
|
||||
}
|
||||
}
|
||||
|
||||
public function processToSAP(): void
|
||||
{
|
||||
throw new SAPException('Process to SAP method is not implemented');
|
||||
}
|
||||
|
||||
protected function postprocess(): void
|
||||
{
|
||||
}
|
||||
|
||||
protected function onDeadlockFailure(array $item): void
|
||||
{
|
||||
// v BaseSynchronizer se nic nestane -> pouze az v CatalogSynchronizer
|
||||
}
|
||||
|
||||
abstract protected function getHandledFields(): array;
|
||||
|
||||
protected function createContext(array $data): void
|
||||
{
|
||||
$this->currentImportType = $data['ImportType'] ?? 'DIFF';
|
||||
$this->isFileImport = $data['isFileImport'] ?? false;
|
||||
|
||||
$context = [
|
||||
'importType' => $data['ImportType'] ?? 'DIFF',
|
||||
'isFileImport' => $data['isFileImport'] ?? false,
|
||||
'process' => $data['Process'] ?? 'WPJPL',
|
||||
];
|
||||
|
||||
$context['language'] = $this->configuration->getLanguageByProcess($context['process']);
|
||||
|
||||
if ($context['isFileImport']) {
|
||||
$context['filename'] = $data['filename'] ?? null;
|
||||
}
|
||||
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
public function getContext(): array
|
||||
{
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
protected function log(array $item, ?string $message = null): void
|
||||
{
|
||||
if (isLocalDevelopment()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->isLoggingEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$message) {
|
||||
$message = sprintf('SAP: Processing change of \'%s\'', static::getType());
|
||||
}
|
||||
|
||||
$this->logger->notice(
|
||||
$message,
|
||||
[
|
||||
'Type' => static::getType(),
|
||||
'Item' => $item,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function isLoggingEnabled(): bool
|
||||
{
|
||||
// vypinam logovani, protoze ho ted nevyuzivama a generuje to obrovske mnozstvi dat do Kibany
|
||||
return false;
|
||||
|
||||
// plne logovani pouze pro monobrandy
|
||||
if (in_array($this->configuration->getShopId(), [Configuration::SHOP_KEEN, Configuration::SHOP_HANNAH, Configuration::SHOP_RAFIKI])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->logging;
|
||||
}
|
||||
|
||||
private $tmpLastSync;
|
||||
|
||||
protected function getLastSyncTime(?string $type = null): ?int
|
||||
{
|
||||
$dbcfg = \Settings::getDefault();
|
||||
$sap = $dbcfg->loadValue('SAP');
|
||||
|
||||
$this->tmpLastSync = time() - (60 * 2);
|
||||
|
||||
return $sap[$type ?: static::getType()] ?? null;
|
||||
}
|
||||
|
||||
protected function updateLastSyncTime(): void
|
||||
{
|
||||
$dbcfg = \Settings::getDefault();
|
||||
|
||||
if (!($sap = $dbcfg->loadValue('SAP'))) {
|
||||
$sap = [];
|
||||
}
|
||||
|
||||
$sap[static::getType()] = $this->tmpLastSync ?: (time() - (60 * 2));
|
||||
|
||||
$dbcfg->saveValue('SAP', $sap, false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user