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