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',
'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) {
$finalResult[$storeId][$species] = round(array_sum($salesData), 2);
}
}
-
return [
'detail' => $resultData,
'final' => $finalResult,