From: fomichev Date: Wed, 21 May 2025 13:45:35 +0000 (+0300) Subject: Коректировки по ценам товаров без истории - расчет по неделям X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=729a0f093a688b18b46825f616cf593095569a64;p=erp24_rep%2Fyii-erp24%2F.git Коректировки по ценам товаров без истории - расчет по неделям --- diff --git a/erp24/services/StorePlanService.php b/erp24/services/StorePlanService.php index 0911a597..d660a6d3 100755 --- a/erp24/services/StorePlanService.php +++ b/erp24/services/StorePlanService.php @@ -536,6 +536,20 @@ class StorePlanService $tYear = (int)$target->format('Y'); $tMonth = (int)$target->format('m'); + $region = CityStoreParams::find() + ->where(['store_id' => $storeId]) + ->one()->address_region; + + if (!$region) { + // определяем регион по городу + $cityId = CityStore::find()->select('city_id')->where(['id' => $storeId])->scalar(); + if ($cityId == 1) { + $region = BouquetComposition::REGION_MSK; + } else { + $region = BouquetComposition::REGION_NN; + } + } + $monthStart = sprintf('%04d-%02d-01', $tYear, $tMonth); $daysInMonth = cal_days_in_month(CAL_GREGORIAN, $tMonth, $tYear); $monthEnd = sprintf('%04d-%02d-%02d', $tYear, $tMonth, $daysInMonth); @@ -543,6 +557,7 @@ class StorePlanService $priceRecords = PricesDynamic::find() ->where(['product_id' => $productId]) ->andWhere(['<=', 'date_from', $monthEnd]) + ->andWhere(['region_id' => $region]) ->andWhere([ 'or', ['>=', 'date_to', $monthStart], @@ -550,18 +565,6 @@ class StorePlanService ]) ->all(); - // определяем регион по городу - $cityId = CityStore::find()->select('city_id')->where(['id' => $storeId])->scalar(); - if ($cityId == 1342) { - $region = BouquetComposition::REGION_NN; - } elseif ($cityId == 1) { - $region = BouquetComposition::REGION_MSK; - } else { - $region = null; - } - - // ->andWhere(['or', ['region_id' => $region], ['region_id' => null]]) - if (empty($priceRecords)) { return 0.0; } @@ -578,6 +581,74 @@ class StorePlanService return $count > 0 ? ($total / $count) : 0.0; } + public static function getPriceForProductAtOffsetMonthWeekly( + string $productId, + int $year, + int $month, + int $storeId, + int $offset = 2 + ): float { + $date = new \DateTimeImmutable(sprintf('%04d-%02d-01', $year, $month)); + $target = $date->modify(sprintf('-%d months', $offset)); + $tYear = (int)$target->format('Y'); + $tMonth = (int)$target->format('m'); + + $region = CityStoreParams::find() + ->where(['store_id' => $storeId]) + ->select('address_region') + ->scalar(); + if (!$region) { + $cityId = CityStore::find()->where(['id' => $storeId])->select('city_id')->scalar(); + $region = $cityId === 1 + ? BouquetComposition::REGION_MSK + : BouquetComposition::REGION_NN; + } + + $monthStart = new \DateTimeImmutable(sprintf('%04d-%02d-01', $tYear, $tMonth)); + $daysInMonth = cal_days_in_month(CAL_GREGORIAN, $tMonth, $tYear); + $monthEnd = $monthStart->modify(sprintf('+%d days', $daysInMonth - 1)); + + $interval = new \DateInterval('P1W'); + $period = new \DatePeriod( + $monthStart, + $interval, + $monthEnd->modify('+1 day') + ); + + $weeklyAverages = []; + + foreach ($period as $weekStart) { + $potentialEnd = $weekStart->modify('+6 days'); + $weekEnd = $potentialEnd > $monthEnd ? $monthEnd : $potentialEnd; + + $priceRecords = PricesDynamic::find() + ->where(['product_id' => $productId, 'region_id' => $region]) + ->andWhere(['<=', 'date_from', $weekEnd->format('Y-m-d')]) + ->andWhere([ + 'or', + ['>=', 'date_to', $weekStart->format('Y-m-d')], + ['date_to' => '2100-01-01 03:00:00+03'] + ]) + ->all(); + + $sum = 0; $cnt = 0; + foreach ($priceRecords as $rec) { + if (isset($rec->price)) { + $sum += $rec->price; + $cnt++; + } + } + $weeklyAverages[] = $cnt > 0 ? ($sum / $cnt) : 0.0; + } + + if (empty($weeklyAverages)) { + return 0.0; + } + + // Среднее арифметическое всех недельных средних + $total = array_sum($weeklyAverages); + return $total / count($weeklyAverages); + } /** * Рассчитывает итоговые стоимости для товаров без истории, группируя суммы по @@ -605,20 +676,20 @@ class StorePlanService int $storeId, int $selectedMonth, int $selectedYear, - array $weightedProductsWithoutHistory + array $productsWithoutHistory ): array { $accumulator = []; - foreach ($weightedProductsWithoutHistory as $guid => $info) { + foreach ($productsWithoutHistory as $guid => $info) { $quantity = (float)$info; if ($quantity <= 0) { continue; } // цена за два месяца назад - $price = self::getPriceForProductAtOffsetMonth( + $price = self::getPriceForProductAtOffsetMonthWeekly( $guid, $selectedYear, $selectedMonth,