}
//var_dump($bouquetSpeciesForecast); die();
$noHistoryProductData = $service->calculateSpeciesForecastForProductsWithoutHistory($filters['plan_date'], $filters);
- var_dump($noHistoryProductData); die();
- $cleanedSpeciesGoals = $service->subtractSpeciesGoals($data, $bouquetSpeciesForecast, $noHistoryProductData);
+ $cleanedSpeciesGoals = $service->subtractSpeciesGoals($data, $bouquetSpeciesForecast, $noHistoryProductData);
+ //var_dump($cleanedSpeciesGoals); die();
$flatData = array_filter($cleanedSpeciesGoals, function ($row) use ($filters) {
foreach ($filters as $key => $value) {
namespace yii_app\services;
+use Yii;
use yii\db\Expression;
use yii\db\Query;
use yii\helpers\ArrayHelper;
*/
public function calculateSpeciesForecastForProductsWithoutHistory($dateFrom, $filters): array
{
+ $t0 = hrtime(true);
// Получение ID видимых магазинов
$storeIds = array_map(fn($store) => $store->id, $this->getVisibleStores());
$year = $date->format('Y');
$result = [];
+ $initTime = (hrtime(true) - $t0) / 1e6; // миллисекунды
+ Yii::warning( "Init (getVisibleStores + filters): {$initTime} ms\n");
foreach ($storeIds as $storeId) {
+ $t1 = hrtime(true);
$histResult = StorePlanService::calculateHistoricalShare(
$storeId,
$month,
$subcategory,
$species
);
+ $dur = (hrtime(true) - $t1) / 1e6;
+ Yii::warning( "calculateHistoricalShare for store {$storeId}: {$dur} ms\n");
$productsWithoutHistory = $histResult['without_history'] ?? [];
-
if (empty($productsWithoutHistory)) {
continue;
}
+ // ——————— WEIGHTED SALES ————————
+ $t2 = hrtime(true);
$weightedResults = StorePlanService::calculateWeightedSalesForProductsWithoutHistory(
- $storeId,
- $month,
- $year,
- $productsWithoutHistory
+ $storeId, $month, $year, $productsWithoutHistory
);
-
+ $dur = (hrtime(true) - $t2) / 1e6;
+ Yii::warning("calculateWeightedSalesForProductsWithoutHistory for store {$storeId}: {$dur} ms\n");
if (empty($weightedResults)) {
continue;
}
+ // ——————— COST CALCULATION ————————
+ $t3 = hrtime(true);
$costs = StorePlanService::calculateCostForProductsWithoutHistory(
$storeId, $month, $year, $weightedResults
);
+ $dur = (hrtime(true) - $t3) / 1e6;
+ Yii::warning( "calculateCostForProductsWithoutHistory for store {$storeId}: {$dur} ms\n");
if (!empty($costs)) {
$result = array_merge($result, $costs);
}
}
+ $totalTime = (hrtime(true) - $t0) / 1e6;
+ Yii::warning( "Total calculateSpeciesForecastForProductsWithoutHistory: {$totalTime} ms\n");
return $result;
}
return $mapped;
}
- public function subtractSpeciesGoals(array $data, array $forecast, array $noHistory): array {
- $forecastMap = $this->mapGoalsBySpecies($forecast);
+ public function subtractSpeciesGoals(array $data, array $bouquetForecast, array $noHistory): array {
+ $bouquetForecastMap = $this->mapGoalsBySpecies($bouquetForecast);
$noHistoryMap = $this->mapGoalsBySpecies($noHistory);
$result = [];
$species = $row['species'];
$originalGoal = $row['goal'];
- $forecastGoal = $forecastMap[$storeId][$category][$subcategory][$species] ?? 0;
+ $bouquetForecastGoal = $bouquetForecastMap[$storeId][$category][$subcategory][$species] ?? 0;
$noHistoryGoal = $noHistoryMap[$storeId][$category][$subcategory][$species] ?? 0;
- $cleanGoal = $originalGoal - $forecastGoal - $noHistoryGoal;
+ $cleanGoal = $originalGoal - ($bouquetForecastGoal + $noHistoryGoal);
$result[] = [
'category' => $category,
'subcategory' => $subcategory,
'species' => $species,
+ 'dirtyGoal' => $originalGoal,
+ 'bouquetGoal' => $bouquetForecastGoal,
+ 'noHistoryGoal' => $noHistoryGoal,
'goal' => $cleanGoal
];
}
use DateTime;
use yii\db\Expression;
+use yii\db\Query;
use yii\helpers\ArrayHelper;
use yii_app\records\BouquetComposition;
use yii_app\records\BouquetCompositionMatrixTypeHistory;
'species' => $sp,
'month' => $selectedMonth,
'year' => $selectedYear,
- 'sum' => 0.0,
+ 'goal' => 0.0,
];
}
- $accumulator[$key]['sum'] += $cost;
+ $accumulator[$key]['goal'] += $cost;
}
return array_values($accumulator);
$salesValues[] = (int)$sales;
}
+ /* $rows = (new Query())
+ ->select(['sp.product_id', 'cnt' => 'COUNT(*)'])
+ ->from(['s' => 'sales'])
+ ->innerJoin(['sp' => 'sales_products'], 's.id = sp.check_id')
+ ->where(['sp.product_id' => $similarProductIds])
+ ->andWhere(['s.store_id' => $storeId])
+ ->andWhere(['between', 's.date', $startDate . ' 00:00:00', $endDate . ' 23:59:59'])
+ ->andWhere(['not', ['s.order_id' => ['','0']]])
+ ->groupBy('sp.product_id')
+ ->indexBy('product_id')
+ ->all();*/
+
+ //var_dump($similarProductIds, $storeId, $startDate, $endDate);die();
+// $salesValues = [];
+// foreach ($similarProductIds as $id) {
+// $salesValues[] = isset($rows[$id]) ? (int)$rows[$id]['cnt'] : 0;
+// }
+
$nonZeroSales = array_filter($salesValues, function($val) {
return $val > 0;
});
['attribute' => 'category', 'label' => 'Категория'],
['attribute' => 'subcategory', 'label' => 'Подкатегория'],
['attribute' => 'species', 'label' => 'Тип'],
- ['attribute' => 'sum', 'label' => 'Сумма', 'format' => ['decimal', 2]],
+ ['attribute' => 'goal', 'label' => 'Сумма', 'format' => ['decimal', 2]],
];
['attribute' => 'category', 'label' => 'Категория'],
['attribute' => 'subcategory', 'label' => 'Подкатегория'],
['attribute' => 'species', 'label' => 'Тип'],
- ['attribute' => 'goal', 'label' => 'Сумма', 'format' => ['decimal', 2]],
+ ['attribute' => 'dirtyGoal', 'label' => 'Неочищенная цель', 'format' => ['decimal', 2]],
+ ['attribute' => 'bouquetGoal', 'label' => 'Цель букета', 'format' => ['decimal', 2]],
+ ['attribute' => 'noHistoryGoal', 'label' => 'Товары без истории', 'format' => ['decimal', 2]],
+ ['attribute' => 'goal', 'label' => 'Очищенная цель', 'format' => ['decimal', 2]],
];