]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Правки по подкатегориям
authorfomichev <vladimir.fomichev@erp-flowers.ru>
Thu, 29 May 2025 15:02:43 +0000 (18:02 +0300)
committerfomichev <vladimir.fomichev@erp-flowers.ru>
Thu, 29 May 2025 15:02:43 +0000 (18:02 +0300)
erp24/controllers/AutoPlannogrammaController.php
erp24/services/AutoPlannogrammaService.php
erp24/views/auto-plannogramma/1_2.php

index ee54fdf4ae21353f8da6c13311abbfa6745ac23e..4b86952ae5bfcd69d5b492ccfc19052e00cdd583 100644 (file)
@@ -9,7 +9,9 @@ use yii\db\Query;
 use yii\helpers\ArrayHelper;
 use yii_app\records\CityStore;
 use yii_app\records\MatrixBouquetForecast;
+use yii_app\records\PricesDynamic;
 use yii_app\records\Products1c;
+use yii_app\records\Products1cNomenclature;
 use yii_app\services\AutoPlannogrammaService;
 use yii_app\services\StorePlanService;
 
@@ -293,7 +295,7 @@ class AutoPlannogrammaController extends BaseController
             $filters['plan_date'] = $filters['year'] . '-' . str_pad($filters['month'], 2, '0', STR_PAD_LEFT) . '-01';
 
             $service = new AutoPlannogrammaService();
