From 0a2813570e76d3470695ab8ef2a8419a361c4b7a Mon Sep 17 00:00:00 2001 From: fomichev Date: Fri, 16 May 2025 14:42:13 +0300 Subject: [PATCH] =?utf8?q?=D0=9E=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0?= =?utf8?q?=D1=86=D0=B8=D1=8F=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- erp24/services/StorePlanService.php | 209 +++++++++++++--------------- 1 file changed, 98 insertions(+), 111 deletions(-) diff --git a/erp24/services/StorePlanService.php b/erp24/services/StorePlanService.php index 4dcb214b..155c7c2d 100755 --- a/erp24/services/StorePlanService.php +++ b/erp24/services/StorePlanService.php @@ -913,20 +913,16 @@ class StorePlanService public static function getBouquetSpiecesMonthGoalFromForecast($month, $year, $storeId = null, $matrixGroups = []) { - $stores = []; - $forecasts = []; - if (!empty($storeId)) { - $stores[] = $storeId; - } else { - $stores = ArrayHelper::getColumn( - CityStore::find() - ->select(['id']) - ->where(['visible' => CityStore::IS_VISIBLE]) - ->asArray() - ->all(), - 'id' - ); + $stores = $storeId ? [$storeId] : ArrayHelper::getColumn( + CityStore::find()->select(['id'])->where(['visible' => CityStore::IS_VISIBLE])->asArray()->all(), + 'id' + ); + + if (empty($matrixGroups)) { + return ['detail' => [], 'final' => [], 'debug' => []]; } + + // Типы продаж $types = [ 's_store' => 'offline', 'm_store' => 'offline', @@ -935,130 +931,122 @@ class StorePlanService 'marketplace' => 'marketplace', 'internet' => 'online' ]; + $storeSizeTypes = [1 => 's_store', 2 => 'm_store', 3 => 'l_store', 4 => 'xl_store']; - $storeSizeTypes = [ - 1 => 's_store', - 2 => 'm_store', - 3 => 'l_store', - 4 => 'xl_store', - ]; - // var_dump($stores); die(); - $storesParams = CityStoreParams::find() + $storeParams = CityStoreParams::find() ->select(['store_id', 'address_region', 'store_type']) ->where(['store_id' => $stores]) - ->andWhere(['not', ['address_region' => '']]) - ->asArray() + //->andWhere(['not', ['address_region' => '']]) ->indexBy('store_id') + ->asArray() ->all(); + $storeCities = ArrayHelper::map( + CityStore::find()->select(['id', 'city_id'])->where(['id' => $stores])->asArray()->all(), + 'id', + 'city_id' + ); + $resultData = []; $debugData = []; - if (!empty($matrixGroups)) { - foreach ($matrixGroups as $matrixGroup) { - $forecasts = MatrixBouquetForecast::find() - ->where(['year' => $year, 'month' => $month]) - ->andWhere(['not', ['guid' => null]]) - ->andWhere(['group' => $matrixGroup]) - ->asArray() - ->all(); - foreach ($forecasts as $forecast) { - $products = []; - - $product = Products1c::find() - ->select(['components']) - ->where(['id' => $forecast['guid']]) - ->asArray() - ->one(); - - if ($product && !empty($product['components'])) { - $components = json_decode($product['components'], true); - if (is_array($components)) { - foreach ($components as $productId => $count) { - $products[] = [ - 'product_guid' => $productId, - 'count' => (float)$count, - ]; - } + $priceCache = []; + $speciesCache = []; + + foreach ($matrixGroups as $matrixGroup) { + $forecasts = MatrixBouquetForecast::find() + ->where(['year' => $year, 'month' => $month]) + ->andWhere(['group' => $matrixGroup]) + ->andWhere(['not', ['guid' => null]]) + ->asArray() + ->all(); + + $guidList = array_column($forecasts, 'guid'); + $productComponents = Products1c::find() + ->select(['id', 'components']) + ->where(['id' => $guidList]) + ->indexBy('id') + ->asArray() + ->all(); + $allGuids = []; + foreach ($productComponents as $comp) { + if ($json = $comp['components']) { + $decoded = @json_decode($json,true); + if (json_last_error()===JSON_ERROR_NONE) { + $allGuids = array_merge($allGuids, array_keys($decoded)); + } + } + } + $speciesCache = Products1cNomenclature::find() + ->select(['id','species']) + ->where(['id'=>array_unique($allGuids)]) + ->indexBy('id')->asArray()->all(); + foreach ($forecasts as $forecast) { + $products = []; + $json = $productComponents[$forecast['guid']]['components'] ?? null; + if ($json) { + $decoded = json_decode($json, true); + if (json_last_error() === JSON_ERROR_NONE) { + foreach ($decoded as $guid => $count) { + $products[] = ['product_guid' => $guid, 'count' => (float)$count]; } } + } - $productGuids = array_filter(array_column($products, 'product_guid')); - - - + $productGuids = array_column($products, 'product_guid'); + foreach ($types as $field => $typeSales) { + $typeSalesValue = (int)$forecast[$field]; + if ($typeSalesValue <= 0) continue; - foreach ($storesParams as $storeId => $params) { - // var_dump($storesParams);die(); - foreach ($types as $field => $typeSales) { + foreach ($storeParams as $sid => $params) { + if ($typeSales === 'offline' && ($storeSizeTypes[$params['store_type']] ?? null) !== $field) { + continue; + } - $typeSalesValue = (int)$forecast[$field]; - if ($typeSalesValue <= 0) { - continue; - } - } - $regionId = $params['address_region']; - if (!$regionId) { - if (CityStore::find()->where(['id' => $storeId])->one()->city_id == 1342) { - $regionId = 52; - } elseif (CityStore::find()->where(['id' => $storeId])->one()->city_id == 1) { - $regionId = 77; - } else { - $regionId = 52; - } - } + $regionId = $params['address_region'] ?: match ($storeCities[$sid] ?? null) { + 1342 => 52, + 1 => 77, + default => 52, + }; - $pricesData = ArrayHelper::map( + $priceKey = $regionId . ':' . md5(implode(',', $productGuids)); + if (!isset($priceCache[$priceKey])) { + $priceCache[$priceKey] = ArrayHelper::map( PricesDynamic::find() - ->where(['product_id' => $productGuids]) - ->andWhere(['active' => 1]) - ->andWhere(['region_id' => $regionId]) ->select(['price', 'product_id']) + ->where(['product_id' => $productGuids]) + ->andWhere(['active' => 1, 'region_id' => $regionId]) ->asArray() ->all(), 'product_id', 'price' ); - - foreach ($products as $product) { - $productModel = Products1cNomenclature::findOne($product['product_guid']); - $species = $productModel?->species ?? 'Неизвестно'; - $basePrice = $pricesData[$product['product_guid']] ?? 0; - $rawCalculation = $basePrice * $product['count'] * $typeSalesValue; - $productCost = round($rawCalculation * 1.15, 2); - - if (!isset($resultData[$storeId][$species][$typeSales])) { - $resultData[$storeId][$species][$typeSales] = 0; - } - $resultData[$storeId][$species][$typeSales] += $productCost; - - $debugData[$storeId][$species][$typeSales][] = [ - 'product_guid' => $product['product_guid'], - 'price' => $basePrice, - 'count' => $product['count'], - 'forecast' => $typeSalesValue, - 'guid' => $forecast['guid'], - 'raw_calculation' => $rawCalculation, - 'rounded' => $productCost, - ]; - } } - + $prices = $priceCache[$priceKey]; + + foreach ($products as $product) { + $guid = $product['product_guid']; + $species = $speciesCache[$guid]['species'] ?? 'Неизвестно'; + $price = $prices[$guid] ?? 0; + $raw = $price * $product['count'] * $typeSalesValue; + $cost = round($raw * 1.15, 2); + + $resultData[$sid][$species][$typeSales] = ($resultData[$sid][$species][$typeSales] ?? 0) + $cost; + $debugData[$sid][$species][$typeSales][] = [ + 'product_guid' => $guid, + 'price' => $price, + 'count' => $product['count'], + 'forecast' => $typeSalesValue, + 'guid' => $forecast['guid'], + 'raw_calculation' => $raw, + 'rounded' => $cost, + ]; + } + } } } - } else { - return [ - 'detail' => [], - 'final' => [], - 'debug' => [] - ]; } - // var_dump($forecasts); die(); - - // var_dump( $forecasts); die(); - - $finalResult = []; foreach ($resultData as $storeId => $speciesData) { @@ -1066,7 +1054,6 @@ class StorePlanService $finalResult[$storeId][$species] = round(array_sum($salesData), 2); } } - return [ 'detail' => $resultData, 'final' => $finalResult, -- 2.39.5