]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Расчет за 3 месяца
authorVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Wed, 18 Jun 2025 14:18:55 +0000 (17:18 +0300)
committerVladimir Fomichev <vladimir.fomichev@erp-flowers.ru>
Wed, 18 Jun 2025 14:18:55 +0000 (17:18 +0300)
erp24/services/AutoPlannogrammaService.php

index 86a1bc2e0c9e86e1606a3305a589a2d6c0b5d8d4..bcb43f2e057fb2755ad7c1dc6f39eea3008a482a 100644 (file)
@@ -3058,11 +3058,11 @@ class AutoPlannogrammaService
 
         $grouped = [];
         foreach ($weeksProductForecast as $item) {
-            $productId = $item['product_guid'];
+            $productId = $item['product_id'];
             $week = $item['week'];
             $type = 'writeOffs';
             $forecastValue = $item['forecast'];
-            $grouped[$productId][$week][$type] = $forecastValue;
+            $grouped[$productId][$week][$type] = ceil($forecastValue);
 
         }
 
@@ -3070,59 +3070,55 @@ class AutoPlannogrammaService
     }
 
     /**
-     * Рассчитывает долю списания (write-offs) каждого товара за заданный месяц
-     * Ð½Ð° Ð¾Ñ\81новании Ð¸Ñ\81Ñ\82оÑ\80иÑ\87еÑ\81киÑ\85 Ð´Ð°Ð½Ð½Ñ\8bÑ\85 Ð·Ð° Ð´Ð²Ð° Ð¿Ñ\80едÑ\8bдÑ\83Ñ\89иÑ\85 Ð³Ð¾Ð´а.
+     * Рассчитывает долю списания товаров за целевой месяц,
+     * Ð¸Ñ\81полÑ\8cзÑ\83Ñ\8f Ð²Ð·Ð²ÐµÑ\88еннÑ\8bе Ð´Ð°Ð½Ð½Ñ\8bе Ð·Ð° Ñ\82Ñ\80и Ð¿Ñ\80едÑ\8bдÑ\83Ñ\89иÑ\85 Ð¼ÐµÑ\81Ñ\8fÑ\86а.
      *
-     * @param array  $productList  Список товаров:
+     * @param array $productList  Список товаров с ключами:
+     *                            ['store_id', 'category', 'subcategory', 'species', 'product_id', …]
+     * @param int   $month        Целевой месяц (1–12)
+     * @param int   $year         Целевой год (например, 2025)
+     * @return array              [
      *                             [
-     *                               [
-     *                                 'week'             => int,
-     *                                 'store_id'         => int,
-     *                                 'category'         => string,
-     *                                 'subcategory'      => string,
-     *                                 'species'          => string,
-     *                                 'product_id'       => string,
-     *                                 'forecast_month_pieces' => float,
-     *                                 'forecast_week_pieces'  => float,
-     *                               ], …
-     *                             ]
-     * @param string $monthYear    Формат 'YYYY-MM'
-     * @return array               [
-     *                               [
-     *                                 'store_id'   => int,
-     *                                 'month'      => int,
-     *                                 'year'       => int,
-     *                                 'category'   => string,
-     *                                 'subcategory'=> string,
-     *                                 'species'    => string,
-     *                                 'product_id' => string,
-     *                                 'writeoff_qty'   => float,
-     *                                 'species_qty'    => float,
-     *                                 'share'          => float, // доля
-     *                               ], …
-     *                             ]
+     *                               'store_id', 'month', 'year',
+     *                               'category','subcategory','species',
+     *                               'product_id','writeoff_qty','species_qty','share'
+     *                             ],
+     *                             …
+     *                           ]
      */
