]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Оптимизация метода
authorfomichev <vladimir.fomichev@erp-flowers.ru>
Fri, 16 May 2025 11:42:13 +0000 (14:42 +0300)
committerfomichev <vladimir.fomichev@erp-flowers.ru>
Fri, 16 May 2025 11:42:13 +0000 (14:42 +0300)
erp24/services/StorePlanService.php

index 4dcb214b09e755bee7abcb0880d97d13249bac97..155c7c2d0d021f95f0c1813d8711d1109e8b982b 100755 (executable)
@@ -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,