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

index c2e0f5cddf9eab0a3820c62dc520ec4c99c15259..ce61ae5b80f63411a5362c3e1e3cbe010d6ac1ab 100644 (file)
@@ -47,7 +47,7 @@ class CategoryPlanController extends Controller {
 
         $service = new AutoPlannogrammaService();
         $isEditable = date($model->year . '-' . $model->month . '-d') > date('Y-m-d') && (
-            (date('d') < 25) || (date('Y-m-d', strtotime('-1 month', strtotime(date($model->year . '-' . $model->month . '-d')))) > date('Y-m-d')));
+            (date('d') < 27) || (date('Y-m-d', strtotime('-1 month', strtotime(date($model->year . '-' . $model->month . '-d')))) > date('Y-m-d')));
 
         $categoryPlan = CategoryPlan::find()->where(['year' => $model->year, 'month' => $model->month, 'store_id' => $model->store_id])->indexBy('category')->asArray()->all();
         $types = [];
index 7f63250e5bda23460489c9a03df21592081cd3fd..b9afcce8b0ef0dab4b16be6bf265ddf34bb537ba 100644 (file)
@@ -205,21 +205,21 @@ input[readonly] {
                             $data = $categoryPlan[$type]['offline'];
                             $p1 = $offline_sale <= 0 ? 0 : round( $data / $offline_sale, 6) * 100;
                             ?>
-                            <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>
+                            <td data-p1-<?= $type ?> data-offline="<?= $offline_sale ?>" data-offline-type="<?= $type ?>"><?= Html::textInput('p1', number_format($p1, 2, '.', ''), ['type' => 'number', 'style' => 'max-width: 80px;', 'readonly' => !$isEditable, 'onchange' => 'editProcent(this, 1);']) ?>%</td>
+                            <td data-offline-type="<?= $type ?>"><?= Html::textInput('offline', number_format($categoryPlan[$type]['offline'], 0, '.', ''), ['type' => 'number', 'readonly' => true, 'onchange' => 'editField(this);']) ?></td>
                             <?php
                             $data2 = $categoryPlan[$type]['internet_shop'];
                             $p2 = $online_sale <= 0 ? 0 : round( $data2 / $online_sale, 6) * 100;
                             ?>
-                            <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>
+                            <td data-p2-<?= $type ?> data-online="<?= $online_sale ?>" data-online-type="<?= $type ?>"><?= Html::textInput('p2', number_format($p2, 2, '.', ''), ['type' => 'number', 'style' => 'max-width: 80px;', 'readonly' => !$isEditable, 'onchange' => 'editProcent(this, 2);']) ?>%</td>
+                            <td data-online-type="<?= $type ?>"><?= Html::textInput('internet_shop', number_format($categoryPlan[$type]['internet_shop'], 0, '.', ''), ['type' => 'number', 'readonly' => true, 'onchange' => 'editField(this);']) ?></td>
                             <?php //<td></td><td></td> ?>
                             <?php
                             $data4 = $categoryPlan[$type]['write_offs'];
                             $p3 = $write_offs <= 0 ? 0 : round( $data4 / $write_offs, 6) * 100;
                             ?>
-                            <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>
+                            <td data-p3-<?= $type ?> data-writeoffs="<?= $write_offs ?>" data-writeoffs-type="<?= $type ?>"><?= Html::textInput('p3', number_format($p3, 2, '.', ''), ['type' => 'number', 'style' => 'max-width: 80px;', 'readonly' => !$isEditable, 'onchange' => 'editProcent(this, 3);']) ?>%</td>
+                            <td data-writeoffs-type="<?= $type ?>"><?= Html::textInput('write_offs', number_format($categoryPlan[$type]['write_offs'], 0, '.', ''), ['type' => 'number',  'readonly' => true, 'onchange' => 'editField(this);']) ?></td>
                         </tr>
                     <?php endforeach; ?>
                 </tbody>
index df3c96d174d6facbf5f791dc9cd4f419f3b4cb02..d0c24865645a68a8e2bdb24f117e8d62be5aae08 100644 (file)
@@ -32,67 +32,94 @@ function updateStores() {
 }
 
 function editField(zis) {
-    const tr = zis.parentNode.parentNode;
-    const store_id = document.querySelector("#selected-store").value;
-    const type = tr.querySelector("[data-type]").textContent;
-    const offline = tr.querySelector("input[name=offline]").value;
-    const internet_shop = tr.querySelector("input[name=internet_shop]").value;
-    const write_offs = tr.querySelector("input[name=write_offs]").value;
-
-    const editFields = [
-        offline,
-        internet_shop,
-        write_offs
-    ];
-
-    let succ = true;
-    editFields.forEach((el) => {
-        if (!isNumeric(el)) {
-            succ = false;
-            alert(el + " не число");
-            console.log(el);
+    const tr = zis.closest('tr');
+    const store_id = document.querySelector('#selected-store').value;
+    const type = tr.querySelector('th[data-type]').textContent.trim();
+
+    // Инпуты с исходными значениями
+    const offlineInput     = tr.querySelector(`td[data-offline-type="${type}"] input[name="offline"]`);
+    const internetInput    = tr.querySelector(`td[data-online-type="${type}"] input[name="internet_shop"]`);
+    const writeoffsInput   = tr.querySelector(`td[data-writeoffs-type="${type}"] input[name="write_offs"]`);
+
+    const offlineVal     = offlineInput.value;
+    const internetVal    = internetInput.value;
+    const writeoffsVal   = writeoffsInput.value;
+
+    // валидация
+    [offlineVal, internetVal, writeoffsVal].forEach(v => {
+        if (!isNumeric(v)) {
+            alert(v + ' не число');
+            throw new Error('Некорректное число');
         }
     });
 
-    if (succ) {
-        const p1 = tr.querySelector("[data-p1]");
-        const p2 = tr.querySelector("[data-p2]");
-        const p3 = tr.querySelector("[data-p3]");
-        p1.querySelector('input').value = (p1.dataset.offline > 0 ? Math.round(100.0 * offline / +p1.dataset.offline) : 0);
-        p2.querySelector('input').value = (p2.dataset.online > 0 ? Math.round(100.0 * internet_shop / +p2.dataset.online) : 0);
-        p3.querySelector('input').value = (p3.dataset.writeoffs > 0 ? Math.round(100.0 * write_offs / +p3.dataset.writeoffs) : 0);
-
-        $.ajax({
-            method: "POST",
-            url: '/category-plan/save-fields',
-            data: {
-                year: document.querySelector('#dynamicmodel-year').value,
-                month: document.querySelector('#dynamicmodel-month').value,
-                store_id,
-                type,
-                offline,
-                internet_shop,
-                write_offs,
-                [param26]: token26
-            },
-            dataType: "text",
-            success: function(data) {
-                console.log(data);
-            },
-        });
-    }
+    // ячейки с процентами по тому же type
+    const p1Cell = tr.querySelector(`td[data-offline][data-offline-type="${type}"]`);
+    const p2Cell = tr.querySelector(`td[data-online][data-online-type="${type}"]`);
+    const p3Cell = tr.querySelector(`td[data-writeoffs][data-writeoffs-type="${type}"]`);
+
+    const p1Input = p1Cell.querySelector('input');
+    const p2Input = p2Cell.querySelector('input');
+    const p3Input = p3Cell.querySelector('input');
+
+    // пересчитываем %
+    p1Input.value = p1Cell.dataset.offline > 0
+        ? (100 * offlineVal / +p1Cell.dataset.offline).toFixed(2)
+        : 0;
+    p2Input.value = p2Cell.dataset.online > 0
+        ? (100 * internetVal / +p2Cell.dataset.online).toFixed(2)
+        : 0;
+    p3Input.value = p3Cell.dataset.writeoffs > 0
+        ? (100 * writeoffsVal / +p3Cell.dataset.writeoffs).toFixed(2)
+        : 0;
+
+    // сохраняем на сервере
+    $.ajax({
+        method: "POST",
+        url: '/category-plan/save-fields',
+        data: {
+            year:   document.querySelector('#dynamicmodel-year').value,
+            month:  document.querySelector('#dynamicmodel-month').value,
+            store_id,
+            type,
+            offline:       offlineVal,
+            internet_shop: internetVal,
+            write_offs:    writeoffsVal,
+            [param26]:     token26
+        },
+        dataType: "text"
+    });
 }
 
 function editProcent(zis, num) {
-    const tr = zis.parentNode.parentNode;
-    const p1 = tr.querySelector("[data-p1]");
-    const p2 = tr.querySelector("[data-p2]");
-    const p3 = tr.querySelector("[data-p3]");
+    const tr   = zis.closest('tr');
+    const type = tr.querySelector('th[data-type]').textContent.trim();
+
+    const p1Cell = tr.querySelector(`td[data-offline][data-offline-type="${type}"]`);
+    const p2Cell = tr.querySelector(`td[data-online][data-online-type="${type}"]`);
+    const p3Cell = tr.querySelector(`td[data-writeoffs][data-writeoffs-type="${type}"]`);
+
     switch (num) {
-        case 1: tr.querySelector("input[name=offline]").value = Math.round(p1.querySelector('input').value / 100.0 * (+p1.dataset.offline)); break;
-        case 2: tr.querySelector("input[name=internet_shop]").value = Math.round(p2.querySelector('input').value / 100.0 * (+p2.dataset.online)); break;
-        case 3: tr.querySelector("input[name=write_offs]").value = Math.round(p3.querySelector('input').value / 100.0 * (+p3.dataset.writeoffs)); break;
+        case 1: {
+            const pct = +p1Cell.querySelector('input').value;
+            const newVal = Math.round(pct / 100 * +p1Cell.dataset.offline);
+            tr.querySelector(`td[data-offline-type="${type}"] input[name="offline"]`).value = newVal;
+            break;
+        }
+        case 2: {
+            const pct = +p2Cell.querySelector('input').value;
+            const newVal = Math.round(pct / 100 * +p2Cell.dataset.online);
+            tr.querySelector(`td[data-online-type="${type}"] input[name="internet_shop"]`).value = newVal;
+            break;
+        }
+        case 3: {
+            const pct = +p3Cell.querySelector('input').value;
+            const newVal = Math.round(pct / 100 * +p3Cell.dataset.writeoffs);
+            tr.querySelector(`td[data-writeoffs-type="${type}"] input[name="write_offs"]`).value = newVal;
+            break;
+        }
     }
+
     editField(zis);
 }