220 lines
7.6 KiB
PHP
220 lines
7.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace External\ZNZBundle\Synchronizers;
|
|
|
|
use External\ZNZBundle\Exception\ZNZException;
|
|
use KupShop\KupShopBundle\Util\Database\QueryHint;
|
|
use KupShop\StoresBundle\Utils\StoresInStore;
|
|
use KupShop\SynchronizationBundle\Exception\RabbitRetryMessageException;
|
|
use Query\Operator;
|
|
|
|
class SupplySynchronizer extends BaseSynchronizer
|
|
{
|
|
public static string $typeItems = 'stores_item';
|
|
|
|
protected static string $type = 'supply';
|
|
protected static bool $logging = false;
|
|
|
|
/** @required */
|
|
public StoresInStore $storesInStore;
|
|
|
|
public static function getHandledTables(): array
|
|
{
|
|
return [
|
|
'ProduktDostupnost' => 'processSupplyItem',
|
|
];
|
|
}
|
|
|
|
public static function getIdField(): ?string
|
|
{
|
|
return 'IdProdukt';
|
|
}
|
|
|
|
public function processSupplyItem(array $item): void
|
|
{
|
|
if ($this->isDeleteMessage($item) && !empty($item['meta']['unique_id'])) {
|
|
$parts = explode('-', $item['meta']['unique_id']);
|
|
$item['IdProdukt'] = (int) $parts[0];
|
|
$item['IdSklad'] = $parts[1] ?? null;
|
|
}
|
|
|
|
if (!$this->isDeleteMessage($item) && !$this->isMessageWithStoreRequiredValid($item)) {
|
|
return;
|
|
}
|
|
|
|
[$productId, $variationId] = $this->znzUtil->getProductMapping($item['IdProdukt']);
|
|
if (!$productId) {
|
|
throw new RabbitRetryMessageException();
|
|
}
|
|
|
|
if (!empty($item['IdSklad'])) {
|
|
$variationId = $this->znzUtil->getProductVariationIdWithStoreCheck($productId, $variationId, $item['IdSklad'] ?? null);
|
|
}
|
|
|
|
if (!$variationId && $this->hasProductVariations($productId)) {
|
|
throw new ZNZException(
|
|
sprintf('Invalid stock data for product "%s" (%s): trying to update product stock while the product has variations', $item['IdProdukt'], $productId)
|
|
);
|
|
}
|
|
|
|
// pokud prijde delete, tak nastavim sklad na 0
|
|
if ($this->isDeleteMessage($item)) {
|
|
// pokud neprislo IdSklad, tak smaznu vsechnu skladovost konkretniho produktu
|
|
if (empty($item['IdSklad'])) {
|
|
sqlQueryBuilder()
|
|
->delete('stores_items')
|
|
->where(Operator::equalsNullable(
|
|
[
|
|
'id_product' => $productId,
|
|
'id_variation' => $variationId,
|
|
]
|
|
))->execute();
|
|
|
|
return;
|
|
}
|
|
|
|
$item['Dostupnost'] = 0;
|
|
}
|
|
|
|
$maxId = $this->znzUtil->getZNZMaxId((int) $item['IdProdukt'], 'ProduktDostupnost', $item['IdSklad']);
|
|
// je to stara zmena, ktera nas uz nezajima, protoze mame novejsi data
|
|
if ($maxId && $maxId >= $item['meta']['id_change']) {
|
|
return;
|
|
}
|
|
|
|
QueryHint::withRouteToMaster(function () use ($item, $productId, $variationId) {
|
|
// vytvorim si mapping, ke kteremu bude ukladat data o moznosti objednani od dodavatele
|
|
if (!$this->isDeleteMessage($item) && !$this->znzUtil->getMapping(static::$typeItems, $item['IdPorovnej'])) {
|
|
$this->znzUtil->createMapping(
|
|
static::$typeItems,
|
|
$item['IdPorovnej'],
|
|
$this->getStoreItemId(
|
|
$this->getStoreId($item['IdSklad']),
|
|
$productId,
|
|
$variationId
|
|
)
|
|
);
|
|
}
|
|
|
|
// aktualizuju skladovou zasobu
|
|
$this->storesInStore->updateStoreItem(
|
|
[
|
|
'id_store' => $this->getStoreId($item['IdSklad']),
|
|
'id_product' => $productId,
|
|
'id_variation' => $variationId,
|
|
'quantity' => $item['Dostupnost'],
|
|
],
|
|
false
|
|
);
|
|
});
|
|
|
|
$this->znzUtil->updateZNZMaxId((int) $item['IdProdukt'], 'ProduktDostupnost', $item['IdSklad'], $item['meta']['id_change']);
|
|
|
|
// pokud je to delete, tak chci prepocitat sklad hned, at tam treba nezustava posledni kus 5 minut nez se spusti prepocet skladu
|
|
if ($item['Dostupnost'] <= 0) {
|
|
$this->znzUtil->recalculateStores(productIds: [$productId], withVariationsInStoreRecalculate: false);
|
|
}
|
|
|
|
if (!$this->isDeleteMessage($item)) {
|
|
$supplierData = [];
|
|
if (!empty($item['DobaDodani']) && !empty($item['PrahObjednani']) && !empty($item['ZemeObjednani'])) {
|
|
$supplierData = [
|
|
'dobaDodani' => $item['DobaDodani'],
|
|
'prahObjednani' => $item['PrahObjednani'],
|
|
'zemeObjednani' => $item['ZemeObjednani'],
|
|
'dnyVTydnu' => $item['DnyVTydnu'],
|
|
];
|
|
}
|
|
|
|
sqlQueryBuilder()
|
|
->update('znz_stores_items')
|
|
->directValues(['data' => json_encode(['supplier' => $supplierData])])
|
|
->where(Operator::equals(['id_znz' => $item['IdPorovnej']]))
|
|
->execute();
|
|
}
|
|
}
|
|
|
|
private function hasProductVariations(int $productId): bool
|
|
{
|
|
static $hasVariationsCache = [];
|
|
|
|
if (($hasVariationsCache[$productId] ?? null) !== null) {
|
|
return $hasVariationsCache[$productId];
|
|
}
|
|
|
|
$variationId = sqlQueryBuilder()
|
|
->select('id')
|
|
->from('products_variations')
|
|
->where(Operator::equals(['id_product' => $productId]))
|
|
->execute()->fetchOne();
|
|
|
|
return $hasVariationsCache[$productId] = (bool) $variationId;
|
|
}
|
|
|
|
private function getStoreItemId(int $storeId, int $productId, ?int $variationId): int
|
|
{
|
|
$storeItemId = sqlQueryBuilder()
|
|
->select('id')
|
|
->from('stores_items')
|
|
->andWhere(Operator::equalsNullable(
|
|
[
|
|
'id_product' => $productId,
|
|
'id_variation' => $variationId,
|
|
'id_store' => $storeId,
|
|
])
|
|
)
|
|
->execute()
|
|
->fetchOne();
|
|
|
|
if (!$storeItemId) {
|
|
$storeItemId = sqlGetConnection()->transactional(function () use ($storeId, $productId, $variationId) {
|
|
sqlQueryBuilder()
|
|
->insert('stores_items')
|
|
->directValues(
|
|
[
|
|
'id_store' => $storeId,
|
|
'id_product' => $productId,
|
|
'id_variation' => $variationId,
|
|
'quantity' => 0,
|
|
]
|
|
)
|
|
->execute();
|
|
|
|
return (int) sqlInsertId();
|
|
});
|
|
}
|
|
|
|
return $storeItemId;
|
|
}
|
|
|
|
private function getStoreId(string $znzId): int
|
|
{
|
|
static $storesCache = [];
|
|
|
|
if (!($storesCache[$znzId] ?? false)) {
|
|
if (!($storeId = $this->znzUtil->getMapping('store', $znzId))) {
|
|
$storeId = sqlGetConnection()->transactional(function () use ($znzId) {
|
|
sqlQueryBuilder()
|
|
->insert('stores')
|
|
->directValues(
|
|
[
|
|
'name' => $znzId,
|
|
'figure' => 'N',
|
|
]
|
|
)->execute();
|
|
|
|
return (int) sqlInsertId();
|
|
});
|
|
|
|
$this->znzUtil->createMapping('store', $znzId, $storeId);
|
|
}
|
|
|
|
$storesCache[$znzId] = $storeId;
|
|
}
|
|
|
|
return $storesCache[$znzId];
|
|
}
|
|
}
|