-            $data = $service->getUnmarkedProductsComponents($filters['store_id'], $filters['month'], $filters['year'], $filters['type']);
+            $data = $service->getProductsComponentsInCategory($filters['store_id'], $filters['month'], $filters['year'], $filters['type']);
 
             $flatData = array_filter($data, function ($row) use ($filters) {
                 foreach ($filters as $key => $value) {
@@ -309,7 +311,8 @@ class AutoPlannogrammaController extends BaseController
 
             $dataProvider = new ArrayDataProvider([
                 'allModels' => array_values($flatData),
-                'pagination' => ['pageSize' => 100],
+                'pagination' => ['pageSize' => 500],
+
             ]);
         }
 
@@ -353,22 +356,15 @@ class AutoPlannogrammaController extends BaseController
                 $filters,
                 $filters['type']
             );
-           // var_dump($data);die();
-            $categoryRows = [];
-            $allProdIds   = [];
 
+            $allProdIds   = [];
+            $categoryRows = [];
             foreach ($data as $storeId => $categories) {
                 $storeName = CityStore::findOne($storeId)->name ?? null;
                 foreach ($categories as $row) {
-                    $prodIds = array_filter(
-                        array_map('trim', explode(',', $row['products_list'] ?? '')),
-                        fn($v) => $v !== ''
-                    );
-                    $prodCompIds = array_filter(
-                        array_map('trim', explode(',', $row['products_components_list'] ?? '')),
-                        fn($v) => $v !== ''
-                    );
-                    $allProdIds = array_merge($allProdIds, $prodIds, $prodCompIds);
+                    $prodIds     = array_filter(explode(',', $row['products_list'] ?? ''), fn($v)=>$v!=='');
+                    $prodCompIds = array_filter(explode(',', $row['products_components_list'] ?? ''), fn($v)=>$v!=='');
+                    $rowProdIds  = array_merge($prodIds, $prodCompIds);
 
                     $categoryRows[] = [
                         'store_id'         => (string)$storeId,
@@ -378,40 +374,51 @@ class AutoPlannogrammaController extends BaseController
                         'new_total_store'  => $row['new_total_store'],
                         'total_sum'        => $row['total_sum'],
                         'percent'          => $row['percent'],
-                        'product_ids'      => $allProdIds,
+                        'product_ids'      => $rowProdIds,
                     ];
+
+                    $allProdIds = array_merge($allProdIds, $rowProdIds);
                 }
             }
 
+
             $allProdIds = array_values(array_unique($allProdIds));
-           // var_dump($allProdIds);die();
-            if (!empty($allProdIds)) {
-                $products = Products1c::find()
-                    ->select(['id', 'name', 'type', 'components'])
-                    ->andWhere(['id' => $allProdIds])
-                    ->asArray()
-                    ->indexBy('id')
-                    ->all();
-            } else {
-                $products = [];
-            }
-            //var_dump($products);die();
+            $products = Products1c::find()
+                ->select(['id','name','type','components'])
+                ->andWhere(['id'=>$allProdIds])
+                ->asArray()
+                ->indexBy('id')
+                ->all();
+
+
             $productsRows = [];
-            foreach ($categoryRows as &$row) {
-                $rowProducts = [];
+            foreach ($categoryRows as $row) {
                 foreach ($row['product_ids'] as $pid) {
-                    if (isset($products[$pid])) {
-                        $prod = $products[$pid];
-
-                        $prod['category'] = $row['category'];
-                        $rowProducts[]    = $prod;
-                        $productsRows[$pid] = $prod;
+                    if (!isset($products[$pid])) {
+                        continue;
                     }
+                    $prod = $products[$pid];
+
+                    $prod['category'] = Products1cNomenclature::find()->where(['id' => $pid])->one()->category ?? null;
+                    $prod['price'] = PricesDynamic::find()
+                        ->where(['product_id' => $pid])
+                        ->andWhere(['region_id' => 52])
+                        ->andWhere(['active' => 1])
+                        ->one()->price ?? null;
+                    $productsRows[]   = $prod;
                 }
-                $row['products'] = $rowProducts;
-                unset($row['product_ids']);
             }
-            unset($row);
+            if (!empty($filters['category'])) {
+                $productsRows = array_filter($productsRows, function($prod) use ($filters) {
+                    return $prod['category'] === $filters['category'];
+                });
+            }
+
+
+            $productsProvider = new ArrayDataProvider([
+                'allModels'  => $productsRows,
+                'pagination' => ['pageSize'=>500],
+            ]);
 
             $categoryRows = array_filter($categoryRows, function($row) use ($filters) {
                 foreach ($filters as $key => $value) {
@@ -428,12 +435,9 @@ class AutoPlannogrammaController extends BaseController
 
             $categoriesProvider = new ArrayDataProvider([
                 'allModels'  => array_values($categoryRows),
-                'pagination' => ['pageSize' => 50],
-            ]);
-            $productsProvider = new ArrayDataProvider([
-                'allModels'  => array_values($productsRows),
                 'pagination' => ['pageSize' => 500],
             ]);
+
         }
 
         return $this->render('1_2', [
@@ -861,7 +865,7 @@ class AutoPlannogrammaController extends BaseController
             $filters['plan_date'] = $filters['year'] . '-' . str_pad($filters['month'], 2, '0', STR_PAD_LEFT) . '-01';
 
             $service = new AutoPlannogrammaService();
-            $monthCategoryShare = $service->getMonthCategoryShareOrWriteOff($filters['plan_date'], $filters);
+            $monthCategoryShare = $service->getMonthCategoryShareOrWriteOff($filters['plan_date'], $filters, $filters['type']);
 
             $monthCategoryGoal = $service->getMonthCategoryGoal($monthCategoryShare, $filters['plan_date']);
             $monthSubcategoryShare = $service->getMonthSubcategoryShareOrWriteOff($filters['plan_date'], $filters);
index e46d26e4c7013621d68fa93491da3707320a1b1f..d3aabeafb0bba92c6ae011f37a0f2d4d4094d1ae 100644 (file)
@@ -4,6 +4,7 @@ namespace yii_app\services;
 
 use Yii;
 use yii\db\Expression;
+use yii\db\mssql\PDO;
 use yii\db\Query;
 use yii\helpers\ArrayHelper;
 use yii_app\records\BouquetComposition;
@@ -108,7 +109,6 @@ class AutoPlannogrammaService
             ]);
 
         }
-
         // Основной запрос с CTE
         $query = (new Query())
             ->select([
@@ -132,8 +132,10 @@ class AutoPlannogrammaService
                     ->leftJoin($productTableJoin, $productTableJoinCondition)
                     ->leftJoin('products_1c_nomenclature p1c', "p1c.id = $productJoinCondition")
                     ->leftJoin('export_import_table ex', $storeJoinCondition)
+                    ->leftJoin('products_1c p1', "p1.id = $productJoinCondition")
                     ->andWhere(['ex.entity_id' => $storeIds])
-                    ->andWhere(['<>', 'p1c.category', ['', 'букет', 'сборка', 'сервис' ]])
+                    ->andWhere(['p1.components' => ''])
+                    ->andWhere(['not in', 'p1c.category', ['', 'букет', 'сборка', 'сервис']])
                     ->andWhere(['>=', "$alias.date", (new \DateTime($month1 . '-01'))->format('Y-m-d')])
                     ->andWhere(['<=', "$alias.date", (new \DateTime($month3 . '-01'))->modify('last day of this month')->format('Y-m-d')])
                     ->groupBy(['ex.entity_id', 'p1c.category']),
@@ -148,8 +150,10 @@ class AutoPlannogrammaService
                     ->leftJoin($productTableJoin, $productTableJoinCondition)
                     ->leftJoin('products_1c_nomenclature p1c', "p1c.id = $productJoinCondition")
                     ->leftJoin('export_import_table ex', $storeJoinCondition)
+                    ->leftJoin('products_1c p1', "p1.id = $productJoinCondition")
                     ->andWhere(['ex.entity_id' => $storeIds])
-                    ->andWhere(['<>', 'p1c.category', ['', 'букет', 'сборка', 'сервис' ]])
+                    ->andWhere(['p1.components' => ''])
+                    ->andWhere(['not in', 'p1c.category', ['', 'букет', 'сборка', 'сервис']])
                     ->andWhere(['>=', "$alias.date", (new \DateTime($month1 . '-01'))->format('Y-m-d')])
                     ->andWhere(['<=', "$alias.date", (new \DateTime($month3 . '-01'))->modify('last day of this month')->format('Y-m-d')])
                     ->groupBy(['ex.entity_id']),
@@ -166,22 +170,25 @@ class AutoPlannogrammaService
         $componentAdds = [];
         $componentAddsSumAll = [];
         $allComponentsProductIds = [];
+
         foreach ($storeIds as $storeId) {
             foreach ($months as $m => $weight) {
                 [$year, $mon] = explode('-', $m);
-                $items = $this->getUnmarkedProductsComponents(
+                $items = $this->getProductsComponentsInCategory(
                     (int)$storeId,
                     (int)$mon,
                     (int)$year,
                     $type
                 );
+
                 if(!$items) {
                     continue;
                 }
                 foreach ($items as $it) {
                     $allComponentsProductIds[$storeId][] = $it['product_id'];
                 }
-                $sums = $this->sumUnmarkedProductsComponentsByCategory($items, $type);
+                $sums = $this->sumProductsComponentsByCategory($items, $type);
+
                 $allComponentsProductIds[$storeId] = array_values(array_unique($allComponentsProductIds[$storeId]));
                 foreach ($sums as $sumRow) {
                     $sid = $sumRow['store_id'];
@@ -194,6 +201,7 @@ class AutoPlannogrammaService
             }
         }
 
+
         $result = [];
         foreach ($rows as $r) {
             $sid = $r['store_id'];
@@ -211,7 +219,7 @@ class AutoPlannogrammaService
                 'category' => $r['category'],
                 'total_sum' => $newTotal,
                 'percent' => $percent,
-                'type' => $r['type'],
+                'type' => $type,
                 'new_total_store' => $newDenominator,
                 'base_total_store' => $baseTotal,
                 'products_list' => $r['products_list'],
@@ -282,21 +290,24 @@ class AutoPlannogrammaService
         $productTableJoin = $type === self::TYPE_WRITE_OFFS ? ['wp' => 'write_offs_products'] : ['sp' => 'sales_products'];
         $productTableJoinCondition = $type === self::TYPE_WRITE_OFFS ? 'wp.write_offs_id = w.id' : 'sp.check_id = s.id';
 
+        $field = $type === self::TYPE_WRITE_OFFS ? 'w.date' : 's.date';
+        $base  = new \DateTime($dateFrom);
+
         $months = [
             [
                 'between',
-                $type === self::TYPE_WRITE_OFFS ? 'w.date' : 's.date',
-                (new \DateTime($dateFrom))->modify('-1 year')->format('Y-m-01'),
-                (new \DateTime($dateFrom))->format('Y-m-t'),
+                $field,
+                (clone $base)->modify('-2 year')->format('Y-m-01 00:00:00'),  // два года назад, начало месяца
+                (clone $base)->modify('-2 year')->format('Y-m-t 23:59:59'),   // два года назад, конец месяца
             ],
             [
                 'between',
-                $type === self::TYPE_WRITE_OFFS ? 'w.date' : 's.date',
-                (new \DateTime($dateFrom))->modify('-1 year')->format('Y-m-01'),
-                (new \DateTime($dateFrom))->format('Y-m-t'),
+                $field,
+                (clone $base)->modify('-1 year')->format('Y-m-01 00:00:00'),  // год назад, начало месяца
+                (clone $base)->modify('-1 year')->format('Y-m-t 23:59:59'),   // год назад, конец месяца
             ],
         ];
-
+        //var_dump($months);die();
         $query = (new Query())
             ->select([
                 'store_id' => 'main.ex_entity_id',
@@ -318,8 +329,10 @@ class AutoPlannogrammaService
                     ->leftJoin($productTableJoin, $productTableJoinCondition)
                     ->leftJoin('products_1c_nomenclature p1c', "p1c.id = $productJoinCondition")
                     ->leftJoin('export_import_table ex', $storeJoinCondition)
+                    ->leftJoin('products_1c p1', "p1.id = $productJoinCondition")
                     ->andWhere(['ex.entity_id' => $storeIds])
-                    ->andWhere(['<>', 'p1c.category', ''])
+                    ->andWhere(['p1.components' => ''])
+                    ->andWhere(['not in', 'p1c.category', ['', 'букет', 'сборка', 'сервис']])
                     ->andWhere(['or', ...$months])
                     ->groupBy(['ex.entity_id', 'p1c.category', 'p1c.subcategory']),
             ])
@@ -334,8 +347,10 @@ class AutoPlannogrammaService
                     ->leftJoin($productTableJoin, $productTableJoinCondition)
                     ->leftJoin('products_1c_nomenclature p1c', "p1c.id = $productJoinCondition")
                     ->leftJoin('export_import_table ex', $storeJoinCondition)
+                    ->leftJoin('products_1c p1', "p1.id = $productJoinCondition")
                     ->andWhere(['ex.entity_id' => $storeIds])
-                    ->andWhere(['<>', 'p1c.category', ''])
+                    ->andWhere(['p1.components' => ''])
+                    ->andWhere(['not in', 'p1c.category', ['', 'букет', 'сборка', 'сервис']])
                     ->andWhere(['or', ...$months])
                     ->groupBy(['ex.entity_id', 'p1c.category'])],
                 'main.ex_entity_id = totals.store_id AND main.category = totals.category'
@@ -737,7 +752,7 @@ class AutoPlannogrammaService
      *                 component_guid, component_name, component_category,
      *                 quantity, price, cost
      */
-    public function getUnmarkedProductsComponents(int $storeId, string $month, string $year, $type = 'sales'): array
+    public function getProductsComponentsInCategory(int $storeId, string $month, string $year, string $type = 'sales'): array
     {
         $region = CityStoreParams::find()
             ->where(['store_id' => $storeId])
@@ -756,7 +771,7 @@ class AutoPlannogrammaService
         $monthStart = sprintf('%04d-%02d-01 00:00:00', $year, $month);
         $daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
         $monthEnd   = sprintf('%04d-%02d-%02d 23:59:59', $year, $month, $daysInMonth);
-        $unmarkedProducts = [];
+        $componentProducts = [];
 
         if ($type == self::TYPE_SALES) {
             $salesProducts = Sales::find()
@@ -781,7 +796,7 @@ class AutoPlannogrammaService
                // ->andWhere(['nom.category' => null])
                 ->asArray()
                 ->all();
-        $unmarkedProducts = $salesProducts;
+        $componentProducts = $salesProducts;
         } else {
 
             $writeOffsProducts = WriteOffs::find()
@@ -817,15 +832,15 @@ class AutoPlannogrammaService
                 ->andWhere(['<>', 'p1c.components', ''])
                 ->asArray()
                 ->all();
-            $unmarkedProducts = $writeOffsProducts;
+            $componentProducts = $writeOffsProducts;
         }
 
 
         $components = [];
         $rows       = [];
-        foreach ($unmarkedProducts as $up) {
+        foreach ($componentProducts as $cp) {
 
-            $js      = trim($up['components']);
+            $js      = trim($cp['components']);
             if ($js === '' || $js[0] !== '{') {
                 continue;
             }
@@ -842,14 +857,14 @@ class AutoPlannogrammaService
                 $components[$guid] = true;
 
                 $rows[] = [
-                    'sale_id'     => $up['id'],
-                    'sale_date'   => $up['date'],
-                    'product_id'  => $up['product_id'],
-                    'product_name'=> $up['name'],
+                    'sale_id'     => $cp['id'],
+                    'sale_date'   => $cp['date'],
+                    'product_id'  => $cp['product_id'],
+                    'product_name'=> $cp['name'],
                     'component_guid' => $guid,
                     'quantity'    => $qty,
                     'type' => $type,
-                    'operation' => $up['operation'] ?? '',
+                    'operation' => $cp['operation'] ?? '',
                 ];
             }
         }
@@ -916,7 +931,7 @@ class AutoPlannogrammaService
     }
 
 
-    public function sumUnmarkedProductsComponentsByCategory(array $items, string $type): array
+    public function sumProductsComponentsByCategory(array $items, string $type): array
     {
         $aggregated = [];
 
index 49f5cf4381b9a61aaeae757f47831e44f73802c8..c4fa983aa66af533b313542a2ceaedfc583c9b51 100644 (file)
@@ -59,7 +59,7 @@
             <?= Html::submitButton('Фильтровать', ['class' => 'btn btn-primary']) ?>
         </div>
         <div class="col-md">
-            <?= Html::a('Сбросить', ['auto-plannogramma/1'], ['class' => 'btn btn-default']) ?>
+            <?= Html::a('Сбросить', ['auto-plannogramma/1_2'], ['class' => 'btn btn-default']) ?>
         </div>
     </div>
 
         ['class' => 'yii\grid\SerialColumn'],
         ['attribute'=>'id',          'label'=>'ID товара'],
         ['attribute'=>'name',        'label'=>'Название'],
+        ['attribute'=>'price',        'label'=>'Цена'],
         ['attribute'=>'components',  'label'=>'Components'],
         ['attribute'=>'type',        'label'=>'Type'],
         ['attribute'=>'category',    'label'=>'Категория'],