From: Vladimir Fomichev Date: Wed, 21 May 2025 07:55:12 +0000 (+0300) Subject: 9 шаг X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=f44f623fb019363ca43ef0492606e97d600230f6;p=erp24_rep%2Fyii-erp24%2F.git 9 шаг --- diff --git a/erp24/controllers/AutoPlannogrammaController.php b/erp24/controllers/AutoPlannogrammaController.php index c96a8fa1..e6410cdb 100644 --- a/erp24/controllers/AutoPlannogrammaController.php +++ b/erp24/controllers/AutoPlannogrammaController.php @@ -568,14 +568,21 @@ class AutoPlannogrammaController extends BaseController $matrixGroups = array_unique(ArrayHelper::getColumn($matrixForecast, 'group')); $bouquetForecast = StorePlanService::getBouquetSpiecesMonthGoalFromForecast($filters['month'], $filters['year'], $filters['store_id'], $matrixGroups); $speciesData = $bouquetForecast['final']; - foreach ($speciesData as $store_id => $species) { - foreach ($species as $specieInd => $row) { - $bouquetSpeciesForecast[] = [ - 'store_id' => $store_id, - 'species' => $specieInd, - 'goal' => $row - ]; + foreach ($speciesData as $store_id => $categoryData) { + foreach ($categoryData as $category => $subcategoryData) { + foreach ($subcategoryData as $subcategory => $species) { + foreach ($species as $speciesInd => $row) { + $bouquetSpeciesForecast[] = [ + 'category' => $category, + 'subcategory' => $subcategory, + 'store_id' => $store_id, + 'species' => $speciesInd, + 'goal' => $row + ]; + } + } } + } //var_dump($matrixGroups); die(); $flatData = array_filter($bouquetSpeciesForecast, function ($row) use ($filters) { @@ -652,4 +659,99 @@ class AutoPlannogrammaController extends BaseController 'filters' => $filters, ]); } + + + public function action9() + { + $request = Yii::$app->request; + + $filters = [ + 'category' => $request->get('category'), + 'subcategory' => $request->get('subcategory') ?? null, + 'species' => $request->get('species') ?? null, + 'store_id' => $request->get('store_id') ?? [], + 'year' => $request->get('year'), + 'month' => $request->get('month'), + 'type' => $request->get('type'), + ]; + + $dataProvider = new ArrayDataProvider([ + 'allModels' => [], + 'pagination' => ['pageSize' => 100], + ]); + + $bouquetSpeciesForecast = []; + // Обработка даты на год и месяц + if (!empty($filters['year']) && !empty($filters['month'])) { + $filters['plan_date'] = $filters['year'] . '-' . str_pad($filters['month'], 2, '0', STR_PAD_LEFT) . '-01'; + //var_dump($filters); die(); + $service = new AutoPlannogrammaService(); + $monthCategoryShare = $service->getMonthCategoryShareOrWriteOff($filters['plan_date'], $filters); + $monthCategoryGoal = $service->getMonthCategoryGoal($monthCategoryShare, $filters['plan_date']); + $monthSubcategoryShare = $service->getMonthSubcategoryShareOrWriteOff($filters['plan_date'], $filters); + $monthSubcategoryGoal = $service->getMonthSubcategoryGoal($monthSubcategoryShare, $monthCategoryGoal); + $monthSpeciesShare = $service->getMonthSpeciesShareOrWriteOff($filters['plan_date'], $filters); + $data = $service->getMonthSpeciesGoalDirty($monthSpeciesShare, $monthSubcategoryGoal); + + if ($filters['type'] == AutoPlannogrammaService::TYPE_WRITE_OFFS) { + $monthCategoryWriteOffsShare = $service->getMonthCategoryShareOrWriteOff($filters['plan_date'], $filters, $filters['type']); + $monthCategoryWriteOffsGoal = $service->getMonthCategoryGoal($monthCategoryWriteOffsShare, $filters['plan_date'], $filters['type']); + $monthSubcategoryWriteOffsShare = $service->getMonthSubcategoryShareOrWriteOff($filters['plan_date'], $filters, $filters['type']); + $monthSubcategoryWriteOffsGoals = $service->getMonthSubcategoryGoal($monthSubcategoryWriteOffsShare, $monthCategoryWriteOffsGoal, $filters['type']); + $monthSpeciesWriteOffShare = $service->getMonthSpeciesShareOrWriteOff($filters['plan_date'], $filters, $filters['type']); + $data = $service->getMonthSpeciesGoalDirty($monthSpeciesWriteOffShare, $monthSubcategoryWriteOffsGoals, $filters['type'], $data); + } + + //var_dump($data); die(); + $matrixForecast = MatrixBouquetForecast::find() + ->where(['year' => $filters['year'], 'month' => $filters['month']]) + ->asArray() + ->all(); + $matrixGroups = array_unique(ArrayHelper::getColumn($matrixForecast, 'group')); + $bouquetForecast = StorePlanService::getBouquetSpiecesMonthGoalFromForecast($filters['month'], $filters['year'], $filters['store_id'], $matrixGroups); + $speciesData = $bouquetForecast['final']; + foreach ($speciesData as $store_id => $categoryData) { + foreach ($categoryData as $category => $subcategoryData) { + foreach ($subcategoryData as $subcategory => $species) { + foreach ($species as $speciesInd => $row) { + $bouquetSpeciesForecast[] = [ + 'category' => $category, + 'subcategory' => $subcategory, + 'store_id' => $store_id, + 'species' => $speciesInd, + 'goal' => $row + ]; + } + } + } + + } + //var_dump($bouquetSpeciesForecast); die(); + $noHistoryProductData = $service->calculateSpeciesForecastForProductsWithoutHistory($filters['plan_date'], $filters); + var_dump($noHistoryProductData); die(); + $cleanedSpeciesGoals = $service->subtractSpeciesGoals($data, $bouquetSpeciesForecast, $noHistoryProductData); + + + $flatData = array_filter($cleanedSpeciesGoals, function ($row) use ($filters) { + foreach ($filters as $key => $value) { + if (empty($value)) continue; + if (!isset($row[$key])) continue; + + if (stripos((string)$row[$key], (string)$value) === false) { + return false; + } + } + return true; + }); + + $dataProvider = new ArrayDataProvider([ + 'allModels' => $flatData, + 'pagination' => ['pageSize' => 100], + ]); + } + return $this->render('9', [ + 'dataProvider' => $dataProvider, + 'filters' => $filters, + ]); + } } diff --git a/erp24/services/AutoPlannogrammaService.php b/erp24/services/AutoPlannogrammaService.php index 28709a9e..e41516a5 100644 --- a/erp24/services/AutoPlannogrammaService.php +++ b/erp24/services/AutoPlannogrammaService.php @@ -621,5 +621,44 @@ class AutoPlannogrammaService return $result; } + public function mapGoalsBySpecies(array $rows): array { + $mapped = []; + foreach ($rows as $row) { + $mapped[$row['store_id']][$row['category']][$row['subcategory']][$row['species']] = $row['goal']; + } + return $mapped; + } + + public function subtractSpeciesGoals(array $data, array $forecast, array $noHistory): array { + $forecastMap = $this->mapGoalsBySpecies($forecast); + $noHistoryMap = $this->mapGoalsBySpecies($noHistory); + $result = []; + + foreach ($data as $row) { + $storeId = $row['store_id']; + $category = $row['category']; + $subcategory = $row['subcategory']; + $species = $row['species']; + $originalGoal = $row['goal']; + + $forecastGoal = $forecastMap[$storeId][$category][$subcategory][$species] ?? 0; + $noHistoryGoal = $noHistoryMap[$storeId][$category][$subcategory][$species] ?? 0; + + $cleanGoal = $originalGoal - $forecastGoal - $noHistoryGoal; + + + $result[] = [ + 'store_id' => $storeId, + 'category' => $category, + 'subcategory' => $subcategory, + 'species' => $species, + 'goal' => $cleanGoal + ]; + } + + return $result; + } + + } \ No newline at end of file diff --git a/erp24/services/StorePlanService.php b/erp24/services/StorePlanService.php index fad3130d..e505ea5c 100755 --- a/erp24/services/StorePlanService.php +++ b/erp24/services/StorePlanService.php @@ -1122,7 +1122,7 @@ class StorePlanService } } $speciesCache = Products1cNomenclature::find() - ->select(['id', 'species']) + ->select(['id', 'species', 'category', 'subcategory']) ->where(['id' => array_unique($allComponentGuids)]) ->indexBy('id')->asArray()->all(); foreach ($forecasts as $forecast) { @@ -1168,11 +1168,13 @@ class StorePlanService foreach ($products as $product) { $guid = $product['product_guid']; $species = $speciesCache[$guid]['species'] ?? 'Неизвестно'; + $category = $speciesCache[$guid]['category'] ?? 'Неизвестно'; + $subcategory = $speciesCache[$guid]['subcategory'] ?? 'Неизвестно'; $price = $priceCache[$regionId][$guid] ?? 0; $raw = $price * $product['count'] * $typeSalesValue; $cost = round($raw * BouquetCompositionPrice::SURCHARGE_ASSEMBLY, 2); - $resultData[$sid][$species][$typeSales] = ($resultData[$sid][$species][$typeSales] ?? 0) + $cost; + $resultData[$sid][$category][$subcategory][$species][$typeSales] = ($resultData[$sid][$category][$subcategory][$species][$typeSales] ?? 0) + $cost; $detailData[$sid][$species][$typeSales][] = [ 'product_guid' => $guid, 'price' => $price, @@ -1189,10 +1191,15 @@ class StorePlanService } $finalResult = []; - foreach ($resultData as $storeId => $speciesData) { - foreach ($speciesData as $species => $salesData) { - $finalResult[$storeId][$species] = round(array_sum($salesData), 2); + foreach ($resultData as $storeId => $categoryData) { + foreach ($categoryData as $category => $subcategoryData) { + foreach ($subcategoryData as $subcategory => $speciesData) { + foreach ($speciesData as $species => $salesData) { + $finalResult[$storeId][$category][$subcategory][$species] = round(array_sum($salesData), 2); + } + } } + } return [ 'detail' => $resultData, diff --git a/erp24/views/auto-plannogramma/9.php b/erp24/views/auto-plannogramma/9.php new file mode 100644 index 00000000..620d8198 --- /dev/null +++ b/erp24/views/auto-plannogramma/9.php @@ -0,0 +1,114 @@ + +
+ +

+ 'get']); ?> +
+
+ field(new \yii\base\DynamicModel(['category' => $filters['category'] ?? '']), 'category')->widget(Select2::class, [ + 'data' => ArrayHelper::map( + Products1cNomenclature::find()->select('category')->distinct()->asArray()->all(), + 'category', + 'category' + ), + 'options' => ['placeholder' => 'Категория', 'name' => 'category'], + 'pluginOptions' => ['allowClear' => true], + ])->label('Категория') ?> +
+
+ field(new \yii\base\DynamicModel(['subcategory' => $filters['subcategory'] ?? '']), 'subcategory')->widget(Select2::class, [ + 'data' => ArrayHelper::map( + Products1cNomenclature::find()->select('subcategory')->distinct()->asArray()->all(), + 'subcategory', + 'subcategory' + ), + 'options' => ['placeholder' => 'Подкатегория', 'name' => 'subcategory'], + 'pluginOptions' => ['allowClear' => true], + ])->label('Подкатегория') ?> +
+
+ field(new \yii\base\DynamicModel(['species' => $filters['species'] ?? '']), 'species')->widget(Select2::class, [ + 'data' => ArrayHelper::map( + Products1cNomenclature::find()->select('species')->distinct()->asArray()->all(), + 'species', + 'species' + ), + 'options' => ['placeholder' => 'Тип товара', 'name' => 'species'], + 'pluginOptions' => ['allowClear' => true], + ])->label('Товар') ?> +
+
+ field(new \yii\base\DynamicModel(['store_id' => $filters['store_id'] ?? '']), 'store_id')->widget(Select2::class, [ + 'data' => ArrayHelper::map( + CityStore::findAll(['visible' => CityStore::IS_VISIBLE]), + 'id', + 'name' + ), + 'options' => ['placeholder' => 'Магазин', 'name' => 'store_id'], + 'pluginOptions' => ['allowClear' => true], + ])->label('Магазин') ?> +
+
+ field(new \yii\base\DynamicModel(['month' => $filters['month'] ?? '']), 'month')->dropDownList(\yii_app\helpers\DateHelper::MONTH_NUMBER_NAMES, [ + 'prompt' => 'Месяц', + 'name' => 'month', + ])->label('Плановый месяц') ?> +
+ +
+ field(new \yii\base\DynamicModel(['year' => $filters['year'] ?? '']), 'year')->dropDownList(['2025' => 2025, '2026' => 2026], [ + 'prompt' => 'Год', + 'name' => 'year', + ])->label('Плановый год') ?> +
+
+ field(new \yii\base\DynamicModel(['type' => $filters['type'] ?? '']), 'type')->widget(Select2::class, [ + 'data' => [ + 'writeOffs' => 'Списания', + 'sales' => 'Продажи' + ], + 'options' => ['placeholder' => 'Тип', 'name' => 'type'], + 'pluginOptions' => ['allowClear' => true], + ])->label('По дефолту продажи!') ?> +
+
+ 'btn btn-primary']) ?> +
+
+ 'btn btn-default']) ?> +
+
+ + +
+ + + + 'store_id', 'label' => 'Магазин', 'value' => function ($data) { + return CityStore::findOne($data['store_id'])->name ?? null; + }], + ['attribute' => 'category', 'label' => 'Категория'], + ['attribute' => 'subcategory', 'label' => 'Подкатегория'], + ['attribute' => 'species', 'label' => 'Тип'], + ['attribute' => 'goal', 'label' => 'Сумма', 'format' => ['decimal', 2]], +]; + + +?> + $dataProvider, + 'columns' => $columns, +]); ?> +