Обычный пользователь
Режим разработчика не нужен нигде. Все четырнадцать карточек проходятся правами кладовщика: кнопки живут в шестерёнке над списком правил, результат каждого действия приходит всплывающим окном на экран. Хватит доступа к складам.
logistic-node.odoo.com · saas~19.4 · прогонный лист v1
Четырнадцать сценариев по стенду распределённой логистики. Каждый — с посевом, шагами, ожидаемым результатом и откатом. Всё проходится от лица обычного пользователя: режим разработчика не нужен нигде, весь результат приходит всплывающим окном на экран. Порядок не случаен: карточки 09–12 идут подряд и не откатываются по одной — это одна связка failover. Стенд в исходном состоянии, ночной крон снят с расписания.
Четыре условия. Если хоть одно не выполнено, половина сценариев даст ложный результат — и вы будете чинить не то.
Режим разработчика не нужен нигде. Все четырнадцать карточек проходятся правами кладовщика: кнопки живут в шестерёнке над списком правил, результат каждого действия приходит всплывающим окном на экран. Хватит доступа к складам.
Все 160 правил должны быть в trigger = Автоматически. После сценариев 09–11 проверьте это ещё раз: failover намеренно переводит 20 правил в ручной режим.
Распределение маршрутов до начала: 33/40/47 — по 20, 55/69 — по 20, 62 — 19, 65 и 19 — по 1, Buy — 39. Сумма 160. К этому же состоянию стенд обязан вернуться в конце.
Действие «Каскад источников: ночной прогон» снято с расписания и в вашем прогоне не участвует. Проверять ничего не нужно: пока оно выключено, никто не передвинет маршруты у вас за спиной.
Отметки сохраняются в браузере — можно закрыть вкладку и вернуться. Кнопка «Выгрузить итог» кладёт в буфер текстовый отчёт со всеми отметками и заметками. Показан пользовательский путь; две служебные карточки под администратором лежат за кнопкой «+ админские» в верхней панели и в счёт прогона не идут.
В штатной Odoo склад не знает, жив он или выведен и кто его подменяет — этого просто нет в модели. Мы добавили складу три поля-«паспорта», и все дальнейшие сценарии опираются на них. Эта карточка — беглая проверка, что паспорт на месте и заполнен верно. Ничего не нажимаете, только смотрите.
WHA,WHB — сначала центральный, если у него не хватает свободного остатка, то резервный. Это и есть «каскад источников» из сценариев 03–06.WHB.WHA,WHB.WHB,WHA. Так и задумано: они ближе к резервному складу.Не требуется — только чтение.
Две колонки памяти спрятаны под галочку. Они понадобятся в сценариях 09–11, чтобы увидеть, что именно натворило переключение.
Колонки можно оставить включёнными — они пригодятся дальше.
Скучный случай, и именно поэтому важный: каскад не должен суетиться, когда основной узел покрывает потребность.
Правило S1 Магазин Подол / [UNV-01] Кондиціонер 12k BTU. Записать исходные значения: мин 4, макс 8, маршрут S1 ← WH-A. Выставить мин 20, макс 25. Потребность станет 19 (25 − 6 в наличии).
S1 ← WH-A.Вернуть мин 4, макс 8.
Главный сценарий каскада. Потребность подобрана так, чтобы попасть в узкое окно между свободным остатком WH-A и WH-B.
То же правило S1 / UNV-01. Выставить мин 30, макс 35 — потребность станет 29. На WH-A свободно 27, на WH-B 30. Окно, в котором первый источник обязан отвалиться, а второй — подхватить.
S1 ← WH-A придётся руками, и это честное ограничение, а не дефект.Маршрут вручную на S1 ← WH-A, затем мин 4, макс 8.
Проверка на тот самый инцидент: в первом прогоне крон подменил хабам закупочный маршрут межскладским, и хабы перестали закупать у поставщика. Посев не нужен — дефициты на хабах уже есть.
Не требуется. Прямо сейчас 11 правил с ненулевой потребностью, и все они на хабах с маршрутом Buy: WH-A / UNV-01 и десять правил WH-B (ESP-01…05 и UNV-01…05).
пропущено — правило не межузловое (Buy).op.route_id.supplier_wh_id в действиях 935 и 936.Не требуется, если ждём совпало. Если маршруты поехали — вернуть все затронутые правила на Buy.
Среднее состояние должно что-то значить. Узел с остатком, но «ограничен», не выбирается источником — хотя товара у него хватает.
Двойной. Первое: WH-A ▸ Состояние узла = Ограничен. Второе: правило S1 / UNV-01 ▸ мин 20, макс 25 (потребность 19 — WH-A такое покрыл бы легко).
WHA: не в строю (limited).WH-A ▸ Состояние = Доступен. Маршрут правила вручную на S1 ← WH-A. Затем мин 4, макс 8.
Переброска «магазин → магазин» мимо хабов. Донор считается по излишку сверх собственного максимума, а не по абсолютному остатку.
Правило S1 / [FST-01] Смартфон 256GB. Исходно мин 6, макс 15, в наличии 15. Выставить мин 20, макс 25 — потребность 10. У S6 Днепр лежит 60 при собственном максимуме 15, то есть излишек 45; у всех остальных магазинов ровно по 15 — излишек ноль.
S1 ← WH-A.Действие 937 возвращает маршрут. Останется вернуть мин 6, макс 15.
Отрицательный сценарий. Действие обязано отказаться внятно, а не переставить маршрут наугад.
Правило S1 / UNV-01, мин 30, макс 35 — потребность 29. По UNV-01 во всех магазинах ровно по 6 штук при максимуме 8: излишка нет ни у кого.
Вернуть мин 4, макс 8.
Центральный сценарий стенда. Одно действие вместо примерно семидесяти ручных правок в шести разных меню.
Не требуется. Перед запуском зафиксируйте время — понадобится, чтобы честно сравнить с ручной альтернативой.
trigger = Вручную, колонка «Приглушено failover» отмечена. Мёртвый склад больше не заказывает себе товар.Отложен до карточки 11.
WH-A уже выведен. Попытка вывести и WH-B оставила бы сеть без обоих хабов — действие обязано отказать.
Состояние из карточки 09: WH-A выведен, WH-B доступен и указан резервом для WH-A. Резерв самого WH-B — это WH-A.
Не требуется — действие ничего не записало.
Возврат должен идти строго по запомненным маршрутам, а не по догадке «наверное, было от WH-A». Разница видна на S3: одно правило там сидит на межскладском маршруте изначально.
Автоматически.Это и есть откат связки 09–11.
Отказ должен срабатывать не только на выведенном резерве, но и на ограниченном. Иначе среднее состояние окажется декорацией.
WH-B ▸ Состояние узла = Ограничен. Оба узла в остальном исходные.
WH-B ▸ Состояние = Доступен.
Двух карточек ниже в работе оператора нет — они требуют режима разработчика и в счёт прогона не идут. Открыты по вашей просьбе кнопкой «+ админские». Настройки ▸ в самом низу ▸ «Активировать режим разработчика».
Крон снят с расписания, но код на месте. Проверяем, что он делает ровно то же, что ручной запуск каскада, и что хабы для него неприкосновенны.
пропущено — правило не межузловое (Buy).Проверить, что галочка «Активно» осталась снятой.
Оператор видит результат во всплывающем окне, но окно живёт до первого клика. Постоянный след остаётся только в техническом журнале — и вот он оператору уже недоступен. Проверяем, что хотя бы администратор может восстановить ход событий задним числом.
Не требуется.
Не дефект количества, а дефект формы. Количества верные; неудобен способ, которым Odoo 19 их оформляет.
OP/00123.procurement.group в saas~19.4 больше нет, поле group_id убрано и с перемещения, и с документа. Склеивать заявки одного правила в 19-й нечем; штатная замена — батчи, но это склейка на исполнении, а не единая заявка.Не требуется — только чтение.
Единственный процесс, который настройкой не закрывается вообще. Убедиться в этом руками стоит до того, как закладывать его в оценку.
Любой из подтверждённых заказов S00001…S00005 — все пять оформлены на WH-A.
stock, настройкой не лечится.Вернуть в заказе склад WH-A. Проверить, что отгрузка осталась прежней и ничего не задвоилось.
Значения сняты со стенда перед прогоном. Если они разошлись с тем, что вы видите — стенд уже кто-то двигал, и сценарии с подобранными окнами потребности перестанут работать.
| Код | Резерв | Каскад |
|---|---|---|
| WHA | WH-B | WHB |
| WHB | WH-A | WHA |
| S1 Подол | — | WHA,WHB |
| S2 Оболонь | — | WHA,WHB |
| S3 Троещина | — | WHA,WHB |
| S4 Львов | — | WHB,WHA |
| S5 Одесса | — | WHB,WHA |
| S6 Днепр | — | WHB,WHA |
| SKU | WH-A своб. | WH-B своб. |
|---|---|---|
| UNV-01 | 27 (из 52) | 30 |
| ESP-01 | 34 | 20 |
| ESP-02 | 40 | 20 |
| ESP-05 | 38 | 20 |
| FST-01 | 105 | 60 |
| FST-03 | 120 | 0 |
| UNV-04 | 60 | 30 |
По UNV-01 на WH-A лежит 52, но свободно 27 — остальное зарезервировано. Каскад считает по свободному; это и делает возможным сценарий 04.
| ID | Тип | Название | Где искать |
|---|---|---|---|
| 19577 | поле | stock.warehouse.x_node_state | Форма склада |
| 19578 | поле | stock.warehouse.x_failover_to | Форма склада |
| 19579 | поле | stock.warehouse.x_source_priority | Форма склада |
| 19580 | поле | …orderpoint.x_route_before_failover | Колонка в пополнении |
| 19585 | поле | …orderpoint.x_route_before_lateral | Колонка в пополнении |
| 19587 | поле | …orderpoint.x_muted_by_failover | Колонка в пополнении |
| 2770 | вид | Форма склада: блок состояния | Технические ▸ Представления |
| 2771 | вид | Список правил: две колонки | Технические ▸ Представления |
| 933 | действие | Вывести узел из сети (failover) | Шестерёнка на складе |
| 934 | действие | Вернуть узел в сеть | Шестерёнка на складе |
| 935 | действие | Выбрать источник по каскаду | Шестерёнка в пополнении |
| 936 | действие | Латеральная переброска: найти донора | Шестерёнка в пополнении |
| 937 | действие | Отменить латерал (вернуть маршрут) | Шестерёнка в пополнении |
| 70 | крон | Каскад источников: ночной прогон | Запланированные ▸ Архивные |
Семь проверок. Пока все семь не сошлись, стенд считать исходным нельзя — и следующий замер сравнивать будет не с чем.
| # | Что сверяем | Норма |
|---|---|---|
| 1 | Распределение по маршрутам в пополнении | 33/40/47 — по 20 · 55/69 — по 20 · 62 — 19 · 65 и 19 — по 1 · Buy — 39 |
| 2 | Всего правил | 160 |
| 3 | Правил в trigger = Автоматически | 160, ни одного «Вручную» |
| 4 | Состояние всех восьми узлов | Доступен |
| 5 | Колонки «Маршрут до failover» и «до латерала» | пусты у всех строк |
| 6 | Колонка «Приглушено failover» | снята у всех строк |
| 7 | Мин/макс у правил S1 / UNV-01 и S1 / FST-01 | 4 и 8 · 6 и 15 |