]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Merge branch 'develop' into feature_zozirova_erp-359_logic_of_calculation_for_month
authormarina <m.zozirova@gmail.com>
Tue, 15 Apr 2025 07:23:51 +0000 (10:23 +0300)
committermarina <m.zozirova@gmail.com>
Tue, 15 Apr 2025 07:23:51 +0000 (10:23 +0300)
1  2 
erp24/views/auto-planogramma/index.php

index d330c0bd27ff592f7b2462a33befb87133166de5,0000000000000000000000000000000000000000..7201c532b48286ecc48889df6d478dbc61298bbe
mode 100644,000000..100644
--- /dev/null
@@@ -1,350 -1,0 +1,336 @@@
-             <div class="row">
-                 <div class="d-flex justify-content-center">
-                     <button class="btn btn-light" type="button" data-bs-toggle="collapse"
-                             data-bs-target="#filter-container"
-                             aria-expanded="true">
-                         <span data-bs-collapse-icon="open">▲</span>
-                         <span data-bs-collapse-icon="closed">▼</span>
-                     </button>
-                 </div>
 +<?php
 +
 +use kartik\grid\GridView;
 +use kartik\select2\Select2;
 +use yii\helpers\ArrayHelper;
 +use yii\helpers\Html;
 +use yii_app\helpers\DateHelper;
 +use yii_app\records\Admin;
 +use yii_app\records\AdminGroup;
 +use yii_app\records\StoreCityList;
 +use yii_app\records\StoreDynamic;
 +use yii_app\records\StoreType;
 +use sjaakp\bandoneon\Bandoneon;
 +use yii\jui\Accordion;
 +
 +/* @var $categories \yii_app\records\Products1cNomenclature */
 +
 +
 +use yii\data\ArrayDataProvider;
 +
 +$tooltipText = "Оффлайн: 50&#10;Флаумак (off-line): 20&#10;Флаумак (on-line): 10&#10;Флаумак (market): 10&#10;Изумительная (off-line): 30&#10;Списания: 20"; ?>
 +
 +<h1 class="ms-3 mb-4"><?= Html::encode("Автопланограмма") ?></h1>
 +<div class="autopolnogramma p-3 px-4">
 +    <div class="filters">
 +        <div class="row">
 +        </div>
 +        <div class="collapse show" id="filter-container">
 +            <div class="row">
 +                <div class="col-md d-flex">
 +                    <?= Select2::widget([
 +                        'name' => 'year-filter',
 +                        'data' => array_combine(range(date('Y') - 5, date('Y') + 5), range(date('Y') - 5, date('Y') + 5)),
 +                        'options' => ['placeholder' => 'Год', 'id' => 'year'],
 +                        'pluginOptions' => ['allowClear' => true],
 +                    ]) ?>
 +                </div>
 +                <div class="col-md d-flex">
 +                    <?= Select2::widget([
 +                        'name' => 'city-filter',
 +                        'data' => ArrayHelper::map(StoreCityList::findAll(['type' => StoreCityList::TYPE_CITY]), 'id', 'name'),
 +                        'options' => ['placeholder' => 'Город', 'id' => 'city'],
 +                        'pluginOptions' => ['allowClear' => true],
 +                    ]) ?>
 +                </div>
 +                <div class="col-md d-flex">
 +                    <?= Select2::widget([
 +                        'name' => 'store-type-filter',
 +                        'data' => ArrayHelper::map(StoreType::find()->orderBy('sequence_number')->all(), 'id', 'name'),
 +                        'options' => ['placeholder' => 'Тип магазина', 'id' => 'store-type', 'style' => 'width: 110%;'],
 +                        'pluginOptions' => ['allowClear' => true],
 +                    ]) ?>
 +                </div>
 +                <div class="col-md d-flex">
 +                    <?= Select2::widget([
 +                        'name' => 'territorial-manager-filter',
 +                        'data' => ArrayHelper::map(
 +                            array_merge(
 +                                Admin::findAll(['group_id' => AdminGroup::GROUP_BUSH_DIRECTOR]),
 +                                Admin::findAll(['id' => StoreDynamic::find()->andWhere(['category' => 3, 'active' => 1])->select('value_int')->column()])
 +                            ),
 +                            'id',
 +                            'name',
 +                        ),
 +                        'options' => ['placeholder' => 'Тер. управляющий', 'id' => 'territorial-manger'],
 +                        'pluginOptions' => ['allowClear' => true],
 +                    ]) ?>
 +                </div>
 +                <div class="col-md d-flex">
 +                    <?= Select2::widget([
 +                        'name' => 'polnogramma-type-filter',
 +                        'data' => ['min' => 'min', 'max' => 'max'],
 +                        'options' => ['placeholder' => 'Тип п-ма', 'id' => 'polnogramma-type'],
 +                        'pluginOptions' => ['allowClear' => true],
 +                    ]) ?>
 +                </div>
 +                <div class="col-md d-flex">
 +                    <?= Html::submitButton('Применить', ['class' => 'btn btn-apply btn-primary', 'style' => 'width:100%']); ?>
 +                </div>
 +            </div>
 +            <div class="row py-3">
 +                <div class="col-md d-flex">
 +                    <?= Select2::widget([
 +                        'name' => 'week-filter',
 +                        'data' => ['1' => '1', '2' => '2'],
 +                        'options' => ['placeholder' => 'Неделя', 'id' => 'week'],
 +                        'pluginOptions' => ['allowClear' => true],
 +                    ]) ?>
 +                </div>
 +                <div class="col-md d-flex">
 +                    <?= Select2::widget([
 +                        'name' => 'region-filter',
 +                        'data' => ArrayHelper::map(StoreCityList::findAll(['type' => StoreCityList::TYPE_REGION]), 'id', 'name'),
 +                        'options' => ['placeholder' => 'Регион', 'id' => 'region'],
 +                        'pluginOptions' => ['allowClear' => true],
 +                    ]) ?>
 +                </div>
 +                <div class="col-md d-flex">
 +                </div>
 +                <div class="col-md d-flex">
 +                    <?= Select2::widget([
 +                        'name' => 'bush_chef_florist',
 +                        'value' => null,
 +                        'data' => ArrayHelper::map(Admin::findAll(['group_id' => AdminGroup::GROUP_BUSH_CHEF_FLORIST]), 'id', 'name'),
 +                        'options' => [
 +                            'placeholder' => 'Кустовой шеф-флорист',
 +                            'class' => 'form-select',
 +                            'id' => 'bush_chef_florist',
 +                        ],
 +                        'pluginOptions' => [
 +                            'allowClear' => true,
 +                        ],
 +                    ]); ?>
 +                </div>
 +                <div class="col-md d-flex">
 +                </div>
 +                <div class="col-md d-flex"></div>
 +            </div>
 +            <div class="row">
 +                <div class="col-md d-flex">
 +                    <?= Html::label('Месяца-месяцы') ?>
 +                </div>
 +                <div class="col-md d-flex">
 +                    <?= Select2::widget([
 +                        'name' => 'district-filter',
 +                        'data' => ArrayHelper::map(StoreCityList::findAll(['type' => StoreCityList::TYPE_DISTRICT]), 'id', 'name'),
 +                        'options' => ['placeholder' => 'Район', 'id' => 'district'],
 +                        'pluginOptions' => ['allowClear' => true],
 +                    ]) ?>
 +                </div>
 +                <div class="col-md d-flex"></div>
 +                <div class="col-md d-flex"></div>
 +                <div class="col-md d-flex"></div>
 +                <div class="col-md d-flex">
 +                    <?= Html::button('Сохранить', ['class' => 'btn btn-success btn-save', 'style' => 'width:100%']); ?>
 +                </div>
 +            </div>
