]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Расчет долей и процентов
authorfomichev <vladimir.fomichev@erp-flowers.ru>
Tue, 24 Jun 2025 14:38:44 +0000 (17:38 +0300)
committerfomichev <vladimir.fomichev@erp-flowers.ru>
Tue, 24 Jun 2025 14:38:44 +0000 (17:38 +0300)
erp24/controllers/CategoryPlanController.php
erp24/views/category-plan/index.php

index ed43a2d391ab1cc26e7341aedd059bd3af214737..c2e0f5cddf9eab0a3820c62dc520ec4c99c15259 100644 (file)
@@ -193,18 +193,18 @@ class CategoryPlanController extends Controller {
             $mnths = array_keys($mnths);
 
             sort($mnths);
-            $countMnths = count($mnths);
+
             $weights = [];
             foreach ($mnths as $ind => $month) {
                 $weights[$month] = $ind + 1;
             }
 
             foreach ($sales as $sale) {
-                $table[$sale['store_id']][$sale['type']] = ($table[$sale['store_id']][$sale['type']] ?? 0) + $weights[$sale['month']] * $sale['total'] / $countMnths;
+                $table[$sale['store_id']][$sale['type']] = ($table[$sale['store_id']][$sale['type']] ?? 0) + $weights[$sale['month']] * $sale['total'] ;
             }
             foreach ($salesMatrixOffline as $saleMatrix) {
                 $types[$saleMatrix['type']] = 1;
-                $table[$saleMatrix['store_id']][$saleMatrix['type']] = ($table[$saleMatrix['store_id']][$saleMatrix['type']] ?? 0) + $weights[$saleMatrix['month']] * $saleMatrix['total'] / $countMnths;
+                $table[$saleMatrix['store_id']][$saleMatrix['type']] = ($table[$saleMatrix['store_id']][$saleMatrix['type']] ?? 0) + $weights[$saleMatrix['month']] * $saleMatrix['total'] ;
             }
             //var_dump($table); die();
             foreach ($compoundSalesData['offline'] as $monthKey => $categories) {
@@ -215,11 +215,12 @@ class CategoryPlanController extends Controller {
                     $sum = (float)$item['sum'];
                     $types[$item['category']] = 1;
                     $table[$store][$type] = ($table[$store][$type] ?? 0)
-                        + $w * $sum / $countMnths;
+                        + $w * $sum ;
                 }
             }
-            // var_dump($table); die();
-            /////////////////////////////////////////////////////////////////////////////////////
+
+            $offlinePlannedSales = self::calculatePlannedSales($table, $salesWriteOffsPlan->offline_sales_plan);
+
             $salesOnline = Sales::find()->alias('s')->select([
                 "COUNT(*) as cnt",
                 "SUM(CASE WHEN operation='Продажа' THEN sp.summ ELSE (CASE WHEN operation='Возврат' THEN -sp.summ ELSE 0 END) END) as total",
@@ -270,11 +271,11 @@ class CategoryPlanController extends Controller {
 
             foreach ($salesOnline as $sale) {
                 $types[$sale['type']] = 1;
-                $tableOnline[$sale['store_id']][$sale['type']] = ($tableOnline[$sale['store_id']][$sale['type']] ?? 0) + $weights[$sale['month']] * $sale['total'] / 3;
+                $tableOnline[$sale['store_id']][$sale['type']] = ($tableOnline[$sale['store_id']][$sale['type']] ?? 0) + $weights[$sale['month']] * $sale['total'] ;
             }
             foreach ($salesMatrixOnline as $saleMatrix) {
                 $types[$saleMatrix['type']] = 1;
-                $tableOnline[$saleMatrix['store_id']][$saleMatrix['type']] = ($tableOnline[$saleMatrix['store_id']][$saleMatrix['type']] ?? 0) + $weights[$saleMatrix['month']] * $saleMatrix['total'] / $countMnths;
+                $tableOnline[$saleMatrix['store_id']][$saleMatrix['type']] = ($tableOnline[$saleMatrix['store_id']][$saleMatrix['type']] ?? 0) + $weights[$saleMatrix['month']] * $saleMatrix['total'] ;
             }
 
             foreach ($compoundSalesData['online'] as $monthKey => $categories) {
@@ -285,11 +286,13 @@ class CategoryPlanController extends Controller {
                     $sum = (float)$item['sum'];
                     $types[$item['category']] = 1;
                     $tableOnline[$store][$type] = ($tableOnline[$store][$type] ?? 0)
-                        + $w * $sum / $countMnths;
+                        + $w * $sum ;
                 }
             }
-            //var_dump($compoundSalesData['online']); die();
-            /////////////////////////////////////////////////////////////////////////////////////
+
+            $onlinePlannedSales = self::calculatePlannedSales($tableOnline, $salesWriteOffsPlan->online_sales_shop_plan);
+
+
             $eit = ExportImportTable::find()->where(['entity' => 'city_store', 'export_id' => 1, 'entity_id' => $model->store_id])->one();
             $store_id = $eit->export_val ?? '';
             $writeOffs = WriteOffs::find()->alias('wo')->select([
@@ -353,12 +356,12 @@ class CategoryPlanController extends Controller {
 
             foreach ($writeOffs as $writeoff) {
                 $types[$writeoff['p1ctype']] = 1;
-                $tableWriteOffs[$writeoff['store_id']][$writeoff['p1ctype']] = ($tableWriteOffs[$writeoff['store_id']][$writeoff['p1ctype']] ?? 0) + $weights[$writeoff['month']] * $writeoff['total'] / $countMnths;
+                $tableWriteOffs[$writeoff['store_id']][$writeoff['p1ctype']] = ($tableWriteOffs[$writeoff['store_id']][$writeoff['p1ctype']] ?? 0) + $weights[$writeoff['month']] * $writeoff['total'];
             }
 
             foreach ($writeOffsMatrix as $writeOffMatrix) {
                 $types[$writeOffMatrix['p1ctype']] = 1;
-                $tableWriteOffs[$writeOffMatrix['store_id']][$writeOffMatrix['p1ctype']] = ($tableWriteOffs[$writeOffMatrix['store_id']][$writeOffMatrix['p1ctype']] ?? 0) + $weights[$writeOffMatrix['month']] * $writeOffMatrix['total'] / $countMnths;
+                $tableWriteOffs[$writeOffMatrix['store_id']][$writeOffMatrix['p1ctype']] = ($tableWriteOffs[$writeOffMatrix['store_id']][$writeOffMatrix['p1ctype']] ?? 0) + $weights[$writeOffMatrix['month']] * $writeOffMatrix['total'];
             }
 
             foreach ($compoundWriteOffsData as $monthKey => $categories) {
@@ -369,10 +372,10 @@ class CategoryPlanController extends Controller {
                     $sum = (float)$item['sum'];
                     $types[$item['category']] = 1;
                     $tableWriteOffs[$store][$type] = ($tableWriteOffs[$store][$type] ?? 0)
-                        + $w * $sum / $countMnths;
+                        + $w * $sum ;
                 }
             }
-
+            $plannedWriteOffs = self::calculatePlannedSales($tableWriteOffs, $salesWriteOffsPlan->write_offs_plan);
             $types = array_keys($types);
             /////////////////////////////////////////////////////////////////////////////////////
 
@@ -383,10 +386,10 @@ class CategoryPlanController extends Controller {
                     $categoryPlanNew->month = $model->month;
                     $categoryPlanNew->store_id = $model->store_id;
                     $categoryPlanNew->category = $type;
-                    $categoryPlanNew->offline = $table[$model->store_id][$type] ?? 0;
-                    $categoryPlanNew->internet_shop = $tableOnline[$model->store_id][$type] ?? 0;
+                    $categoryPlanNew->offline = $offlinePlannedSales[$model->store_id][$type] ?? 0;
+                    $categoryPlanNew->internet_shop = $onlinePlannedSales[$model->store_id][$type] ?? 0;
                     $categoryPlanNew->marketplace = 0;
-                    $categoryPlanNew->write_offs = $tableWriteOffs[$model->store_id][$type] ?? 0;
+                    $categoryPlanNew->write_offs = $plannedWriteOffs[$model->store_id][$type] ?? 0;
                     $categoryPlanNew->created_at = date('Y-m-d HH:i:s');
                     $categoryPlanNew->updated_at = date('Y-m-d HH:i:s');
                     $categoryPlanNew->created_by = Yii::$app->user->id;
@@ -672,4 +675,39 @@ class CategoryPlanController extends Controller {
     }
 
 
+    /**
+     * Рассчитывает плановые офлайн-продажи по долям категорий.
+     *
+     * @param array $salesByCategory Массив вида [store_id => [category => sum, ...], ...]
+     * @param float $planLevel Общее значение плана для каждого магазина
+     * @return array Массив плановых продаж [store_id => [category => plannedSale, ...], ...]
+     */
+    public static function calculatePlannedSales(array $salesByCategory, float $planLevel): array
+    {
+        $offlinePlannedSales = [];
+
+        foreach ($salesByCategory as $store => $types) {
+            $sumCat = 0.0;
+            foreach ($types as $type => $sum) {
+                if ($type === 'Матрица') {
+                    continue;
+                }
+                $sumCat += $sum;
+            }
+
+            if ($sumCat <= 0) {
+                $offlinePlannedSales[$store] = [];
+                continue;
+            }
+
+            foreach ($types as $type => $sum) {
+                $share = round($sum / $sumCat, 4);
+                $offlinePlannedSales[$store][$type] = $planLevel * $share;
+            }
+        }
+
+        return $offlinePlannedSales;
+    }
+
+
 }
index a4aa9fab52c6b46c73eb4da971e3b24746764554..7f63250e5bda23460489c9a03df21592081cd3fd 100644 (file)
@@ -203,22 +203,22 @@ input[readonly] {
                             <th data-type><?= $type ?></th>
                             <?php
                             $data = $categoryPlan[$type]['offline'];
-                            $p1 = $offline_sale <= 0 ? 0 : 1.0 * $data / $offline_sale * 100;
+                            $p1 = $offline_sale <= 0 ? 0 : round( $data / $offline_sale, 6) * 100;
                             ?>
-                            <td data-p1 data-offline="<?= $offline_sale ?>"><?= Html::textInput('p1', number_format($p1, 0, '.', ''), ['type' => 'number', 'style' => 'max-width: 80px;', 'readonly' => !$isEditable, 'onchange' => 'editProcent(this, 1);']) ?>%</td>
+                            <td data-p1 data-offline="<?= $offline_sale ?>"><?= Html::textInput('p1', number_format($p1, 2, '.', ''), ['type' => 'number', 'style' => 'max-width: 80px;', 'readonly' => !$isEditable, 'onchange' => 'editProcent(this, 1);']) ?>%</td>
                             <td><?= Html::textInput('offline', number_format($categoryPlan[$type]['offline'], 0, '.', ''), ['type' => 'number', 'readonly' => !$isEditable, 'onchange' => 'editField(this);']) ?></td>
                             <?php
                             $data2 = $categoryPlan[$type]['internet_shop'];
-                            $p2 = $online_sale <= 0 ? 0 : $data2 / $online_sale * 100;
+                            $p2 = $online_sale <= 0 ? 0 : round( $data2 / $online_sale, 6) * 100;
                             ?>
-                            <td data-p2 data-online="<?= $online_sale ?>"><?= Html::textInput('p2', number_format($p2, 0, '.', ''), ['type' => 'number', 'style' => 'max-width: 80px;', 'readonly' => !$isEditable, 'onchange' => 'editProcent(this, 2);']) ?>%</td>
+                            <td data-p2 data-online="<?= $online_sale ?>"><?= Html::textInput('p2', number_format($p2, 2, '.', ''), ['type' => 'number', 'style' => 'max-width: 80px;', 'readonly' => !$isEditable, 'onchange' => 'editProcent(this, 2);']) ?>%</td>
                             <td><?= Html::textInput('internet_shop', number_format($categoryPlan[$type]['internet_shop'], 0, '.', ''), ['type' => 'number', 'readonly' => !$isEditable, 'onchange' => 'editField(this);']) ?></td>
                             <?php //<td></td><td></td> ?>
                             <?php
                             $data4 = $categoryPlan[$type]['write_offs'];
-                            $p3 = $write_offs <= 0 ? 0 : $data4 / $write_offs * 100;
+                            $p3 = $write_offs <= 0 ? 0 : round( $data4 / $write_offs, 6) * 100;
                             ?>
-                            <td data-p3 data-writeoffs="<?= $write_offs ?>"><?= Html::textInput('p3', number_format($p3, 0, '.', ''), ['type' => 'number', 'style' => 'max-width: 80px;', 'readonly' => !$isEditable, 'onchange' => 'editProcent(this, 3);']) ?>%</td>
+                            <td data-p3 data-writeoffs="<?= $write_offs ?>"><?= Html::textInput('p3', number_format($p3, 2, '.', ''), ['type' => 'number', 'style' => 'max-width: 80px;', 'readonly' => !$isEditable, 'onchange' => 'editProcent(this, 3);']) ?>%</td>
                             <td><?= Html::textInput('write_offs', number_format($categoryPlan[$type]['write_offs'], 0, '.', ''), ['type' => 'number',  'readonly' => !$isEditable, 'onchange' => 'editField(this);']) ?></td>
                         </tr>
                     <?php endforeach; ?>