Files
kupshop/bundles/External/HannahBundle/Admin/Actions/SellerUpdateAction.php
2025-08-02 16:30:27 +02:00

223 lines
6.8 KiB
PHP

<?php
declare(strict_types=1);
namespace External\HannahBundle\Admin\Actions;
use External\HannahBundle\SAP\MappingType;
use External\HannahBundle\SAP\Util\SAPUtil;
use External\HannahBundle\Util\Configuration;
use GraphQL\Exception\QueryError;
use KupShop\AdminBundle\Admin\Actions\AbstractAction;
use KupShop\AdminBundle\Admin\Actions\ActionResult;
use KupShop\AdminBundle\Admin\Actions\IAction;
use KupShop\AdminBundle\Util\ActivityLog;
use KupShop\ContentBundle\Entity\Image;
use KupShop\ContentBundle\Util\Block;
use KupShop\KupShopBundle\Config;
use KupShop\SellerBundle\Utils\SellerUtil;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use WpjShop\GraphQL\Client;
class SellerUpdateAction extends AbstractAction implements IAction
{
private array $context = [];
public function __construct(
private Configuration $configuration,
private SAPUtil $sapUtil,
private SellerUtil $sellerUtil,
private HttpClientInterface $client,
private Block $blockUtil,
) {
}
public function getTypes(): array
{
return ['sellers'];
}
public function getName(): string
{
return '[OC] Aktualizovat napříč shopy';
}
public function isVisible()
{
return (bool) $this->getId();
}
public function isEnabled()
{
return $this->configuration->getShopId() === Configuration::SHOP_ROCKPOINT;
}
public function showInMassEdit()
{
return true;
}
public function execute(&$data, array $config, string $type): ActionResult
{
if (isLocalDevelopment()) {
return new ActionResult(false);
}
try {
// projdu jednotlive shopy a zavolam na nich update / create
$this->forShop(function (Client $client) {
// pridam si ID root blocku do odpovedi
$client->seller->addSelection(['content' => ['id']]);
// nactu si data prodejny
$sellerData = $this->getSellerData((int) $this->getId());
try {
// kouknu pres API, zda na remote shopu prodejce uz existuje nebo neexistuje
$seller = $client->seller->get((int) $this->getId());
} catch (QueryError) {
$seller = null;
}
// provedu vytvoreni / aktualizaci prodejce
if (!$seller) {
$response = $client->seller->create($sellerData);
} else {
$response = $client->seller->update($seller['id'], $sellerData);
}
// aktualizuju obsah blocku
if ($response['result'] === true) {
$client->editableContent->update(
// musim pouzit spravne ID root bloku
$response['seller']['content']['id'],
$this->getSellerBlockData(
$this->sellerUtil->getSeller((int) $this->getId())
)
);
}
});
} catch (\Throwable $e) {
addActivityLog(ActivityLog::SEVERITY_ERROR, ActivityLog::TYPE_SYNC, '[OC] Synchronizace prodejen selhala!', [
'sellerId' => $this->getId(),
'message' => $e->getMessage(),
'data' => $sellerData ?? null,
]);
return new ActionResult(false, 'Během aktualizace se vyskytla chyba!');
}
return new ActionResult(true);
}
private function getSellerData(int $sellerId): ?array
{
if (!($seller = $this->sellerUtil->getSeller($sellerId))) {
return null;
}
$data = [
'id' => $sellerId,
'visible' => $seller['figure'] === 'Y',
'name' => $seller['title'],
'latitude' => (float) $seller['x'],
'longitude' => (float) $seller['y'],
'description' => $seller['descr'],
'type' => $seller['type'],
'email' => $seller['email'],
'street' => $seller['street'],
'number' => $seller['number'],
'city' => $seller['city'],
'zip' => $seller['psc'],
'phone' => $seller['phone'],
'country' => $seller['country'],
'data' => json_encode($seller['data']),
'photos' => [],
'deletePhotos' => true,
'flags' => [
'delete' => true,
'id' => array_keys($seller['flags'] ?? []),
],
];
// aktualizace skladu
if (!empty($seller['id_store'])) {
$data['storeId'] = $this->getStoreIdBySapId(
(string) $this->sapUtil->getSapId(MappingType::STORES, (int) $seller['id_store'])
);
}
$cfg = Config::get();
/** @var Image $photo */
foreach ($seller['photos'] ?? [] as $photo) {
$photoItem = [
'url' => (isDevelopment() ? $cfg['Addr']['full_original'] : $cfg['Addr']['full']).$photo->getImagePath(),
];
if ($centerPoint = ($photo->getData()['center_point'] ?? false)) {
$photoItem['centerPoint'] = [
'x' => (float) ($centerPoint['x'] ?? 50),
'y' => (float) ($centerPoint['y'] ?? 50),
];
}
$data['photos'][] = $photoItem;
}
return $data;
}
private function getSellerBlockData(array $seller): array
{
$data = [
'areas' => [],
'overwrite' => true,
];
foreach ($seller['blocks'] ?? [] as $block) {
$data['areas'][] = [
'id' => null,
'name' => $block['name'],
'dataPortable' => $this->blockUtil->getBlockPortableData($block) ?: '[]',
];
}
return $data;
}
private function getStoreIdBySapId(string $sapId): ?int
{
if (empty($sapId)) {
return null;
}
try {
$response = $this->client->request('GET', sprintf('%s/_sap/store_id/%s/', rtrim($this->context['domain'], '/'), $sapId));
if ($storeId = ($response->toArray()['id'] ?? null)) {
return (int) $storeId;
}
} catch (\Throwable $e) {
}
return null;
}
private function forShop(callable $fn): void
{
$dbcfg = \Settings::getDefault();
$configs = $dbcfg->loadValue('outdoorconcept')['api'] ?? [];
$this->context = [];
foreach ($configs as $config) {
if (empty($config['domain']) || empty($config['token'])) {
continue;
}
$this->context = $config;
$fn(new Client(rtrim($config['domain'], '/').'/admin/graphql', $config['token']));
}
}
}