class MarketplaceService
{
- public static function infoForMarketplace(int $marketId, bool $is_yandex) {
+
+ private const CATEGORIES_WITH_SUBCATEGORIES = [
+ "Цветы" => [
+ "Монобукеты",
+ "Авторские букеты",
+ "Цветы в коробке",
+ "Цветы в корзине",
+ "Букеты невесты",
+ "Композиции из цветов",
+ "Мягкие игрушки",
+ "Подарочные наборы",
+ "Мишки из роз",
+ "Открытки",
+ "Стабилизированные цветы",
+ "Букеты из сухоцветов",
+ "Искусственные цветы",
+ "Цветы в ящиках",
+ "Другое",
+ "Цветы поштучно",
+ "Траурные цветы",
+ "Букеты из мыла",
+ "Цветы для интерьера",
+ ],
+ "Живые растения" => [
+ "Цветы в горшках",
+ "Флорариумы",
+ "Суккуленты, кактусы",
+ "Бонсаи",
+ "Пальмы и деревья",
+ "Левитирующие растения",
+ "Саженцы и рассада",
+ "Фитокартины",
+ "Семена",
+ "Другое",
+ "Кашпо и горшки для цветов",
+ "Наборы для выращивания",
+ "Грунты и удобрения",
+ "Аксессуары для комнатных растений",
+ "Спатифиллумы",
+ "Замиокулькасы",
+ "Антуриумы"
+ ]
+ ];
+
- if (!array_key_exists($marketId, MarketplaceStore::getWarehouseId()))
- return;
+ public static function infoForMarketplace(int $marketId) {
+ if (!array_key_exists($marketId, MarketplaceStore::getWarehouseId())) {
+ return null;
+ }
-
- $marketplacesCount = count(MarketplaceStore::getWarehouseId());
+ $is_yandex = $marketId == 2;
// 1. Получение гуидов букетов
$productsGroup = ProductsClass::find()
- ->orWhere(['ilike', 'tip', ProductsClass::MARKETPLACE])
- ->orWhere(['ilike', 'tip', ProductsClass::MARKETPLACE_ADDITIONAL])
+ ->where(['tip' => [ProductsClass::MARKETPLACE, ProductsClass::MARKETPLACE_ADDITIONAL]])
->select('category_id')
- ->asArray();
+ ->asArray()
+ ->column();
$productsGuids = Products1c::find()
- ->andWhere(['in', 'parent_id', $productsGroup])
- ->andWhere(['<>', 'components', ''])
- ->select('id')
- ->column();
+ ->where(['parent_id' => $productsGroup])
+ ->andWhere(['!=', 'components', ''])
+ ->select(['id', 'components'])
+ ->asArray()
+ ->all();
// 2. Получение цен на букеты
- // $prices = ArrayHelper::map(Prices::findAll(['product_id' => $productsGuids]), 'product_id', 'price');
- $prices = ArrayHelper::map(Prices::findAll(['product_id' => ArrayHelper::getColumn($productsGuids, 'id')]), 'product_id', 'price');
++ // $prices = ArrayHelper::map(Prices::findAll(['product_id' => ArrayHelper::getColumn($productsGuids, 'id')]), 'product_id', 'price');
+ $allPrices = Prices::findAll(['product_id' => $productsGuids]);
+ $prices = ArrayHelper::map($allPrices, 'product_id', 'price');
+
+
+ foreach ($productsGuids as $productId) {
+ if (!array_key_exists($productId, $prices)) {
+ $prices[$productId] = 0;
+ }
+ }
-
// 3. Получение состава букетов
$bouquetComposition = [];
- foreach ($productsGuids as $guid) {
- $components = Products1c::find()
- ->andWhere(['id' => $guid])
- ->select('components')
- ->column();
+ $componentsGuids = [];
+ foreach ($productsGuids as $ind => $dataComponents) {
+ $guid = $dataComponents['id'];
+ $components = $dataComponents['components'];
// Проверяем, что массив не пустой и строка валидна
- if (!empty($components) && !in_array('', $components, true)) {
- $bouquetComposition[$guid] = json_decode($components[0]); // Сохраняем компоненты
+ if (!empty($components)) {
+ $componentsJson = json_decode($components);
+ $bouquetComposition[$guid] = $componentsJson;
+ foreach ($componentsJson as $compJsonGuid => $compJsonCnt) {
+ $componentsGuids[] = $compJsonGuid;
+ }
}
}
+ $componentsGuids = array_unique($componentsGuids);
// 4. Проверка остатков
$temp = intval($values['count'] / $products->$productGuid);
$bouquetCount = !empty($bouquetCount) ? min($bouquetCount, $temp) : $temp;
$store = $values['marketplace_guid'];
- }
+
- if (isset($bouquetCount) && $bouquetCount > 0) {
+ if (!empty($stockRecords) && isset($store) && $bouquetCount > 0) {
$stocks[$guid] = ['count' => $bouquetCount, 'store' => $store];
}
+ }
+
}
// 5. Получение приоритетов
}
}
- return Json::encode($availableGuids);
+ return Json::encode($distribution);
}
+
+ /**
+ * Статический метод для получения всей информации по продуктам, которая необходима для создания фида.
+ *
+ * @return array
+ */
+ public static function getAllProductsInfo($id)
+ {
+ $parents = ProductsClass::find()
+ ->select('category_id')
+ ->orWhere(['ilike', 'tip', ProductsClass::MARKETPLACE])
+ ->orWhere(['ilike', 'tip', ProductsClass::MARKETPLACE_ADDITIONAL])
+ ->column();
+
+ $products = Products1c::find()
+ ->where(['tip' => 'products'])
+ ->andWhere(['not', ['components' => '']])
+ ->andWhere(['parent_id' => $parents])
+
+ ->all();
+
+ $count = (int)$id;
+ $selectedProducts = array_slice($products, 0, $count);
+
+ $result = [];
+
+ foreach ($selectedProducts as $product) {
+
+ $properties = MarketplaceService::getProductPropertiesByGuid($product->id);
+ if (!$properties) {
+ $message = "Товар с GUID {$product->id} не имеет свойств в MatrixErpProperty и был исключен из фида.";
+ Yii::error($message, __METHOD__);
+
+
+ InfoLogService::setInfoLog(
+ __FILE__,
+ __LINE__,
+ $message,
+ 'Missing properties error'
+ );
+ continue;
+ }
+
+ $price = MarketplaceService::getProductPrice($product->id);
+
+
+ /* if ($price == 0) {
+ $message = "У товара {$product->id} отсутствует цена и он будет исключен из фида.";
+ Yii::error($message, __METHOD__);
+
+
+ InfoLogService::setInfoLog(
+ __FILE__,
+ __LINE__,
+ $message,
+ 'Zero price error'
+ );
+ continue;
+ }*/
+
+ $components = json_decode($product->components, true);
+ $composition = [];
+
+ foreach ($components as $componentId => $quantity) {
+ $component = Products1c::findOne(['id' => $componentId]);
+ if ($component && $quantity > 0) {
+ $composition[] = [
+ 'name' => $component->name,
+ 'quantity' => $quantity,
+ 'unit' => 'шт'
+ ];
+ }
+ }
+
+ $properties = MarketplaceService::getProductPropertiesByGuid($product->id);
+
+ $result[] = [
+ 'id' => $product->id,
+ 'name' => $properties['displayName'],
+ 'pictures' => [$properties['imageUrl']],
+ 'price' => $price,
+ 'oldprice' => MarketplaceService::getProductOldPrice($product->id),
+ 'description' => MarketplaceService::getProductDescription($product->id),
+ 'qty' => MarketplaceService::getProductQty($product->id),
+ 'amount' => MarketplaceService::getProductQty($product->id),
+ 'weight' => MarketplaceService::getProductWeight($product->id),
+ 'minorder' => MarketplaceService::getProductMinOrder($product->id),
+ 'composition' => $composition,
+ 'available' => MarketplaceService::getProductAvailability($product->id),
+ 'category_id' => MarketplaceService::getProductCategory($product->id),
+ 'category_name' => $properties['flowwowSubcategory'],
+ 'params' => MarketplaceService::getProductParams($product->id),
+ 'productLink' => MarketplaceService::getProductLinkByGuid($product->id),
+ ];
+ }
+
+ return $result;
+ }
+
+
+ /**
+ * Статический метод для создания XML-фида на основе информации о продуктах.
+ *
+ * @param array $productsInfo
+ * @return string
+ */
+ public static function createXMLFeed($productsInfo)
+ {
+ $xml = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><yml_catalog/>');
+ $xml->addAttribute('date', date('Y-m-d H:i'));
+
+ $shop = $xml->addChild('shop');
+ $shop->addChild('name', 'Интернет магазин База Цветов 24');
+ $shop->addChild('company', 'Интернет магазин База Цветов 24');
+ $shop->addChild('url', 'https://bazacvetov24.ru');
+ $shop->addChild('platform', 'BSM/Yandex/Market');
+
+ // Добавление валюты
+ $currencies = $shop->addChild('currencies');
+ $currency = $currencies->addChild('currency');
+ $currency->addAttribute('id', 'RUB');
+ $currency->addAttribute('rate', '1');
+
+ // Добавление категорий (пример добавления нескольких категорий)
+ $uniqueCategories = [];
+ foreach ($productsInfo as $product) {
+ $categoryId = $product['category_id'];
+ $categoryName = $product['category_name'];
+
+
+ if (!isset($uniqueCategories[$categoryId])) {
+ $uniqueCategories[$categoryId] = $categoryName;
+ }
+ }
+
+
+ $categories = $shop->addChild('categories');
+ foreach ($uniqueCategories as $id => $name) {
+ $category = $categories->addChild('category', $name);
+ $category->addAttribute('id', $id);
+ }
+
+ // Добавление офферов (продуктов)
+ $offers = $shop->addChild('offers');
+ foreach ($productsInfo as $product) {
+ $offer = $offers->addChild('offer');
+ $offer->addAttribute('id', $product['id']);
+ $offer->addAttribute('available', $product['available'] ? 'true' : 'false');
+
+ // Добавление URL продукта
+ $offer->addChild('url', $product['productLink']);
+
+ // Добавление цены и валюты
+ $offer->addChild('price', $product['price']);
+ $offer->addChild('oldPrice', $product['oldprice']);
+ $offer->addChild('currencyId', 'RUB');
+ $offer->addChild('categoryId', $product['category_id']);
+
+ // Добавление доступности доставки
+ $offer->addChild('delivery', 'true');
+
+ // Описание продукта
+ if (!empty($product['description'])) {
+ $offer->addChild('description', $product['description']);
+ }
+
+ // Добавление веса и количества
+ $offer->addChild('weight', $product['weight']);
+ // $offer->addChild('qty', $product['qty']);
+ // $offer->addChild('amount', $product['amount']);
+ // $offer->addChild('cost', $product['amount']);
+
+ foreach ($product['composition'] as $component) {
+ $consist = $offer->addChild('consist', $component['quantity']);
+ $consist->addAttribute('name', $component['name']);
+ $consist->addAttribute('unit', $component['unit']);
+ // $consist->addAttribute('cost', 12);
+ }
+
+ // Добавление параметров
+ if (!empty($product['params'])) {
+ foreach ($product['params'] as $paramName => $paramValue) {
+ $param = $offer->addChild('param', $paramValue);
+ $param->addAttribute('name', $paramName);
+ }
+ }
+
+ // Название продукта
+ $offer->addChild('name', $product['name']);
+
+ // Добавление изображений продукта
+ if (!empty($product['pictures'])) {
+ foreach ($product['pictures'] as $picture) {
+ $offer->addChild('picture', $picture);
+ }
+ }
+ }
+
+ return $xml->asXML();
+ }
+
+
+ private static function getProductPropertiesByGuid($guid) {
+ $product = MatrixErpProperty::find()
+ ->where(['guid' => $guid])
+ ->one();
+
+ if (!$product) {
+ return null;
+ }
+
+ return [
+ 'id' => $product->id,
+ 'description' => $product->description,
+ 'imageUrl' => self::getProductImageUrl($product->image_id),
+ 'date' => $product->date,
+ 'displayName' => $product->display_name,
+ 'externalImageUrl' => $product->external_image_url,
+ 'productUrl' => $product->product_url,
+ 'flowwowCategory' => $product->flowwow_category,
+ 'flowwowSubcategory' => $product->flowwow_subcategory,
+ ];
+ }
+
+ private static function getProductImageUrl($imageId) {
+ $image = Images::findOne($imageId);
+ $fileName = '';
+ if ($image && File::src($image->filename, 'images') != null) {
+ $fileName = File::src($image->filename, 'images');
+ return 'https://media.dev.erp-flowers.ru/media/view-url?url=' . $fileName;
+ }
+
+
+ return null;
+ }
+ private static function getProductLinkByGuid($guid) {
+ return 'https://media.dev.erp-flowers.ru/media/view-card?guid=' . urlencode($guid);
+ }
+
+ private static function getProductPrice($productId) {
+ $price = Prices::find()
+ ->where(['product_id' => $productId])
+ ->one();
+ return $price['price'] ?? 0;
+ }
+ private static function getProductOldPrice($productId) { return 300; }
+ private static function getProductDescription($productId) {
+
+ $product = MatrixErpProperty::find()
+ ->where(['guid' => $productId])
+ ->one();
+
+ if (!$product) {
+ return null; // Вернуть null, если продукт не найден
+ }
+
+ return $product->description;
+ }
+ private static function getProductQty($productId) { return 9; }
+ private static function getProductWeight($productId) {
+ return 0.5;
+ }
+ private static function getProductCategory($productId) {
+
+ $product = MatrixErpProperty::find()
+ ->where(['guid' => $productId])
+ ->one();
+
+ if (!$product) {
+ return null;
+ }
+
+ return self::getCategorySubcategoryId($product->flowwow_category, $product->flowwow_subcategory);
+ }
+
+ public static function getCategorySubcategoryId($category, $subcategory)
+ {
+ $categories = self::CATEGORIES_WITH_SUBCATEGORIES;
+
+ if (!array_key_exists($category, $categories)) {
+ return null;
+ }
+
+ $categoryIndex = array_search($category, array_keys($categories)) + 1;
+ $subcategoryIndex = array_search($subcategory, $categories[$category]) + 1;
+
+ if ($subcategoryIndex === false) {
+ return null;
+ }
+
+
+ return (string)$categoryIndex . (string)$subcategoryIndex;
+ }
+
+ private static function getProductMinOrder($productId) {
+ return 1;
+ }
+ private static function getProductAvailability($productId) {
+ return true;
+ }
+
+ private static function getProductMaterial($productId)
+ {
+ // Здесь можно реализовать логику получения материала продукта
+ return 'Цветы'; // Пример значения
+ }
+
+ private static function getProductWidth($productId)
+ {
+ // Здесь можно реализовать логику получения ширины продукта
+ return 18; // Пример значения
+ }
+
+ private static function getProductHeight($productId)
+ {
+ // Здесь можно реализовать логику получения высоты продукта
+ return 20; // Пример значения
+ }
+
+ private static function getProductLength($productId)
+ {
+ // Здесь можно реализовать логику получения длины продукта
+ return 9; // Пример значения
+ }
+
+ private static function getProductParams($productId)
+ {
+ return [
+
+ 'Ширина, См' => self::getProductWidth($productId),
+ 'Высота, См' => self::getProductHeight($productId),
+
+ ];
+ }
+
+
+
}