-    public function calculateWriteOffShareByMonth(array $productList, int $month, int $year ): array
-    {
-        $year  = $year ?? (int)date("Y");
-        $month = $month ?? (int)date("m",  strtotime( "+ 2 month" . date('Y-m-01')));
-
-        $storeIds = array_unique(array_column($productList, 'store_id'));
+    public function calculateWriteOffShareByMonth(
+        array $productList,
+        int   $month,
+        int   $year
+    ): array {
+        $targetDate   = strtotime(sprintf('%04d-%02d-01', $year, $month));
+        $storeIds     = array_unique(array_column($productList, 'store_id'));
         if (empty($storeIds)) {
             return [];
         }
 
-        $productQtyMap        = []; // [store][cat][sub][spec][pid] => qty
-        $speciesQtyMap        = []; // [store][cat][sub][spec] => total qty
+        $periods = StorePlanService::getPeriods($targetDate, 3, false, true);
+
+        $productQtyMap = []; // [store][cat][sub][spec][pid] => weighted qty
+        $speciesQtyMap = []; // [store][cat][sub][spec]        => weighted total
+
+        $storeJoin = 'ex.export_val = w.store_id';
 
-        $storeJoinCondition = 'ex.export_val = w.store_id';
 
-        for ($offset = 2; $offset >= 1; $offset--) {
-            $histYear = $year - $offset;
-            $start = sprintf('%04d-%02d-01 00:00:00', $histYear, $month);
-            $end   = date('Y-m-d 23:59:59', strtotime("$start +1 month -1 second"));
+        foreach ($periods as $period) {
+            $histYear  = (int)$period['year'];
+            $histMonth = (int)$period['month'];
+            $weight    = (float)$period['weight'];
+
+
+            $start = sprintf('%04d-%02d-01 00:00:00', $histYear, $histMonth);
+            $end   = date(
+                'Y-m-d 23:59:59',
+                strtotime("$start +1 month -1 second")
+            );
+
 
-            $productsWriteOffs = (new Query())
+            $productsWriteOffs = (new \yii\db\Query())
                 ->select([
                     'store_id'    => 'ex.entity_id',
                     'category'    => 'p1c.category',
@@ -3131,46 +3127,68 @@ class AutoPlannogrammaService
                     'product_id'  => 'wp.product_id',
                     'qty'         => new \yii\db\Expression('SUM(wp.quantity)'),
                 ])
-                ->from(['w' => 'write_offs'])
-                ->innerJoin(['wp' => 'write_offs_products'], 'wp.write_offs_id = w.id')
-                ->leftJoin('export_import_table ex', $storeJoinCondition)
-                ->leftJoin('products_1c_nomenclature p1c', 'p1c.id = wp.product_id')
-                ->leftJoin('products_1c p1', 'p1.id = wp.product_id')
-
+                ->from(['w'  => 'write_offs'])
+                ->innerJoin(
+                    ['wp' => 'write_offs_products'],
+                    'wp.write_offs_id = w.id'
+                )
+                ->leftJoin(
+                    'export_import_table ex',
+                    $storeJoin
+                )
+                ->leftJoin(
+                    'products_1c_nomenclature p1c',
+                    'p1c.id = wp.product_id'
+                )
+                ->leftJoin(
+                    'products_1c p1',
+                    'p1.id = wp.product_id'
+                )
                 ->andWhere(['ex.entity_id' => $storeIds])
                 ->andWhere(['>=', 'w.date', $start])
                 ->andWhere(['<=', 'w.date', $end])
-
                 ->andWhere(['p1.components' => ''])
-                ->andWhere(['not in', 'p1c.category', ['', 'букет', 'сборка', 'сервис']])
-                ->groupBy(['ex.entity_id','p1c.category','p1c.subcategory','p1c.species','wp.product_id'])
+                ->andWhere([
+                    'not in',
+                    'p1c.category',
+                    ['', 'букет', 'сборка', 'сервис']
+                ])
+                ->groupBy([
+                    'ex.entity_id',
+                    'p1c.category',
+                    'p1c.subcategory',
+                    'p1c.species',
+                    'wp.product_id',
+                ])
                 ->all();
 
+
             foreach ($productsWriteOffs as $productsWriteOffsItem) {
                 $sid  = (int)$productsWriteOffsItem['store_id'];
                 $cat  = $productsWriteOffsItem['category'];
                 $sub  = $productsWriteOffsItem['subcategory'];
                 $spec = $productsWriteOffsItem['species'];
                 $pid  = $productsWriteOffsItem['product_id'];
-                $qty  = (float)$productsWriteOffsItem['qty'];
-
+                $qty  = (float)$productsWriteOffsItem['qty'] * $weight;
 
                 $productQtyMap[$sid][$cat][$sub][$spec][$pid] =
-                    ($productQtyMap[$sid][$cat][$sub][$spec][$pid] ?? 0.0) + $qty;
+                    ($productQtyMap[$sid][$cat][$sub][$spec][$pid] ?? 0.0)
+                    + $qty;
 
                 $speciesQtyMap[$sid][$cat][$sub][$spec] =
-                    ($speciesQtyMap[$sid][$cat][$sub][$spec] ?? 0.0) + $qty;
+                    ($speciesQtyMap[$sid][$cat][$sub][$spec] ?? 0.0)
+                    + $qty;
             }
         }
 
-        $seen = [];
+        $seen   = [];
         $result = [];
         foreach ($productList as $item) {
-            $pid  = $item['product_id'];
             $sid  = $item['store_id'];
             $cat  = $item['category'];
             $sub  = $item['subcategory'];
             $spec = $item['species'];
+            $pid  = $item['product_id'];
 
             $key = "{$sid}|{$cat}|{$sub}|{$spec}|{$pid}";
             if (isset($seen[$key])) {
@@ -3179,26 +3197,27 @@ class AutoPlannogrammaService
             $seen[$key] = true;
 
             $productsQty = $productQtyMap[$sid][$cat][$sub][$spec][$pid] ?? 0.0;
-            $speciesQty = $speciesQtyMap[$sid][$cat][$sub][$spec] ??  0.0;
-            $share = $speciesQty > 0
+            $speciesQty = $speciesQtyMap[$sid][$cat][$sub][$spec]        ?? 0.0;
+            $share = $speciesQty > 0.0
                 ? round($productsQty / $speciesQty, 4)
                 : 0.0;
 
             $result[] = [
-                'store_id'        => $sid,
-                'month'           => $month,
-                'year'            => $year,
-                'category'        => $cat,
-                'subcategory'     => $sub,
-                'species'         => $spec,
-                'product_id'      => $pid,
-                'writeoff_qty'    => $productsQty,
-                'species_qty'     => $speciesQty,
-                'share'           => $share,
+                'store_id'     => $sid,
+                'month'        => $month,
+                'year'         => $year,
+                'category'     => $cat,
+                'subcategory'  => $sub,
+                'species'      => $spec,
+                'product_id'   => $pid,
+                'writeoff_qty' => round($productsQty, 4),
+                'species_qty'  => round($speciesQty, 4),
+                'share'        => $share,
             ];
         }
 
         return $result;
     }
 
+
 }
\ No newline at end of file