$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);
$priceRecords = PricesDynamic::find()
->where(['product_id' => $productId])
->andWhere(['<=', 'date_from', $monthEnd])
+ ->andWhere(['region_id' => $region])
->andWhere([
'or',
['>=', 'date_to', $monthStart],
])
->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;
}
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);
+ }
/**
* Рассчитывает итоговые стоимости для товаров без истории, группируя суммы по
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,