use yii\db\Query;
use yii\helpers\ArrayHelper;
use yii_app\records\CityStore;
+use yii_app\records\CityStoreParams;
use yii_app\services\AutoPlannogrammaService;
class AutoPlannogrammaController extends BaseController
new Expression("
CASE
WHEN category ILIKE 'срезка' THEN 'Срезка'
- WHEN category ILIKE 'горшечные растения' THEN 'Горшечные растения'
+ WHEN category ILIKE 'горшечные_растения' THEN 'Горшечные растения'
WHEN category ILIKE 'сухоцветы' THEN 'Сухоцветы'
ELSE 'Остальные категории'
END AS category
"),
'subcategory',
- new Expression('json_agg(name) AS products'),
])
+ ->andWhere(['is not', 'subcategory', null])
->from('products_1c_nomenclature')
->groupBy(['category', 'subcategory'])
->orderBy([
new Expression("
CASE
WHEN category ILIKE 'срезка' THEN 1
- WHEN category ILIKE 'горшечные растения' THEN 2
+ WHEN category ILIKE 'горшечные_растения' THEN 2
WHEN category ILIKE 'сухоцветы' THEN 3
ELSE 4
END
]);
}
- public function actionCalculating()
+ public function actionGetProducts(string $category, string $subcategory): array
{
- $request = Yii::$app->request;
- $filters = [
- 'category' => $request->get('category'),
- 'subcategory' => $request->get('subcategory'),
- 'product_name' => $request->get('product_name'),
- 'store_id' => $request->get('store_id'),
- 'plan_date' => $request->get('plan_date'),
- 'type' => $request->get('type'),
- ];
- $dataProvider = new ArrayDataProvider([
- 'allModels' => [],
- 'pagination' => ['pageSize' => 100],
- ]);
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
- if (!empty($filters['plan_date'])) {
- $service = new AutoPlannogrammaService();
- $dataProvider = new ArrayDataProvider([
- 'allModels' => $service->calculateFullGoalChain($filters),
- 'pagination' => ['pageSize' => 100],
- ]);
- }
-
- return $this->render('calculating', [
- 'dataProvider' => $dataProvider,
- 'filters' => $filters,
- ]);
+ return [
+ [
+ 'name' => 'Роза Эквадор 60',
+ 'guid' => '74876785y85',
+ 'values' => [
+ ['count' => 42,
+ 'store_id' => 1,
+ ],
+ [
+ 'count' => 13,
+ 'store_id' => 2,
+ ],
+ ]
+ ],
+ [
+ 'name' => 'Роза Эквадор 50',
+ 'guid' => '74876e785y85',
+ 'values' => [
+ ['count' => 2,
+ 'store_id' => 1,
+ ],
+ [
+ 'count' => 1,
+ 'store_id' => 2,
+ ],
+ ]
+ ],
+ ];
}
- public function actionControl()
+ public function actionGetVisibleStores()
{
- $filters = Yii::$app->request->get();
- $params = [];
- $conditions = [];
+ Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
- if (!empty($filters['product_name'])) {
- $conditions[] = 'p1n.name LIKE :product_name';
- $params[':product_name'] = '%' . $filters['product_name'] . '%';
- }
-
- if (!empty($filters['category'])) {
- $conditions[] = 'p1n.category = :category';
- $params[':category'] = $filters['category'];
- }
-
- if (!empty($filters['subcategory'])) {
- $conditions[] = 'p1n.subcategory = :subcategory';
- $params[':subcategory'] = $filters['subcategory'];
- }
-
- if (!empty($filters['city_name'])) {
- $conditions[] = 'c.name LIKE :city_name';
- $params[':city_name'] = '%' . $filters['city_name'] . '%';
- }
+ $filters = Yii::$app->request->get();
- if (!empty($filters['plan_date'])) {
- $date = \DateTime::createFromFormat('d-m-Y', $filters['plan_date']);
- if ($date) {
- $startDate = $date->format('Y-m-d');
- $endDate = $date->modify('+1 month')->format('Y-m-d');
-
- if ($filters['type'] === 'writeOffs') {
- $conditions[] = 'DATE(w.date) >= :start_date';
- $conditions[] = 'DATE(w.date) < :end_date';
- } else {
- $conditions[] = 'DATE(s.date) >= :start_date';
- $conditions[] = 'DATE(s.date) < :end_date';
- }
+ $query = CityStoreParams::find()
+ ->alias('p')
+ ->joinWith(['store s'])
+ ->select('p.store_id')
+ ->where(['s.visible' => CityStore::IS_VISIBLE]);
+
+ $fields = [
+ 'city' => 's.city_id',
+ 'storeType' => 's.type_id',
+ 'territorialManager' => 's.territorial_manager_id',
+ 'region' => 's.region_id',
+ 'district' => 's.district_id',
+ 'bushChefFlorist' => 's.bush_chef_florist_id',
+ ];
- $params[':start_date'] = $startDate;
- $params[':end_date'] = $endDate;
+ foreach ($fields as $param => $column) {
+ if (!empty($filters[$param])) {
+ $query->andWhere([$column => $filters[$param]]);
}
}
- $where = !empty($conditions) ? 'WHERE ' . implode(' AND ', $conditions) : '';
-
- if (isset($filters['type']) && $filters['type'] === 'writeOffs') {
- $query = Yii::$app->db->createCommand("
- SELECT
- c.name AS city_name,
- p1n.category,
- p1n.subcategory,
- item ->> 'product_id' AS product_id,
- p1n.name AS product_name,
- SUM(CAST(item ->> 'quantity' AS NUMERIC)) AS count,
- SUM(CAST(item ->> 'summ' AS NUMERIC)) AS sum
- FROM write_offs w
- JOIN export_import_table ex ON ex.export_val = w.store_id
- JOIN city_store c ON c.id = ex.entity_id
- JOIN LATERAL jsonb_array_elements(w.items::jsonb) AS item ON true
- LEFT JOIN products_1c_nomenclature p1n ON p1n.id = item ->> 'product_id'
- $where
- GROUP BY w.store_id, c.name, p1n.category, p1n.subcategory, product_id, p1n.name
- ORDER BY w.store_id, p1n.category, p1n.subcategory, p1n.name
- ")->bindValues($params)->queryAll();
- } else {
- $query = Yii::$app->db->createCommand("
- SELECT
- c.name AS city_name,
- p1n.name AS product_name,
- p1n.category,
- p1n.subcategory,
- SUM(CASE
- WHEN s.operation = 'Продажа' THEN sp.quantity
- WHEN s.operation = 'Возврат' THEN -sp.quantity
- ELSE 0
- END) AS count,
- SUM(CASE
- WHEN s.operation = 'Продажа' THEN sp.summ
- WHEN s.operation = 'Возврат' THEN -sp.summ
- ELSE 0
- END) AS sum
- FROM sales s
- LEFT JOIN sales_products sp ON sp.check_id = s.id
- LEFT JOIN products_1c_nomenclature p1n ON p1n.id = sp.product_id
- LEFT JOIN export_import_table ex ON ex.export_val = store_id_1c
- LEFT JOIN city_store c ON c.id = entity_id
- $where
- GROUP BY p1n.name, p1n.category, p1n.subcategory, c.name, c.id
- ORDER BY c.id DESC, category, subcategory, p1n.name
- ")->bindValues($params)->queryAll();
- }
+ return ['store_ids' => $query->column()];
+ }
- $dataProvider = new ArrayDataProvider([
- 'allModels' => $query,
- 'pagination' => ['pageSize' => 20],
- ]);
- return $this->render('control', [
- 'dataProvider' => $dataProvider,
- 'filters' => $filters,
- ]);
- }
public function action1()
{
'pagination' => ['pageSize' => 100],
]);
- // Обработка даты на год и месяц
if (!empty($filters['year']) && !empty($filters['month'])) {
$filters['plan_date'] = $filters['year'] . '-' . str_pad($filters['month'], 2, '0', STR_PAD_LEFT) . '-01';
--- /dev/null
+<?php
+
+use yii\db\Migration;
+
+/**
+ * Handles the creation of table `{{%autoplannagramma}}`.
+ */
+class m250605_201027_create_autoplannagramma_table extends Migration
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function safeUp()
+ {
+ $this->createTable('{{%autoplannogramma}}', [
+ 'id' => $this->primaryKey(),
+ 'week' => $this->integer()->comment('Неделя'),
+ 'year' => $this->integer()->comment('Год'),
+ 'product_id' => $this->string()->comment('GUID продукта'),
+ 'store_id' => $this->integer()->comment('ID магазина'),
+ 'capacity_type' => $this->integer()->comment('Тип планограммы'),
+ 'auto_forecast' => $this->boolean()->comment('Прогнозированное значение'),
+ 'quantity' => $this->integer()->comment('Количество'),
+ 'created_at' => $this->dateTime()->comment('Дата создания'),
+ 'updated_at' => $this->dateTime()->comment('Дата обновления'),
+ 'created_by' => $this->integer()->comment('Автор создания'),
+ 'updated_by' => $this->integer()->comment('Автор обновления'),
+ ]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropTable('{{%autoplannogramma}}');
+ }
+}
+++ /dev/null
-<?php
-
-use kartik\date\DatePicker;
-use kartik\select2\Select2;
-use yii\helpers\ArrayHelper;
-use yii\helpers\Html;
-use yii\widgets\ActiveForm;
-use yii\grid\GridView;
-use yii_app\records\CityStore;
-use yii_app\records\Products1cNomenclature;
-
-/** @var array $filters */
-?>
-
-<div class="filter-form" style="margin-bottom: 20px;">
- <?php $form = ActiveForm::begin(['method' => 'get']); ?>
- <div class="row p-3">
- <div class="col-md">
- <?= $form->field(new \yii\base\DynamicModel(['category' => $filters['category'] ?? '']), 'category')->widget(Select2::class, [
- 'data' => ArrayHelper::map(
- Products1cNomenclature::find()->select('category')->distinct()->asArray()->all(),
- 'category',
- 'category'
- ),
- 'options' => ['placeholder' => 'Категория', 'name' => 'category'],
- 'pluginOptions' => ['allowClear' => true],
- ])->label('Категория') ?>
- </div>
- <div class="col-md">
- <?= $form->field(new \yii\base\DynamicModel(['subcategory' => $filters['subcategory'] ?? '']), 'subcategory')->widget(Select2::class, [
- 'data' => ArrayHelper::map(
- Products1cNomenclature::find()->select('subcategory')->distinct()->asArray()->all(),
- 'subcategory',
- 'subcategory'
- ),
- 'options' => ['placeholder' => 'Подкатегория', 'name' => 'subcategory'],
- 'pluginOptions' => ['allowClear' => true],
- ])->label('Подкатегория') ?>
- </div>
- <div class="col-md">
- <?= $form->field(new \yii\base\DynamicModel(['product_name' => $filters['product_name'] ?? '']), 'product_name')->widget(Select2::class, [
- 'data' => ArrayHelper::map(
- Products1cNomenclature::find()->select('name')->distinct()->asArray()->all(),
- 'name',
- 'name'
- ),
- 'options' => ['placeholder' => 'Название товара', 'name' => 'product_name'],
- 'pluginOptions' => ['allowClear' => true],
- ])->label('Товар') ?>
- </div>
- <div class="col-md">
- <?= $form->field(new \yii\base\DynamicModel(['store_id' => $filters['store_id'] ?? '']), 'store_id')->widget(Select2::class, [
- 'data' => ArrayHelper::map(
- CityStore::findAll(['visible' => CityStore::IS_VISIBLE]),
- 'id',
- 'name'
- ),
- 'options' => ['placeholder' => 'Магазин', 'name' => 'store_id'],
- 'pluginOptions' => ['allowClear' => true],
- ])->label('Магазин') ?>
- </div>
- <div class="col-md">
- <?= $form->field(new \yii\base\DynamicModel(['plan_date' => $filters['plan_date'] ?? '']), 'plan_date')->widget(DatePicker::class, [
- 'pluginOptions' => [
- 'autoclose' => true,
- 'format' => 'dd-mm-yyyy',
- ],
- 'options' => [
- 'class' => 'form-control',
- 'placeholder' => 'Плановая дата',
- 'name' => 'plan_date',
- ],
- ])->label('Плановая дата') ?>
- </div>
- <div class="col-md">
- <?= $form->field(new \yii\base\DynamicModel(['type' => $filters['type'] ?? '']), 'type')->widget(Select2::class, [
- 'data' => [
- 'writeOffs' => 'Списания',
- 'sales' => 'Продажи'
- ],
- 'options' => ['placeholder' => 'Тип', 'name' => 'type'],
- 'pluginOptions' => ['allowClear' => true],
- ])->label('По дефолту продажи!') ?>
- </div>
- <div class="col-md">
- <?= Html::submitButton('Фильтровать', ['class' => 'btn btn-primary']) ?>
- </div>
- <div class="col-md">
- <?= Html::a('Сбросить', ['auto-planogramma/test-sales'], ['class' => 'btn btn-default']) ?>
- </div>
- </div>
-
- <?php ActiveForm::end(); ?>
-</div>
-
-<?= GridView::widget([
- 'dataProvider' => $dataProvider,
- 'columns' => [
- 'category',
- 'subcategory',
- 'product_name',
- 'store_id',
- 'store_name',
- [
- 'attribute' => 'goal',
- 'label' => 'План закупок (RUB)',
- ],
- ],
-]); ?>
+++ /dev/null
-<div class="filter-form" style="margin-bottom: 20px;">
- <?php use kartik\date\DatePicker;
- use kartik\select2\Select2;
- use yii\grid\GridView;
- use yii\helpers\ArrayHelper;
- use yii\helpers\Html;
- use yii\widgets\ActiveForm;
- use yii_app\records\CityStore;
- use yii_app\records\Products1cNomenclature;
-
- $form = ActiveForm::begin(['method' => 'get']); ?>
- <div class="row">
- <div class="col-md">
- <?= Select2::widget([
- 'name' => 'category',
- 'value' => $filters['category'] ?? '',
- 'data' => ArrayHelper::map(
- Products1cNomenclature::find()->select('category')->distinct()->orderBy('category')->asArray()->all(),
- 'category',
- 'category'
- ),
- 'options' => ['placeholder' => 'Категория'],
- 'pluginOptions' => ['allowClear' => true],
- ]) ?>
- </div>
-
- <div class="col-md">
- <?= Select2::widget([
- 'name' => 'subcategory',
- 'value' => $filters['subcategory'] ?? '',
- 'data' => ArrayHelper::map(
- Products1cNomenclature::find()->select('subcategory')->distinct()->orderBy('subcategory')->asArray()->all(),
- 'subcategory',
- 'subcategory'
- ),
- 'options' => ['placeholder' => 'Подкатегория'],
- 'pluginOptions' => ['allowClear' => true],
- ]) ?>
- </div>
- <div class="col-md">
- <?= Select2::widget([
- 'name' => 'product_name',
- 'value' => $filters['product_name'] ?? '',
- 'data' => ArrayHelper::map(
- Products1cNomenclature::find()->select('name')->distinct()->orderBy('name')->asArray()->all(),
- 'name',
- 'name'
- ),
- 'options' => ['placeholder' => 'Товар'],
- 'pluginOptions' => ['allowClear' => true],
- ]) ?>
- </div>
-
-
- <div class="col-md">
- <?= Select2::widget([
- 'name' => 'city_name',
- 'value' => $filters['city_name'] ?? '',
- 'data' => ArrayHelper::map(
- CityStore::find()->select(['name'])->distinct()->orderBy('name')->asArray()->all(),
- 'name',
- 'name'
- ),
- 'options' => ['placeholder' => 'Магазин'],
- 'pluginOptions' => ['allowClear' => true],
- ]) ?>
- </div>
-
- <div class="col-md">
- <?= DatePicker::widget([
- 'name' => 'plan_date',
- 'value' => $filters['plan_date'] ?? '',
- 'pluginOptions' => [
- 'autoclose' => true,
- 'format' => 'dd-mm-yyyy',
- ],
- 'options' => [
- 'class' => 'form-control',
- 'placeholder' => 'Плановая дата',
- ],
- ]) ?>
- </div>
-
- <div class="col-md">
- <?= Select2::widget([
- 'name' => 'type',
- 'value' => $filters['type'] ?? '',
- 'data' => [
- 'writeOffs' => 'Списания',
- 'sales' => 'Продажи'
- ],
- 'options' => ['placeholder' => 'Тип'],
- 'pluginOptions' => ['allowClear' => true],
- ]) ?>
- </div>
-
-
- <div class="col-md">
- <?= Html::submitButton('Фильтровать', ['class' => 'btn btn-primary']) ?>
- </div>
- <div class="col-md">
- <?= Html::a('Сбросить', ['auto-planogramma/sales'], ['class' => 'btn btn-default']) ?>
- </div>
- </div>
- <?php ActiveForm::end(); ?>
-</div>
-
-<?= GridView::widget([
- 'dataProvider' => $dataProvider,
- 'columns' => [
- 'category',
- 'subcategory',
- ['attribute' => 'product_name', 'label' => 'Товар'],
- ['attribute' => 'city_name', 'label' => 'Магазин'],
- ['attribute' => 'count', 'label' => 'Кол-во'],
- ['attribute' => 'sum', 'label' => 'Сумма'],
- ],
-]) ?>
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
+use yii\web\View;
use yii_app\helpers\DateHelper;
use yii_app\records\Admin;
use yii_app\records\AdminGroup;
use yii\data\ArrayDataProvider;
-$tooltipText = "Оффлайн: 50 Флаумак (off-line): 20 Флаумак (on-line): 10 Флаумак (market): 10 Изумительная (off-line): 30 Списания: 20"; ?>
+$tooltipText = "Оффлайн: 50 Флаумак (off-line): 20 Флаумак (on-line): 10 Флаумак (market): 10 Изумительная (off-line): 30 Списания: 20";
+$this->registerJsFile('/js/autoplannogramma/autoplannogramma.js', ['position' => View::POS_END]);
+?>
<h1 class="ms-3 mb-4"><?= Html::encode("Автопланограмма") ?></h1>
<div class="autopolnogramma p-3 px-4">
</div>
<div class="col-md d-flex">
</div>
- <div class="col-md d-flex"></div>
+ <div class="col-md d-flex">
+ <?= Html::submitButton('Сбросить', ['class' => 'btn btn-reset btn-warning', 'style' => 'width:100%']); ?>
+ </div>
</div>
<div class="row">
<div class="col-md d-flex">
</div>
</th>
- <?php foreach ($stores as $store) { ?>
+ <?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%;'
+ font-weight: bold; transform-origin: left bottom; padding-right: 7%;'
]) ?>
</th>
- <?php } ?>
+ <?php endforeach; ?>
</tr>
</thead>
- <tbody>
+ <tbody id="autoplannogramma">
<?php
$groupedCategories = [];
-
- // Группируем данные по категориям и подкатегориям
foreach ($categories as $item) {
- $groupedCategories[$item['category']][$item['subcategory']] = $item['products'];
+ $groupedCategories[$item['category']][] = $item['subcategory'];
}
+ ?>
- foreach ($groupedCategories as $category => $subcategories): ?>
+ <?php foreach ($groupedCategories as $category => $subcategories): ?>
<tr>
<td class="category">
<a class="list-group-item list-group-item-action">
<?= Html::encode($category) ?> ▲
</a>
</td>
+ <?php foreach ($stores as $id => $storeName): ?>
+ <td data-store-id="<?= $id ?>" data-category="<?=$category?>"></td>
+ <?php endforeach; ?>
</tr>
- <?php foreach ($subcategories as $subcategory => $products): ?>
+ <?php foreach ($subcategories as $subcategory): ?>
<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%;">
+ <a href="#" class="list-group-item list-group-item-action subcategory-link"
+ style="width: 95%;"
+ data-category="<?= Html::encode($category) ?>"
+ data-subcategory="<?= Html::encode($subcategory) ?>">
<?= Html::encode($subcategory) ?> ▶
</a>
</td>
+ <?php foreach ($stores as $id => $storeName): ?>
+ <td data-store-id="<?= $id ?>" data-category="<?= $category?>" data-subcategory="<?= $subcategory ?>"></td>
+ <?php endforeach; ?>
</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 () {
- let nextRow = this.parentElement.nextElementSibling;
- let isVisible = nextRow?.style.display === "table-row";
-
- // Закрываем все элементы внутри категории
- while (nextRow && !nextRow.querySelector(".category")) {
- nextRow.style.display = "none";
- nextRow = nextRow.nextElementSibling;
- }
-
- // Если категория была закрыта — открываем подкатегории
- if (!isVisible) {
- nextRow = this.parentElement.nextElementSibling;
- while (nextRow && !nextRow.querySelector(".category")) {
- if (nextRow.querySelector(".subcategory")) {
- nextRow.style.display = "table-row";
- }
- nextRow = nextRow.nextElementSibling;
- }
- }
- });
- });
-
- // Обработчик кликов для подкатегорий
- document.querySelectorAll(".subcategory").forEach(subcategory => {
- subcategory.addEventListener("click", function (event) {
- event.stopPropagation(); // Чтобы клик по подкатегории не закрывал категорию
-
- 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>
/* Стили для таблицы */
--- /dev/null
+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 () {
+ let nextRow = this.parentElement.nextElementSibling;
+ let isVisible = nextRow?.style.display === "table-row";
+
+ // Закрываем все элементы внутри категории
+ while (nextRow && !nextRow.querySelector(".category")) {
+ nextRow.style.display = "none";
+ nextRow = nextRow.nextElementSibling;
+ }
+
+ // Если категория была закрыта — открываем подкатегории
+ if (!isVisible) {
+ nextRow = this.parentElement.nextElementSibling;
+ while (nextRow && !nextRow.querySelector(".category")) {
+ if (nextRow.querySelector(".subcategory")) {
+ nextRow.style.display = "table-row";
+ }
+ nextRow = nextRow.nextElementSibling;
+ }
+ }
+ });
+ });
+
+ // Обработчик кликов для подкатегорий
+ document.querySelectorAll(".subcategory").forEach(subcategory => {
+ subcategory.addEventListener("click", function (event) {
+ event.stopPropagation(); // Чтобы клик по подкатегории не закрывал категорию
+
+ 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;
+ }
+ });
+ });
+});
+
+$('.subcategory-link').on('click', function (e) {
+ e.preventDefault();
+
+ const $link = $(this);
+ const category = $link.data('category');
+ const subcategory = $link.data('subcategory');
+ const $row = $link.closest('tr');
+
+ $.ajax({
+ url: '/auto-plannogramma/get-products',
+ type: 'GET',
+ data: {
+ category: category,
+ subcategory: subcategory
+ },
+ success: function (response) {
+ // Удаляем предыдущие строки
+ $row.nextAll('tr.inserted-row').remove();
+
+ response.forEach(item => {
+ const tr = $('<tr class="inserted-row"></tr>');
+
+ // Подкатегория
+ const subcategoryTd = $(`
+ <td class="subcategory" style="display: flex; justify-content: flex-end;">
+ <a href="#" class="list-group-item list-group-item-action subcategory-link"
+ style="width: 90%;"
+ data-category="${category}" data-subcategory="${subcategory}">
+ ${item.name}
+ </a>
+ </td>
+ `);
+ tr.append(subcategoryTd);
+
+ // Карта store_id => count
+ const valuesMap = {};
+ item.values.forEach(val => {
+ valuesMap[val.store_id] = {
+ count: val.count,
+ guid: item.guid
+ };
+ });
+
+ // Берём колонку из текущей строки, чтобы соблюсти порядок
+ $row.find('td[data-store-id]').each(function () {
+ const td = $(this);
+ const storeId = td.data('store-id');
+ const val = valuesMap[storeId] ?? { count: '', guid: '' };
+
+ const newTd = $(`
+ <td data-store-id="${storeId}">
+ <div style="display: flex; align-items: center;">
+ <input type="text"
+ class="btn btn-primary input"
+ value="${val.count}"
+ data-guid="${val.guid}"
+ data-store_id="${storeId}"
+ data-bs-toggle="tooltip"
+ data-bs-placement="top"
+ data-original-value="${val.count}"
+ style="width: 100%; padding: 0.375rem 0.75rem; font-size: 1rem; line-height: 1.5; border-radius: 0.375rem; border: 1px solid #0d6efd;">
+ <button class="reject-btn" 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>
+ `);
+
+ tr.append(newTd);
+ });
+
+ $row.after(tr);
+ });
+ },
+ error: function (xhr) {
+ alert('Ошибка: ' + xhr.responseText);
+ }
+ });
+});
+
+$('#autoplannogramma').on('change, input', '.input', function () {
+ const $input = $(this);
+ const newValue = $input.val();
+console.log(3)
+ const $td = $input.closest('td');
+ const $svg = $td.find('svg');
+
+ $svg.find('path').attr('fill', 'red');
+});
+
+$('#autoplannogramma').on('click', '.reject-btn', function () {
+ const $button = $(this);
+ const $td = $button.closest('td');
+ const $input = $td.find('input.input');
+ const $svg = $td.find('svg');
+
+ const originalValue = $input.data('original-value');
+
+ if (originalValue !== undefined) {
+ $input.val(originalValue);
+ $svg.find('path').attr('fill', 'grey');
+ }
+});
+
+function getFilterData() {
+ return {
+ year: $('#year').val(),
+ city: $('#city').val(),
+ storeType: $('#store-type').val(),
+ territorialManager: $('#territorial-manger').val(),
+ polnogrammaType: $('#polnogramma-type').val(),
+ week: $('#week').val(),
+ region: $('#region').val(),
+ bushChefFlorist: $('#bush_chef_florist').val(),
+ district: $('#district').val(),
+ };
+}
+
+// Скрываем ячейки магазинов, не подходящих по фильтру
+function applyStoreFilter() {
+ const filterData = getFilterData();
+
+ $.ajax({
+ url: '/auto-plannogramma/get-visible-stores',
+ type: 'GET',
+ data: filterData,
+ success: function (response) {
+ const allowedStoreIds = response.store_ids.map(id => String(id));
+
+ $('td[data-store-id], th[data-store-id]').each(function () {
+ const storeId = $(this).data('store-id').toString();
+ if (!allowedStoreIds.includes(storeId)) {
+ $(this).hide(); // скрываем
+ } else {
+ $(this).show(); // показываем нужное
+ }
+ });
+ },
+ error: function (xhr) {
+ console.error('Ошибка при фильтрации магазинов:', xhr.responseText);
+ }
+ });
+}
+
+// Показываем всё обратно при сбросе
+function resetStoreFilter() {
+ $('td[data-store-id], th[data-store-id]').show(); // показываем все
+}
+
+// Вешаем события
+$('.btn-apply').on('click', function () {
+ applyStoreFilter();
+});
+
+$('.btn-reset').on('click', function () {
+ // Сброс значений фильтров
+ $('#year, #city, #store-type, #territorial-manger, #polnogramma-type, #week, #region, #bush_chef_florist, #district').val('');
+
+ resetStoreFilter();
+});
+
+
+
+