getStores(); $qb->andWhere('1'); // quantity decrement - vyselectuje skladovost externich skladu, aby se mohla odecist od celkoveho mnozstvi skladem $quantityDecrementQb = static::getQuantityDecrementQueryBuilder(); $qb->addQueryBuilderParameters($quantityDecrementQb); foreach ($stores as $key => $store) { if ($selectedStores && !in_array($key, $selectedStores)) { continue; } $table_alias = 'si'.$key; // prepare base sub query $subQuery = sqlQueryBuilder() // temporary fix of mariadb bug - use index ->from('stores_items', $table_alias.' USE INDEX (stores_items_products_id_fk)') ->where("{$table_alias}.id_product = p.id AND {$table_alias}.id_variation <=> pv.id AND {$table_alias}.id_store = {$key}"); // add sub query select /* * Na detailu produktu se ovečkárně přestala zobrazovat dostupnost pouze na prodejně. * Při příchodu na detail produktu není vybrána varianta a ve StoresQuery addStoresInStoreAmounts se nezobrazuje celkový součet napříč všech variant. * Nevěděli jsme, proč bylo: $qb->addSubselect($subQuery->select("SUM(COALESCE({$table_alias}.quantity, 0))"), "store{$key}_in_store"); */ if ($addQuantity) { $qb->addSubselect($subQuery->select("COALESCE(SUM({$table_alias}.quantity), 0)"), "store{$key}_in_store"); } if ($addMinQuantity) { $qb->addSubselect($subQuery->select("COALESCE({$table_alias}.min_quantity, 0)"), "store{$key}_min_in_store"); } } }; } public static function filterByStoresInStore(array $storeIds): callable { return function (QueryBuilder $qb) use ($storeIds) { $qb->joinVariationsOnProducts(); $filterSpecs = []; foreach ($storeIds as $storeId) { $existsSubQuery = sqlQueryBuilder() ->select('si_filter.id') ->from('stores_items', 'si_filter') ->andWhere( Operator::andX( 'si_filter.id_product = p.id AND pv.id <=> si_filter.id_variation', Operator::equals(['si_filter.id_store' => $storeId]), 'si_filter.quantity > 0' ) ); $filterSpecs[] = Operator::exists($existsSubQuery); } return Operator::orX($filterSpecs); }; } public static function filterOrdersByStoreDelivery(int $id_store): callable { return function (QueryBuilder $qb) use ($id_store) { $delivery_operator = 'false'; if ($store = ServiceContainer::getService(StoresInStore::class)->getStores()[$id_store] ?? null) { $id_delivery = $store['id_delivery']; if ($id_delivery) { $id_delivery_types = sqlFetchAll(sqlQueryBuilder()->select('id')->from('delivery_type') ->andWhere(Operator::equals(['id_delivery' => $id_delivery]))->execute(), ['id' => 'id']); $delivery_operator = Operator::inIntArray($id_delivery_types, 'o.id_delivery'); } elseif ($store['type'] == StoresInStore::TYPE_MAIN_STORE) { $id_delivery = array_filter(array_column(ServiceContainer::getService(StoresInStore::class)->getStores(), 'id_delivery')); if ($id_delivery) { $id_delivery_types = sqlFetchAll(sqlQueryBuilder()->select('id')->from('delivery_type') ->andWhere(Operator::inIntArray($id_delivery, 'id_delivery'))->execute(), ['id' => 'id']); $delivery_operator = Operator::not(Operator::inIntArray($id_delivery_types, 'o.id_delivery')); } } } $qb->andWhere($delivery_operator); }; } private static function getQuantityDecrementQueryBuilder(): QueryBuilder { return sqlQueryBuilder() ->select('COALESCE(SUM(quantity), 0)') ->from('stores_items USE INDEX(stores_items_products_id_fk)') ->where('id_product = p.id AND id_variation <=> pv.id AND id_store IN (SELECT id FROM stores WHERE type != :externalStoreType)') ->setParameter('externalStoreType', StoresInStore::TYPE_EXTERNAL_STORE); } }