346 lines
9.4 KiB
PHP
346 lines
9.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace External\ZNZBundle\Util;
|
|
|
|
use External\ZNZBundle\Exception\ZNZException;
|
|
use KupShop\KupShopBundle\Context\CurrencyContext;
|
|
use KupShop\KupShopBundle\Util\Contexts;
|
|
use KupShop\SynchronizationBundle\Rabbit\RetryStrategy\MultiplierRetryStrategy;
|
|
use KupShop\SynchronizationBundle\Rabbit\RetryStrategy\RetryStrategyInterface;
|
|
use KupShop\SynchronizationBundle\Util\SynchronizationConfiguration;
|
|
use Query\Operator;
|
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
|
use Symfony\Contracts\Service\Attribute\Required;
|
|
|
|
class ZNZConfiguration
|
|
{
|
|
public const SHOP_MODE_B2C = 'b2c';
|
|
public const SHOP_MODE_B2B = 'b2b';
|
|
public const SHOP_MODE_B2B_BASIC = 'b2b_basic';
|
|
|
|
private array $parameters = [];
|
|
private array $domains = [];
|
|
|
|
public function __construct(
|
|
private readonly SynchronizationConfiguration $synchronizationConfiguration,
|
|
) {
|
|
}
|
|
|
|
#[Required]
|
|
final public function setDomains(#[Autowire(param: 'shop.domains')] array $domains): void
|
|
{
|
|
$this->domains = $domains;
|
|
}
|
|
|
|
#[Required]
|
|
final public function setParameters(#[Autowire(param: 'znz')] array $parameters): void
|
|
{
|
|
$this->parameters = $parameters;
|
|
}
|
|
|
|
public function getShopMode(): string
|
|
{
|
|
return $this->parameters['mode'] ?? self::SHOP_MODE_B2C;
|
|
}
|
|
|
|
/**
|
|
* B2B mod, ktery lehce meni zpusob synchronizace.
|
|
*
|
|
* Standardni varianty nevznikaji, vsechno jsou produkty.
|
|
* Varianty vznikaji jen pro sklad (Sklad: 00001, 00002...).
|
|
*
|
|
* Diky tomu muze existovat cena per sklad.
|
|
*/
|
|
public function isB2BMode(): bool
|
|
{
|
|
return $this->getShopMode() === self::SHOP_MODE_B2B;
|
|
}
|
|
|
|
/**
|
|
* B2B mod, ktery nemeni synchronizaci a data jsou vlastne stejna jako u B2C shopu.
|
|
*/
|
|
public function isB2BBasicMode(): bool
|
|
{
|
|
return $this->getShopMode() === self::SHOP_MODE_B2B_BASIC;
|
|
}
|
|
|
|
/**
|
|
* Vrati true, pokud je aktivni jeden ze dvou B2B modu.
|
|
*/
|
|
public function isB2BShop(): bool
|
|
{
|
|
return $this->isB2BMode() || $this->isB2BBasicMode();
|
|
}
|
|
|
|
public function getB2BGroup(): ?int
|
|
{
|
|
if (!$this->isB2BShop()) {
|
|
return null;
|
|
}
|
|
|
|
static $b2bGroupId;
|
|
|
|
if (!$b2bGroupId) {
|
|
$userGroupId = sqlQueryBuilder()
|
|
->select('id')
|
|
->from('users_groups')
|
|
->where(Operator::equals(['name' => 'B2B']))
|
|
->execute()->fetchOne();
|
|
|
|
if (!$userGroupId) {
|
|
$userGroupId = sqlGetConnection()->transactional(function () {
|
|
sqlQueryBuilder()
|
|
->insert('users_groups')
|
|
->directValues(['name' => 'B2B', 'types' => 'b2b'])
|
|
->execute();
|
|
|
|
return (int) sqlInsertId();
|
|
});
|
|
}
|
|
|
|
$b2bGroupId = $userGroupId;
|
|
}
|
|
|
|
return $b2bGroupId;
|
|
}
|
|
|
|
public function getB2BRegistrationGroup(): ?int
|
|
{
|
|
if (!$this->isB2BShop()) {
|
|
return null;
|
|
}
|
|
|
|
static $b2bRegistrationGroupId;
|
|
|
|
if ($b2bRegistrationGroupId === null) {
|
|
$b2bRegistrationGroupId = sqlQueryBuilder()
|
|
->select('id')
|
|
->from('users_groups')
|
|
->where(Operator::equals(['name' => 'Registrace B2B']))
|
|
->execute()->fetchOne();
|
|
}
|
|
|
|
return $b2bRegistrationGroupId ?: null;
|
|
}
|
|
|
|
public function isSynchronizationEnabled(): bool
|
|
{
|
|
if (($this->getSettings()['sync']['enabled'] ?? 0) == 1) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function useProductionHelios(): bool
|
|
{
|
|
if (($this->getSettings()['sync']['production'] ?? 0) == 1) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function getOrderErrorStatus(): int
|
|
{
|
|
return 5;
|
|
}
|
|
|
|
public function getOrderStornoStatus(): int
|
|
{
|
|
return 9;
|
|
}
|
|
|
|
public function getOrderPrefix(?string $language = null): ?string
|
|
{
|
|
$result = $this->getSettings()['order']['prefixes'][$language] ?? null;
|
|
if (empty($result)) {
|
|
$result = $this->getSettings()['order']['prefix'] ?? null;
|
|
}
|
|
|
|
return empty($result) ? null : $result;
|
|
}
|
|
|
|
public function getOrderPrefixes(): array
|
|
{
|
|
return array_filter(
|
|
array_merge(
|
|
[$this->getSettings()['order']['prefix'] ?? null],
|
|
array_values($this->getSettings()['order']['prefixes'] ?? [])
|
|
)
|
|
);
|
|
}
|
|
|
|
public function getHeliosConnectionParameters(bool $test = false): array
|
|
{
|
|
if (isLocalDevelopment()) {
|
|
return $this->parameters['helios']['connection']['dev'] ?? [];
|
|
}
|
|
|
|
if ($test) {
|
|
return $this->parameters['helios']['connection']['test'] ?? [];
|
|
}
|
|
|
|
return $this->parameters['helios']['connection'] ?? [];
|
|
}
|
|
|
|
public function getDocumentsUrl(): string
|
|
{
|
|
return $this->parameters['documents_url'];
|
|
}
|
|
|
|
public function getRabbitQueue(): string
|
|
{
|
|
if (isLocalDevelopment()) {
|
|
return 'wpj.Q.znz-test';
|
|
}
|
|
|
|
if (empty($this->parameters['sync']['rabbit.queue'])) {
|
|
throw new ZNZException('Missing "sync.rabbit.queue" configuration!');
|
|
}
|
|
|
|
return $this->parameters['sync']['rabbit.queue'];
|
|
}
|
|
|
|
public function getRabbitRetryStrategy(): ?RetryStrategyInterface
|
|
{
|
|
if ($this->parameters['sync']['rabbit.retry_strategy_enabled'] ?? false) {
|
|
return new MultiplierRetryStrategy(5, multiplier: 2);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function isDefaultPriceListPerWebsite(): bool
|
|
{
|
|
return $this->parameters['sync']['pricelist_per_website'] ?? false;
|
|
}
|
|
|
|
/**
|
|
* Vraci podporovanou websitu (hlavni).
|
|
*/
|
|
public function getMainWebsite(): string
|
|
{
|
|
$websites = array_keys($this->getSupportedWebsites());
|
|
|
|
return reset($websites);
|
|
}
|
|
|
|
/**
|
|
* Vraci vsechny podporovane websity (pro synchronizaci).
|
|
*/
|
|
public function getSupportedWebsites(): array
|
|
{
|
|
if (empty($this->parameters['sync']['websites'])) {
|
|
throw new ZNZException('Missing "sync.websites" configuration!');
|
|
}
|
|
|
|
return $this->parameters['sync']['websites'];
|
|
}
|
|
|
|
public function getMainWebsiteLanguage(): string
|
|
{
|
|
$website = $this->getSupportedWebsites()[$this->getMainWebsite()];
|
|
|
|
$language = $website['language'];
|
|
|
|
// jedna domena podporuje vice jazyku
|
|
if (is_array($language)) {
|
|
$language = reset($language);
|
|
}
|
|
|
|
return $language;
|
|
}
|
|
|
|
public function getWebsiteCurrency(string $website): string
|
|
{
|
|
$language = $this->getWebsiteLanguage($website);
|
|
|
|
foreach ($this->domains as $domain) {
|
|
if ($domain['language'] === $language) {
|
|
return $domain['currency'];
|
|
}
|
|
}
|
|
|
|
return Contexts::get(CurrencyContext::class)->getDefaultId();
|
|
}
|
|
|
|
public function getWebsiteLanguages(string $website): array
|
|
{
|
|
$result = $this->getSupportedWebsites()[$website]['language'] ?? $this->getMainWebsiteLanguage();
|
|
|
|
if (!is_array($result)) {
|
|
$result = [$result];
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function getWebsiteLanguage(string $website): string
|
|
{
|
|
$result = $this->getSupportedWebsites()[$website]['language'] ?? $this->getMainWebsiteLanguage();
|
|
|
|
// jedna domena podporuje vice jazyku
|
|
if (is_array($result)) {
|
|
$result = reset($result);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function getSerieRelatedTypeId(): int
|
|
{
|
|
static $serieRelatedTypeId;
|
|
|
|
if (!$serieRelatedTypeId) {
|
|
$serieRelatedTypeId = sqlQueryBuilder()
|
|
->select('id')
|
|
->from('products_related_types')
|
|
// TODO: dynamicky kvuli vice e-shopum?
|
|
->where(Operator::equals(['id' => 2]))
|
|
->execute()->fetchOne();
|
|
}
|
|
|
|
if (!$serieRelatedTypeId) {
|
|
throw new ZNZException('Product related type with ID 2 was not found!');
|
|
}
|
|
|
|
return $serieRelatedTypeId;
|
|
}
|
|
|
|
public function getExpeditionClosedDays(?\DateTimeInterface $date = null): ?int
|
|
{
|
|
$date = $date ?: new \DateTime();
|
|
$date->setTime(0, 0);
|
|
|
|
if ($expeditionClosed = ($this->getSettings()['expeditionClosed'] ?? null)) {
|
|
$dateFrom = \DateTime::createFromFormat('d.m.Y', $expeditionClosed['from'] ?? '');
|
|
$dateTo = \DateTime::createFromFormat('d.m.Y', $expeditionClosed['to'] ?? '');
|
|
if ($dateFrom && $dateTo && $date >= $dateFrom && $date <= $dateTo) {
|
|
$dateTo->setTime(0, 0);
|
|
$diff = $date->diff($dateTo);
|
|
if ($diff->days > 0) {
|
|
return $diff->days;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function getSettings(): array
|
|
{
|
|
if (!$this->synchronizationConfiguration->has('znz')) {
|
|
$this->synchronizationConfiguration->set(
|
|
'znz',
|
|
fn () => \Settings::getDefault()->loadValue('znz') ?: [],
|
|
900
|
|
);
|
|
}
|
|
|
|
return $this->synchronizationConfiguration->get('znz');
|
|
}
|
|
}
|