From d5eeeff6801a1461691ed6e59cf06124bbb31e28 Mon Sep 17 00:00:00 2001 From: Vladimir Fomichev Date: Mon, 4 Aug 2025 17:42:30 +0300 Subject: [PATCH] =?utf8?q?=D0=9F=D0=B5=D1=80=D0=B5=D1=81=D1=87=D0=B5=D1=82?= =?utf8?q?=20=D0=B4=D0=BE=D0=BB=D0=B5=D0=B9=20=D1=82=D0=BE=D0=B2=D0=B0?= =?utf8?q?=D1=80=D0=BE=D0=B2=20=D1=81=20=D0=B8=D1=81=D1=82=D0=BE=D1=80?= =?utf8?q?=D0=B8=D0=B5=D0=B9=20=D0=B8=20=D0=B1=D0=B5=D0=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- erp24/services/AutoPlannogrammaService.php | 111 ++++++++++++++------- 1 file changed, 73 insertions(+), 38 deletions(-) diff --git a/erp24/services/AutoPlannogrammaService.php b/erp24/services/AutoPlannogrammaService.php index 01396249..39117c8c 100644 --- a/erp24/services/AutoPlannogrammaService.php +++ b/erp24/services/AutoPlannogrammaService.php @@ -1972,15 +1972,14 @@ private function buildCategoryGoals(array $rawGoals, bool $subtractMatrix, int $ { $groupedForecasts = []; - // Обработка товаров без истории foreach ($pieciesForecastProductsNoHistyory as $group) { $base = [ - 'store_id' => $group['store_id'], - 'month' => $group['month'], - 'year' => $group['year'], - 'category' => $group['category'], - 'subcategory' => $group['subcategory'], - 'species' => $group['species'], + 'store_id' => $group['store_id'], + 'month' => $group['month'], + 'year' => $group['year'], + 'category' => $group['category'], + 'subcategory'=> $group['subcategory'], + 'species' => $group['species'], ]; foreach ($group['forecasts'] as $productId => $forecast) { @@ -1990,40 +1989,64 @@ private function buildCategoryGoals(array $rawGoals, bool $subtractMatrix, int $ $groupedForecasts[$key]['meta'] = $base; $groupedForecasts[$key]['products'][$productId] = [ - 'product_id' => $productId, + 'product_id' => $productId, 'forecast_pieces' => (float)$forecast, - 'history_status' => 'No history', + 'history_status' => 'No history', ]; } } - // Обработка товаров с историей + foreach ($pieciesForecastProductWithHistory as $item) { $key = implode('|', [ $item['store_id'], $item['category'], $item['subcategory'], $item['species'] ]); $groupedForecasts[$key]['meta'] = [ - 'store_id' => $item['store_id'], - 'month' => $item['month'], - 'year' => $item['year'], - 'category' => $item['category'], - 'subcategory' => $item['subcategory'], - 'species' => $item['species'], + 'store_id' => $item['store_id'], + 'month' => $item['month'], + 'year' => $item['year'], + 'category' => $item['category'], + 'subcategory'=> $item['subcategory'], + 'species' => $item['species'], ]; $groupedForecasts[$key]['products'][$item['product_id']] = [ - 'product_id' => $item['product_id'], + 'product_id' => $item['product_id'], 'forecast_pieces' => (float)$item['forecast_pieces'], - 'history_status' => 'With history', + 'history_status' => 'With history', ]; } + + $allProductIds = []; + $allStoreIds = []; + foreach ($groupedForecasts as $group) { + $allStoreIds[] = $group['meta']['store_id']; + foreach ($group['products'] as $p) { + $allProductIds[] = $p['product_id']; + } + } + $allProductIds = array_values(array_unique($allProductIds)); + $allStoreIds = array_values(array_unique($allStoreIds)); + + $regions = CityStoreParams::find() + ->select(['store_id', 'address_region']) + ->andWhere(['store_id' => $allStoreIds]) + ->indexBy('store_id') + ->asArray() + ->all(); + + $pricesMap = self::buildPricesMap($allProductIds); + $result = []; foreach ($groupedForecasts as $group) { $meta = $group['meta']; $products = $group['products']; + $storeId = $meta['store_id']; + + $query = Products1cNomenclature::find() ->select('id') ->where(['category' => $meta['category']]) @@ -2032,41 +2055,52 @@ private function buildCategoryGoals(array $rawGoals, bool $subtractMatrix, int $ 'subcategory' => $meta['subcategory'], 'species' => $meta['species'], ]); - $allProductIds = $query->column(); - + $allIdsInNomenclature = $query->column(); - foreach ($allProductIds as $pid) { + foreach ($allIdsInNomenclature as $pid) { if (!isset($products[$pid])) { $products[$pid] = [ 'product_id' => $pid, 'forecast_pieces' => 0.0, - 'history_status' => 'No history', // или 'Missing' + 'history_status' => 'No history', ]; } } - $totalForecast = array_sum(array_column($products, 'forecast_pieces')); + $region = $regions[$storeId]['address_region'] ?? BouquetComposition::REGION_NN; - if ($totalForecast <= 0) { - foreach ($products as $p) { - $result[] = array_merge($meta, [ - 'product_id' => $p['product_id'], - 'forecast_pieces' => $p['forecast_pieces'], - 'share' => 0.0, - 'history_status' => $p['history_status'], - ]); + $productSumms = []; + foreach ($products as $p) { + $pid = $p['product_id']; + $pieces = (float)$p['forecast_pieces']; + + $price = 0.0; + if (isset($pricesMap[$pid]) && isset($pricesMap[$pid][$region]) && $pricesMap[$pid][$region] > 0) { + $price = $pricesMap[$pid][$region]; } - continue; + $productSumms[$pid] = $pieces * $price; } - foreach ($products as $product) { - $share = round($product['forecast_pieces'] / $totalForecast, 4); + $totalSumm = array_sum($productSumms); + + + foreach ($products as $p) { + $pid = $p['product_id']; + $forecastPieces = (float)$p['forecast_pieces']; + $historyStatus = $p['history_status']; + $summ = $productSumms[$pid] ?? 0.0; + + if ($totalSumm > 0) { + $share = round($summ / $totalSumm, 4); + } else { + $share = 0.0; + } $result[] = array_merge($meta, [ - 'product_id' => $product['product_id'], - 'forecast_pieces' => $product['forecast_pieces'], - 'share' => $share, - 'history_status' => $product['history_status'], + 'product_id' => $pid, + 'forecast_pieces' => $forecastPieces, + 'share' => $share, + 'history_status' => $historyStatus, ]); } } @@ -2074,6 +2108,7 @@ private function buildCategoryGoals(array $rawGoals, bool $subtractMatrix, int $ return $result; } + /** * Рассчитывает продажи по каждому товару внутри вида на основе долей и очищенной цели вида. * -- 2.39.5