-                     <div class="buttons d-flex">
-                         <?= Html::a('Auto', '#', ['class' => 'btn btn-success ml-auto']) ?>
-                         <?= Html::a('Corrected', '#', ['class' => 'btn btn-success ml-auto']) ?>
++        </div>
++        <div class="row">
++            <div class="d-flex justify-content-center">
++                <button class="btn btn-light" type="button" data-bs-toggle="collapse"
++                        data-bs-target="#filter-container"
++                        aria-expanded="true">
++                    <span data-bs-collapse-icon="open">▲</span>
++                    <span data-bs-collapse-icon="closed">▼</span>
++                </button>
 +            </div>
 +        </div>
 +    </div>
 +    <div class="table-wrapper">
 +        <table class="table">
 +            <thead>
 +            <tr class="head">
 +                <th scope="col" style="text-align: left !important;">
 +                    <?= Html::label("год: 2025 неделя: 05") ?><br>
 +                    <?= Html::label("январь - февраль") ?><br>
 +                    <?= Html::label("Тип п-ма:") ?><br>
 +                    <?= Html::label("Город:") ?><br>
 +                    <?= Html::label("Регион:") ?><br>
 +                    <?= Html::label("Район:") ?><br>
 +                    <?= Html::label("Тип магазина:") ?><br>
 +                    <?= Html::label("Тер. Уп.:") ?><br>
 +                    <?= Html::label("КШФ:") ?><br>
