Files
kupshop/bundles/External/ZNZBundle/Util/ZNZConfiguration.php
2025-08-02 16:30:27 +02:00

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');
}
}