From: fomichev Date: Fri, 17 Apr 2026 09:23:38 +0000 (+0300) Subject: Фикс по js X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=a509e7abec9d35f67d6709d317ff0386a3b0a1cf;p=erp24_rep%2Fyii-erp24%2F.git Фикс по js --- diff --git a/docs/jira/ERP-300J/test-plan.md b/docs/jira/ERP-300J/test-plan.md new file mode 100644 index 00000000..d7c6ccd8 --- /dev/null +++ b/docs/jira/ERP-300J/test-plan.md @@ -0,0 +1,389 @@ +План ручного тестирования — ERP-300J / Справочник закупщика + +Ветка: feature_fomichev_ERP-300J_suppliers_dict +Разделы: Поставщики · Производители + Плантации · Маркировка · Маппинг товаров + +--- +0. Предусловия + +- Миграции применены: m260408_* (5 таблиц) + m260408_100500_* (junction) + m260409_120000_* (RBAC) +- Пользователь авторизован и имеет права на раздел buyer-reference +- Есть тестовые данные в products_1c_nomenclature (несколько товаров с category/subcategory/species) + + --- +1. Главная страница — 4 вкладки + +┌─────┬───────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├─────┼────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│ 1.1 │ Открыть /buyer-reference │ Страница загружается, видны 4 таба: Поставщики / Производители и плантации / Маркировка / Маппинг товаров │ +├─────┼────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│ 1.2 │ Переключаться между вкладками │ Каждая вкладка подгружает контент без перезагрузки страницы │ +├─────┼────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│ 1.3 │ Обновить страницу на вкладке N │ Активная вкладка остаётся активной (если сохраняется в URL-хэше) │ +└─────┴────────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +--- +2. Вкладка «Поставщики» + +2.1 Создание + +┌───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤ +│ 2.1.1 │ Нажать «Добавить поставщика», заполнить все поля корректно (name, тип, валюта, срок поставки) → Сохранить │ Запись появляется в таблице, тост «Поставщик создан» │ +├───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤ +│ 2.1.2 │ Создать поставщика с существующим именем │ Ошибка: «Поставщик уже существует» │ +├───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤ +│ 2.1.3 │ Отправить форму с пустым именем │ Ошибка валидации на поле name │ +├───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤ +│ 2.1.4 │ Ввести lead_time_days = -1 │ Ошибка: «Срок поставки должен быть >= 0» │ +├───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤ +│ 2.1.5 │ Проверить дропдауны Тип (2 опции) и Валюта (3 опции) │ Варианты: local/international; RUB/EUR/USD │ +└───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────┘ + +2.2 Редактирование + +┌───────┬───────────────────────────────────────────────────┬─────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼───────────────────────────────────────────────────────────┼─────────────────────────────────────────────┤ +│ 2.2.1 │ Нажать «Редактировать» на существующем поставщике │ Модалка открывается с заполненными данными │ +├───────┼───────────────────────────────────────────────────────────┼─────────────────────────────────────────────┤ +│ 2.2.2 │ Изменить name → Сохранить │ Таблица обновляется, новое имя отображается │ +├───────┼───────────────────────────────────────────────────────────┼─────────────────────────────────────────────┤ +│ 2.2.3 │ Попытаться сохранить имя другого существующего поставщика │ Ошибка уникальности │ +└───────┴───────────────────────────────────────────────────────────┴─────────────────────────────────────────────┘ + +2.3 Деактивация (soft delete + каскад) + +┌───────┬─────────────────────────────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼─────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┤ +│ 2.3.1 │ Деактивировать поставщика без связанных маркировок и маппингов │ Тост: «деактивирован. Связанных записей: маркировки — 0, маппинги — 0» │ +├───────┼─────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┤ +│ 2.3.2 │ Деактивировать поставщика у которого есть активные маркировки (создать заранее) │ Тост с корректным счётчиком: «маркировки — N» │ +├───────┼─────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┤ +│ 2.3.3 │ Проверить в БД / вкладке «Маркировка», что связанные маркировки стали is_active = false │ Маркировки деактивированы │ +├───────┼─────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┤ +│ 2.3.4 │ Деактивировать уже неактивного поставщика │ Ошибка: «Поставщик уже деактивирован» │ +└───────┴─────────────────────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────┘ + +2.4 Фильтрация + +┌───────┬────────────────────────────────────────┬────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼────────────────────────────────────────┼────────────────────────────────────────────┤ +│ 2.4.1 │ Ввести текст в поле поиска по name │ Таблица фильтруется │ +├───────┼────────────────────────────────────────┼────────────────────────────────────────────┤ +│ 2.4.2 │ Фильтр по типу (local / international) │ Показываются только соответствующие записи │ +└───────┴────────────────────────────────────────┴────────────────────────────────────────────┘ + +--- +3. Вкладка «Производители и плантации» + +3.1 Производители — Создание / Редактирование + +┌───────┬──────────────────────────────────────────────┬──────────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼──────────────────────────────────────────────┼──────────────────────────────────────────────────────────┤ +│ 3.1.1 │ Создать производителя с уникальным именем │ Запись в таблице, тост «Производитель создан» │ +├───────┼──────────────────────────────────────────────┼──────────────────────────────────────────────────────────┤ +│ 3.1.2 │ Создать производителя с дублирующимся именем │ Ошибка: «Производитель с таким названием уже существует» │ +├───────┼──────────────────────────────────────────────┼──────────────────────────────────────────────────────────┤ +│ 3.1.3 │ Отредактировать имя │ Таблица обновляется │ +└───────┴──────────────────────────────────────────────┴──────────────────────────────────────────────────────────┘ + +3.2 Производители — Деактивация (блокировка) + +┌───────┬───────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼─────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│ 3.2.1 │ Деактивировать производителя без активных маркировок │ Тост с количеством деактивированных плантаций │ +├───────┼─────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│ 3.2.2 │ Деактивировать производителя с активными маркировками │ Ошибка: «Нельзя деактивировать производителя: есть активные маркировки. Сначала деактивируйте их.» │ +├───────┼─────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│ 3.2.3 │ В БД проверить, что плантации производителя стали is_active = false │ Каскад сработал корректно │ +└───────┴─────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +3.3 Плантации + +┌───────┬────────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────┤ +│ 3.3.1 │ Создать плантацию через кнопку «Добавить плантацию» │ В форме доступен выпадающий список активных производителей │ +├───────┼────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────┤ +│ 3.3.2 │ Создать плантацию через кнопку «+» на строке производителя │ Поле producer_id предзаполнено │ +├───────┼────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────┤ +│ 3.3.3 │ Редактировать плантацию │ Данные сохраняются │ +├───────┼────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────┤ +│ 3.3.4 │ Деактивировать плантацию без связанных маркировок │ Тост «Плантация деактивирована» │ +├───────┼────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────┤ +│ 3.3.5 │ Деактивировать уже неактивную плантацию │ Ошибка: «Плантация уже деактивирована» │ +└───────┴────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────┘ + +--- +4. Вкладка «Маркировка» + +4.1 Создание + +┌───────┬───────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼───────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤ +│ 4.1.1 │ Создать маркировку с корректным кодом (напр. SCH-RP-RN50) │ Запись создана │ +├───────┼───────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤ +│ 4.1.2 │ Ввести код строчными буквами (напр. sch-rp) │ Код сохраняется в верхнем регистре (SCH-RP) благодаря strtoupper │ +├───────┼───────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤ +│ 4.1.3 │ Ввести код с недопустимым символом (напр. SCH_RP) │ Ошибка: «Код: 3-12 символов, только A-Z, 0-9 и дефис» │ +├───────┼───────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤ +│ 4.1.4 │ Ввести код короче 3 символов (напр. AB) │ Ошибка валидации │ +├───────┼────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤ +│ 4.1.5 │ Ввести код длиннее 12 символов │ Ошибка валидации │ +├───────┼────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤ +│ 4.1.6 │ Создать маркировку с дублирующимся кодом │ Ошибка: «Маркировка с таким кодом уже существует» │ +├───────┼────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤ +│ 4.1.7 │ Создать маркировку с такой же комбинацией (producer_id + plantation_id + product_name) при другом коде │ Ошибка уникального индекса │ +├───────┼────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────┤ +│ 4.1.8 │ Выбрать производителя — проверить, что в дропдауне «Плантация» появились только его плантации │ Каскадный AJAX-запрос /marking/plantations-by-producer работает │ +└───────┴────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────┘ + +4.2 Деактивация (блокировка) + +┌───────┬─────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼─────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────┤ +│ 4.2.1 │ Деактивировать маркировку без привязанных маппингов │ Тост «Маркировка деактивирована» │ +├───────┼─────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────┤ +│ 4.2.2 │ Деактивировать маркировку с привязанными маппингами │ Ошибка: «Нельзя деактивировать маркировку: есть N привязанных маппингов. Сначала отвяжите их.» │ +└───────┴─────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────────┘ + +--- +5. Вкладка «Маппинг товаров» + +5.1 Список и пагинация + +┌───────┬───────────────────────────────────┬───────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼───────────────────────────────────┼───────────────────────────────────────────────────────┤ +│ 5.1.1 │ Открыть вкладку │ Отображаются карточки товаров, блок аналитики в шапке │ +├───────┼───────────────────────────────────┼───────────────────────────────────────────────────────┤ +│ 5.1.2 │ Сменить per-page (50 / 100 / 500) │ Количество карточек на странице меняется │ +├───────┼───────────────────────────────────┼───────────────────────────────────────────────────────┤ +│ 5.1.3 │ Перейти на страницу 2 │ Корректная пагинация, другие товары │ +└───────┴───────────────────────────────────┴───────────────────────────────────────────────────────┘ + +5.2 Фильтры + +┌───────┬──────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼──────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────┤ +│ 5.2.1 │ Выбрать категорию → дропдаун «Подкатегория» заполняется (каскад) │ AJAX-запрос /product-mapping/cascade-filters │ +├───────┼──────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────┤ +│ 5.2.2 │ Выбрать подкатегорию → дропдаун «Вид» заполняется │ Каскад второго уровня │ +├───────┼──────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤ +│ 5.2.3 │ Ввести текст в поиск → применить фильтр │ Показываются только товары, содержащие текст │ +├───────┼──────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤ +│ 5.2.4 │ Фильтр по поставщику │ Показываются только товары с маппингом на выбранного поставщика │ +├───────┼──────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤ +│ 5.2.5 │ Фильтр по маркировке │ Показываются только товары с маппингом, содержащим выбранную маркировку │ +├───────┼──────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤ +│ 5.2.6 │ Фильтр «Только без маппинга» │ Показываются только товары без записей в product_mappings │ +├───────┼──────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤ +│ 5.2.7 │ Комбинация 2+ фильтров │ Результат пересечения условий │ +├───────┼──────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────┤ +│ 5.2.8 │ Сбросить фильтры │ Показываются все товары │ +└───────┴──────────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────┘ + +5.3 Аналитика + +┌───────┬─────────────────────────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼─────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┤ +│ 5.3.1 │ Применить фильтр │ Блок аналитики пересчитывается через AJAX (/product-mapping/analytics) │ +├───────┼─────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────┤ +│ 5.3.2 │ Проверить корректность % (with_supplier, single_supplier, without_producer) │ Значения математически согласованы с данными таблицы │ +└───────┴─────────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────┘ + +5.4 Создание маппинга + +┌───────┬────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────┤ +│ 5.4.1 │ Нажать «+» на карточке товара → заполнить форму (поставщик, название, квант=1) → Сохранить │ Маппинг появляется в таблице внутри карточки │ +├───────┼────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────┤ +│ 5.4.2 │ Указать квант = 0 │ Ошибка: «Кратность должна быть >= 1» │ +├───────┼───────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────┤ +│ 5.4.3 │ Не заполнить «Название у поставщика» │ Ошибка обязательного поля │ +├───────┼───────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────┤ +│ 5.4.4 │ Создать дублирующий маппинг (тот же товар + поставщик + без плантации) │ Ошибка уникальности │ +├───────┼───────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤ +│ 5.4.5 │ Создать маппинг с плантацией, создать ещё один с тем же товаром + поставщик + та же плантация │ Ошибка уникальности │ +├───────┼───────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤ +│ 5.4.6 │ Создать маппинг с тем же товаром + поставщик, но разными плантациями │ Успешно (разные partial-unique индексы) │ +├───────┼───────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────┤ +│ 5.4.7 │ Создать маппинг с несколькими маркировками (multiselect) │ В БД записи в mapping_markings для всех выбранных ID │ +└───────┴───────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────┘ + +5.5 Редактирование маппинга + +┌───────┬─────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────┤ +│ 5.5.1 │ Открыть форму редактирования │ Форма заполнена, в multiselect отмечены текущие маркировки │ +├───────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────┤ +│ 5.5.2 │ Изменить поставщика, убрать одну маркировку → Сохранить │ Данные обновляются, в mapping_markings убрана запись │ +├───────┼─────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────┤ +│ 5.5.3 │ Снять все маркировки → Сохранить │ В mapping_markings нет записей для этого mapping_id │ +└───────┴─────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────┘ + +5.6 Удаление маппинга + +┌───────┬──────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼──────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ +│ 5.6.1 │ Удалить маппинг с привязанными маркировками │ Маппинг удалён, записи в mapping_markings удалены каскадно (ON DELETE CASCADE) │ +├───────┼──────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ +│ 5.6.2 │ Повторный запрос на удаление уже удалённого маппинга │ 404 или ошибка «Маппинг не найден» │ +└───────┴──────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘ + +5.7 Экспорт в XLSX + +┌───────┬─────────────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├───────┼─────────────────────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────┤ +│ 5.7.1 │ Нажать «Экспорт» без фильтров │ Файл product-mapping-YYYY-MM-DD_HHmmss.xlsx скачивается │ +├───────┼─────────────────────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────┤ +│ 5.7.2 │ Открыть файл: проверить заголовки (12 столбцов), жирный + серый фон, заморозка строки 1 │ Форматирование соответствует │ +├───────┼─────────────────────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────┤ +│ 5.7.3 │ Товар без маппинга в выборке │ В файле строка с пустыми полями маппинга │ +├───────┼─────────────────────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────┤ +│ 5.7.4 │ Товар с 2 маппингами → в файле 2 строки │ Разворачивание маппингов корректно │ +├───────┼─────────────────────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────┤ +│ 5.7.5 │ Экспорт с активным фильтром (напр. по поставщику) │ В файле только отфильтрованные товары │ +├───────┼─────────────────────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────┤ +│ 5.7.6 │ Проверить, что temp-файл удалён после отправки │ Файл в @runtime отсутствует (хук EVENT_AFTER_SEND) │ +└───────┴─────────────────────────────────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────┘ + +--- +6. Консольная команда — ProductMappingCommand + +┌─────┬────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────────────────────┐ +│ # │ Команда │ Ожидаемый результат │ +├─────┼────────────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤ +│ 6.1 │ php yii product-mapping/find-orphans │ Выводит список маппингов без товара в 1С (или «Orphan-маппинги не найдены») │ +├─────┼────────────────────────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────┤ +│ 6.2 │ php yii product-mapping/delete-orphans (предварительно создать orphan вручную) │ Удаляет orphan-маппинги, выводит количество; в mapping_markings каскадно удалены записи │ +└─────┴────────────────────────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────┘ + +--- +7. RBAC / Права доступа + +┌─────┬─────────────────────────────────────────────────────────────────────┬─────────────────────┐ +│ # │ Сценарий │ Ожидаемый результат │ +├─────┼─────────────────────────────────────────────────────────────────────┼────────────────────────┤ +│ 7.1 │ Пользователь без прав на buyer-reference открывает /buyer-reference │ 403 или редирект │ +├─────┼─────────────────────────────────────────────────────────────────────┼────────────────────────┤ +│ 7.2 │ Пользователь без прав на supplier/create выполняет POST │ 403 │ +├─────┼─────────────────────────────────────────────────────────────────────┼────────────────────────┤ +│ 7.3 │ Пользователь с правами — все действия доступны │ Нет лишних ограничений │ +└─────┴─────────────────────────────────────────────────────────────────────┴────────────────────────┘ + +--- +8. Регрессия — вкладка «Бюджет» (style.css / index.js изменены) + +┌─────┬────────────────────────────────────────────┬───────────────────────────────────────────────────┐ +│ # │ Действие │ Ожидаемый результат │ +├─────┼────────────────────────────────────────────┼───────────────────────────────────────────────────┤ +│ 8.1 │ Открыть раздел «Бюджет» │ Страница отображается корректно, стили не сломаны │ +├─────┼────────────────────────────────────────────┼───────────────────────────────────────────────────┤ +│ 8.2 │ Интерактивные элементы бюджета (если есть) │ Работают как прежде │ +└─────┴────────────────────────────────────────────┴───────────────────────────────────────────────────┘ + +--- +Критические сценарии (приоритет 1) + +1. Каскадная деактивация поставщика → маркировки + маппинги деактивируются +2. Блокировка деактивации производителя при наличии активных маркировок +3. Блокировка деактивации маркировки при наличии привязанных маппингов +4. Уникальность partial-индекса маппинга (с плантацией / без плантации) +5. syncMarkings корректно удаляет старые связи и создаёт новые +6. Экспорт XLSX удаляет temp-файл после отправки + + +Миграции БД + +erp24/migrations/m260408_100000_create_suppliers_table.php +erp24/migrations/m260408_100100_create_producers_table.php +erp24/migrations/m260408_100200_create_plantations_table.php +erp24/migrations/m260408_100300_create_markings_table.php +erp24/migrations/m260408_100400_create_product_mappings_table.php +erp24/migrations/m260408_100500_create_mapping_markings_table.php +erp24/migrations/m260409_120000_add_erp300_rbac_permissions.php + +Модели (Records) + +erp24/records/Supplier.php +erp24/records/SupplierSearch.php +erp24/records/Producer.php +erp24/records/ProducerSearch.php +erp24/records/Plantation.php +erp24/records/Marking.php +erp24/records/MarkingSearch.php +erp24/records/ProductMapping.php +erp24/records/MappingMarking.php + +Контроллеры + +erp24/controllers/BuyerReferenceController.php +erp24/controllers/SupplierController.php +erp24/controllers/ProducerController.php +erp24/controllers/MarkingController.php +erp24/controllers/ProductMappingController.php +erp24/commands/ProductMappingController.php + +Сервисы и формы + +erp24/services/ProductMappingService.php +erp24/forms/ProductMappingFilterForm.php + +Views + +erp24/views/buyer-reference/index.php +erp24/views/supplier/index.php +erp24/views/supplier/_form.php +erp24/views/producer/index.php +erp24/views/producer/_producer_form.php +erp24/views/producer/_plantation_form.php +erp24/views/marking/index.php +erp24/views/marking/_form.php +erp24/views/product-mapping/index.php +erp24/views/product-mapping/_card.php +erp24/views/product-mapping/_form.php +erp24/views/product-mapping/_filters.php +erp24/views/product-mapping/_analytics.php + +Frontend + +erp24/web/js/product-mapping/index.js +erp24/web/js/budget/index.js +erp24/web/css/budget/style.css + +Тесты + +erp24/tests/unit/records/SupplierTest.php +erp24/tests/unit/records/ProducerTest.php +erp24/tests/unit/records/PlantationTest.php +erp24/tests/unit/records/MarkingTest.php +erp24/tests/unit/records/ProductMappingTest.php +erp24/tests/unit/forms/ProductMappingFilterFormTest.php +erp24/tests/unit/services/ProductMappingServiceTest.php +erp24/tests/unit/commands/ProductMappingCommandTest.php +erp24/tests/unit/controllers/Erp300ControllersTest.php +erp24/tests/unit/migrations/Erp300RbacMigrationTest.php + +Документация + +docs/jira/ERP-318/debate-log.md +docs/jira/ERP-318/interview.md +docs/jira/ERP-318/plan.md +docs/jira/ERP-318/prd.md +docs/jira/ERP-318/spec.md diff --git a/erp24/views/buyer-reference/index.php b/erp24/views/buyer-reference/index.php index b5cd03ab..6e6368c8 100644 --- a/erp24/views/buyer-reference/index.php +++ b/erp24/views/buyer-reference/index.php @@ -167,4 +167,5 @@ $js = <<registerJs($js); +$this->registerJsFile('/js/product-mapping/index.js', ['position' => \yii\web\View::POS_END]); ?> diff --git a/erp24/views/product-mapping/index.php b/erp24/views/product-mapping/index.php index 70b27b09..71c58820 100644 --- a/erp24/views/product-mapping/index.php +++ b/erp24/views/product-mapping/index.php @@ -109,7 +109,7 @@ use yii\widgets\LinkPager; registerJs('window.pmCfg = ' . \yii\helpers\Json::encode([ +$this->registerJs('if (typeof window.pmInit === "function") { window.pmInit(' . \yii\helpers\Json::encode([ 'urls' => [ 'createForm' => Url::to(['/product-mapping/create-form']), 'updateForm' => Url::to(['/product-mapping/update-form']), @@ -121,7 +121,5 @@ $this->registerJs('window.pmCfg = ' . \yii\helpers\Json::encode([ 'cascade' => Url::to(['/product-mapping/cascade-filters']), 'export' => Url::to(['/product-mapping/export']), ], -]) . ';'); - -$this->registerJsFile('/js/product-mapping/index.js', ['position' => \yii\web\View::POS_END]); +]) . '); }'); ?> diff --git a/erp24/web/js/product-mapping/index.js b/erp24/web/js/product-mapping/index.js index 09955826..4feb7753 100644 --- a/erp24/web/js/product-mapping/index.js +++ b/erp24/web/js/product-mapping/index.js @@ -1,6 +1,5 @@ /* global bootstrap, yii */ -(function () { - var cfg = window.pmCfg; +window.pmInit = function (cfg) { if (!cfg) return; // Снимаем все предыдущие обработчики этого модуля с document, @@ -240,4 +239,4 @@ $(this).removeClass('is-invalid'); $(this).next('.invalid-feedback').remove(); }); -}()); +};