-                 let isVisible = this.parentElement.nextElementSibling?.style.display === "table-row";
++                    <div class="buttons d-flex justify-content-end">
++                        <?= Html::a('Auto', '#', ['class' => 'btn btn-success ms-1']) ?>
++                        <?= Html::a('Corrected', '#', ['class' => 'btn btn-success ms-1']) ?>
 +                    </div>
 +                </th>
 +
 +                <?php foreach ($stores as $store) { ?>
 +                    <th scope="col" class="fixed-column">
 +                        <?= Html::label($store, null, [
 +                            'style' => 'writing-mode: sideways-lr; text-align: center; white-space: nowrap; 
 +                                font-weight: bold; transform-origin: left bottom; padding-right: 7%;'
 +                        ]) ?>
 +                    </th>
 +                <?php } ?>
 +            </tr>
 +            </thead>
 +            <tbody>
 +            <?php
 +            $groupedCategories = [];
 +
 +            // Группируем данные по категориям и подкатегориям
 +            foreach ($categories as $item) {
 +                $groupedCategories[$item['category']][$item['subcategory']] = $item['products'];
 +            }
 +
 +            foreach ($groupedCategories as $category => $subcategories): ?>
 +                <tr>
 +                    <td class="category">
 +                        <a class="list-group-item list-group-item-action">
 +                            <?= Html::encode($category) ?> ▲
 +                        </a>
 +                    </td>
 +                </tr>
 +
 +                <?php foreach ($subcategories as $subcategory => $products): ?>
 +                    <tr>
 +                        <td style="position: relative; display: flex; justify-content: flex-end;" class="subcategory">
 +                            <a class="list-group-item list-group-item-action" style="width: 95%;">
 +                                <?= Html::encode($subcategory) ?> ▶
 +                            </a>
 +                        </td>
 +                    </tr>
 +                    <?php
 +                    $products = is_string($products) ? json_decode($products, true) : $products;
 +                    ?>
 +                    <?php foreach ($products as $product): ?>
 +                        <tr>
 +                            <td style="position: relative; display: flex; justify-content: flex-end;">
 +                                <a class="list-group-item list-group-item-action" style="width: 90%;">
 +                                    <?= Html::encode($product) ?>
 +                                </a>
 +                            </td>
 +
 +                            <?php foreach ($stores as $store): ?>
 +                                <td class="items">
 +                                    <div style="display: flex; align-items: center;">
 +                                        <?= Html::input('text', '', 50, [
 +                                            'class' => 'btn btn-primary input',
 +                                            'data-bs-toggle' => 'tooltip',
 +                                            'data-bs-placement' => 'top',
 +                                            'title' => $tooltipText,
 +                                        ]) ?>
 +                                        <button style="border: none; background: transparent; cursor: pointer; margin-left: 5px;">
 +                                            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
 +                                                <path d="M20 11v5a1 1 0 0 1-2 0v-4H7.414l1.293 1.293a1 1 0 0 1-1.414 1.414l-3-3a1 1 0 0 1 0-1.416l3-3a1 1 0 1 1 1.414 1.416L7.414 10H19a1 1 0 0 1 1 1z"
 +                                                      fill="grey" stroke="none"/>
 +                                            </svg>
 +                                        </button>
 +                                    </div>
 +                                </td>
 +                            <?php endforeach; ?>
 +                        </tr>
 +                    <?php endforeach; ?>
 +                <?php endforeach; ?>
 +            <?php endforeach; ?>
 +            </tbody>
 +        </table>
 +    </div>
 +</div>
 +<script>
 +    document.addEventListener("DOMContentLoaded", function () {
 +        // Изначально скрываем все строки, кроме .category и .head
 +        document.querySelectorAll("tr").forEach(row => {
 +            if (!row.querySelector(".category") && !row.classList.contains("head")) {
 +                row.style.display = "none";
 +            }
 +        });
 +
 +        // Обработчик кликов для категорий
 +        document.querySelectorAll(".category").forEach(category => {
 +            category.addEventListener("click", function () {
-                 // Закрываем все вложенные элементы (subcategory + items)
 +                let nextRow = this.parentElement.nextElementSibling;
++                let isVisible = nextRow?.style.display === "table-row";
 +
-                 // Если категория закрывалась, то открываем только подкатегории
++                // Закрываем все элементы внутри категории
 +                while (nextRow && !nextRow.querySelector(".category")) {
 +                    nextRow.style.display = "none";
 +                    nextRow = nextRow.nextElementSibling;
 +                }
 +
-         let activeSubcategory = null; // Текущая открытая подкатегория
++                // Если категория была закрыта — открываем подкатегории
 +                if (!isVisible) {
 +                    nextRow = this.parentElement.nextElementSibling;
 +                    while (nextRow && !nextRow.querySelector(".category")) {
 +                        if (nextRow.querySelector(".subcategory")) {
 +                            nextRow.style.display = "table-row";
 +                        }
 +                        nextRow = nextRow.nextElementSibling;
 +                    }
 +                }
 +            });
 +        });
 +
-             subcategory.addEventListener("click", function () {
-                 let isOpening = activeSubcategory !== this;
 +        // Обработчик кликов для подкатегорий
 +        document.querySelectorAll(".subcategory").forEach(subcategory => {
-                 // Закрываем текущую открытую подкатегорию и её items
-                 if (activeSubcategory) {
-                     let prevRow = activeSubcategory.parentElement.nextElementSibling;
-                     while (prevRow && !prevRow.querySelector(".subcategory") && !prevRow.querySelector(".category")) {
-                         prevRow.style.display = "none";
-                         prevRow = prevRow.nextElementSibling;
-                     }
-                 }
++            subcategory.addEventListener("click", function (event) {
++                event.stopPropagation(); // Чтобы клик по подкатегории не закрывал категорию
 +
-                 // Если открываем новую, показываем её items
-                 if (isOpening) {
-                     let nextRow = this.parentElement.nextElementSibling;
-                     while (nextRow && !nextRow.querySelector(".subcategory") && !nextRow.querySelector(".category")) {
-                         nextRow.style.display = "table-row";
-                         nextRow = nextRow.nextElementSibling;
-                     }
-                     activeSubcategory = this;
-                 } else {
-                     activeSubcategory = null;
++                let nextRow = this.parentElement.nextElementSibling;
++                let isVisible = nextRow?.style.display === "table-row";
 +
++                // Переключаем видимость только айтемов внутри этой подкатегории
++                while (nextRow && !nextRow.querySelector(".subcategory") && !nextRow.querySelector(".category")) {
++                    nextRow.style.display = isVisible ? "none" : "table-row";
++                    nextRow = nextRow.nextElementSibling;
 +                }
 +            });
 +        });
 +    });
 +</script>
 +
 +<style>
 +    /* Стили для таблицы */
 +    .table {
 +        width: 100%;
 +        table-layout: fixed; /* Это позволяет фиксировать ширину колонок */
 +        overflow-x: auto; /* Это позволяет прокручивать таблицу по горизонтали */
 +        border-collapse: collapse; /* Чтобы не было промежутков между ячейками */
 +    }
 +
 +    /* Первая колонка будет фиксированной */
 +    .fixed-column {
 +        width: 170px; /* Устанавливаем фиксированную ширину для первой колонки */
 +        white-space: nowrap; /* Запрещаем перенос текста в ячейке */
 +        border-right: 1px solid #ddd; /* Вертикальная линия между колонками */
 +    }
 +
 +    /* Для остальных колонок можно установить фиксированную ширину, если нужно */
 +    th, td {
 +        width: 300px; /* Пример для остальных колонок */
 +        text-align: center; /* Центрируем текст */
 +        padding: 10px; /* Немного отступов для улучшения внешнего вида */
 +        border-right: 1px solid #ddd; /* Вертикальная линия между колонками */
 +    }
 +
 +    .items .input {
 +        width: 100%;
 +    }
 +
 +    .table-wrapper {
 +        overflow-x: auto;
 +        max-width: 100%;
 +        position: relative;
 +    }
 +
 +    .fixed-column {
 +        position: sticky;
 +        left: 0;
 +        background: white;
 +        z-index: 2;
 +        border-right: 2px solid #ddd;
 +    }
 +</style>